OLD | NEW |
---|---|
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 Loading... | |
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 } |
pavely
2014/09/09 19:42:23
We discussed that all 4xx except "forbidden" are p
pavely
2014/09/09 19:47:42
Sorry, I meant "unauthorized"
maniscalco
2014/09/09 21:15:43
I think you mean all are transient except for forb
maniscalco
2014/09/09 21:15:43
Acknowledged.
| |
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 ReportResult(UPLOAD_TRANSIENT_ERROR, attachment_.GetId()); |
pavely
2014/09/09 19:42:23
Could you put a TODO that errors should be treated
maniscalco
2014/09/09 21:15:44
Happy to chat more in person. TODO added.
Were y
| |
188 } | 191 } |
189 | 192 |
190 void AttachmentUploaderImpl::UploadState::GetToken() { | 193 void AttachmentUploaderImpl::UploadState::GetToken() { |
191 access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart( | 194 access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart( |
192 token_service_provider_, account_id_, scopes_, this); | 195 token_service_provider_, account_id_, scopes_, this); |
193 } | 196 } |
194 | 197 |
195 void AttachmentUploaderImpl::UploadState::ReportResult( | 198 void AttachmentUploaderImpl::UploadState::ReportResult( |
196 const UploadResult& result, | 199 const UploadResult& result, |
197 const AttachmentId& attachment_id) { | 200 const AttachmentId& attachment_id) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 GURL::Replacements replacements; | 272 GURL::Replacements replacements; |
270 replacements.SetPathStr(path); | 273 replacements.SetPathStr(path); |
271 return sync_service_url.ReplaceComponents(replacements); | 274 return sync_service_url.ReplaceComponents(replacements); |
272 } | 275 } |
273 | 276 |
274 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) { | 277 void AttachmentUploaderImpl::DeleteUploadStateFor(const UniqueId& unique_id) { |
275 state_map_.erase(unique_id); | 278 state_map_.erase(unique_id); |
276 } | 279 } |
277 | 280 |
278 } // namespace syncer | 281 } // namespace syncer |
OLD | NEW |