Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1259)

Side by Side Diff: sync/internal_api/attachments/attachment_uploader_impl.cc

Issue 554743004: Update AttachmentServiceImpl to retry attachment uploads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge with master. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h" 5 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/threading/non_thread_safe.h" 9 #include "base/threading/non_thread_safe.h"
10 #include "google_apis/gaia/gaia_constants.h" 10 #include "google_apis/gaia/gaia_constants.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 } 126 }
127 127
128 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() { 128 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() {
129 DCHECK(CalledOnValidThread()); 129 DCHECK(CalledOnValidThread());
130 return attachment_; 130 return attachment_;
131 } 131 }
132 132
133 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete( 133 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete(
134 const net::URLFetcher* source) { 134 const net::URLFetcher* source) {
135 DCHECK(CalledOnValidThread()); 135 DCHECK(CalledOnValidThread());
136 UploadResult result = UPLOAD_UNSPECIFIED_ERROR; 136 UploadResult result = UPLOAD_TRANSIENT_ERROR;
137 AttachmentId attachment_id = attachment_.GetId(); 137 AttachmentId attachment_id = attachment_.GetId();
138 if (source->GetResponseCode() == net::HTTP_OK) { 138 const int response_code = source->GetResponseCode();
139 if (response_code == net::HTTP_OK) {
139 result = UPLOAD_SUCCESS; 140 result = UPLOAD_SUCCESS;
140 } else if (source->GetResponseCode() == net::HTTP_UNAUTHORIZED) { 141 } else if (response_code == net::HTTP_UNAUTHORIZED) {
141 // TODO(maniscalco): One possibility is that we received a 401 because our 142 // Server tells us we've got a bad token so invalidate it.
142 // access token has expired. We should probably fetch a new access token
143 // and retry this upload before giving up and reporting failure to our
144 // caller (bug 380437).
145 OAuth2TokenServiceRequest::InvalidateToken( 143 OAuth2TokenServiceRequest::InvalidateToken(
146 token_service_provider_, account_id_, scopes_, access_token_); 144 token_service_provider_, account_id_, scopes_, access_token_);
147 } else { 145 // Fail the request, but indicate that it may be successful if retried.
148 // TODO(maniscalco): Once the protocol is better defined, deal with the 146 result = UPLOAD_TRANSIENT_ERROR;
149 // various HTTP response codes we may encounter. 147 } else if (response_code == net::HTTP_FORBIDDEN) {
148 // User is not allowed to use attachments. Retrying won't help.
149 result = UPLOAD_UNSPECIFIED_ERROR;
150 } else if (response_code == net::URLFetcher::RESPONSE_CODE_INVALID) {
151 result = UPLOAD_TRANSIENT_ERROR;
150 } 152 }
151 ReportResult(result, attachment_id); 153 ReportResult(result, attachment_id);
152 } 154 }
153 155
154 void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess( 156 void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess(
155 const OAuth2TokenService::Request* request, 157 const OAuth2TokenService::Request* request,
156 const std::string& access_token, 158 const std::string& access_token,
157 const base::Time& expiration_time) { 159 const base::Time& expiration_time) {
158 DCHECK_EQ(access_token_request_.get(), request); 160 DCHECK_EQ(access_token_request_.get(), request);
159 access_token_request_.reset(); 161 access_token_request_.reset();
160 access_token_ = access_token; 162 access_token_ = access_token;
161 fetcher_.reset( 163 fetcher_.reset(
162 net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this)); 164 net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this));
165 fetcher_->SetAutomaticallyRetryOn5xx(false);
163 fetcher_->SetRequestContext(url_request_context_getter_.get()); 166 fetcher_->SetRequestContext(url_request_context_getter_.get());
164 // TODO(maniscalco): Is there a better way? Copying the attachment data into 167 // TODO(maniscalco): Is there a better way? Copying the attachment data into
165 // a string feels wrong given how large attachments may be (several MBs). If 168 // a string feels wrong given how large attachments may be (several MBs). If
166 // we may end up switching from URLFetcher to URLRequest, this copy won't be 169 // we may end up switching from URLFetcher to URLRequest, this copy won't be
167 // necessary. 170 // necessary.
168 scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData(); 171 scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData();
169 const std::string upload_content(memory->front_as<char>(), memory->size()); 172 const std::string upload_content(memory->front_as<char>(), memory->size());
170 fetcher_->SetUploadData(kContentType, upload_content); 173 fetcher_->SetUploadData(kContentType, upload_content);
171 const std::string auth_header("Authorization: Bearer " + access_token_); 174 const std::string auth_header("Authorization: Bearer " + access_token_);
172 fetcher_->AddExtraRequestHeader(auth_header); 175 fetcher_->AddExtraRequestHeader(auth_header);
173 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 176 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
174 net::LOAD_DO_NOT_SEND_COOKIES | 177 net::LOAD_DO_NOT_SEND_COOKIES |
175 net::LOAD_DISABLE_CACHE); 178 net::LOAD_DISABLE_CACHE);
176 // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and 179 // TODO(maniscalco): Set an appropriate headers (User-Agent, Content-type, and
177 // Content-length) on the request and include the content's MD5, 180 // Content-length) on the request and include the content's MD5,
178 // AttachmentId's unique_id and the "sync birthday" (bug 371521). 181 // AttachmentId's unique_id and the "sync birthday" (bug 371521).
179 fetcher_->Start(); 182 fetcher_->Start();
180 } 183 }
181 184
182 void AttachmentUploaderImpl::UploadState::OnGetTokenFailure( 185 void AttachmentUploaderImpl::UploadState::OnGetTokenFailure(
183 const OAuth2TokenService::Request* request, 186 const OAuth2TokenService::Request* request,
184 const GoogleServiceAuthError& error) { 187 const GoogleServiceAuthError& error) {
185 DCHECK_EQ(access_token_request_.get(), request); 188 DCHECK_EQ(access_token_request_.get(), request);
186 access_token_request_.reset(); 189 access_token_request_.reset();
187 ReportResult(UPLOAD_UNSPECIFIED_ERROR, attachment_.GetId()); 190 // TODO(maniscalco): We treat this as a transient error, but it may in fact be
191 // a very long lived error and require user action. Consider differentiating
192 // between the causes of GetToken failure and act accordingly. Think about
193 // the causes of GetToken failure. Are there (bug 412802).
194 ReportResult(UPLOAD_TRANSIENT_ERROR, attachment_.GetId());
188 } 195 }
189 196
190 void AttachmentUploaderImpl::UploadState::GetToken() { 197 void AttachmentUploaderImpl::UploadState::GetToken() {
191 access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart( 198 access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart(
192 token_service_provider_, account_id_, scopes_, this); 199 token_service_provider_, account_id_, scopes_, this);
193 } 200 }
194 201
195 void AttachmentUploaderImpl::UploadState::ReportResult( 202 void AttachmentUploaderImpl::UploadState::ReportResult(
196 const UploadResult& result, 203 const UploadResult& result,
197 const AttachmentId& attachment_id) { 204 const AttachmentId& attachment_id) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 GURL::Replacements replacements; 276 GURL::Replacements replacements;
270 replacements.SetPathStr(path); 277 replacements.SetPathStr(path);
271 return sync_service_url.ReplaceComponents(replacements); 278 return sync_service_url.ReplaceComponents(replacements);
272 } 279 }
273 280
274 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) { 281 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) {
275 state_map_.erase(unique_id); 282 state_map_.erase(unique_id);
276 } 283 }
277 284
278 } // namespace syncer 285 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698