| OLD | NEW |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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 "chrome/browser/chromeos/policy/upload_job_impl.h" | 5 #include "chrome/browser/chromeos/policy/upload_job_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/chromeos/logging.h" |
| 11 #include "base/location.h" | 12 #include "base/location.h" |
| 12 #include "base/logging.h" | |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "google_apis/gaia/gaia_constants.h" | 15 #include "google_apis/gaia/gaia_constants.h" |
| 16 #include "google_apis/gaia/google_service_auth_error.h" | 16 #include "google_apis/gaia/google_service_auth_error.h" |
| 17 #include "net/base/mime_util.h" | 17 #include "net/base/mime_util.h" |
| 18 #include "net/http/http_status_code.h" | 18 #include "net/http/http_status_code.h" |
| 19 #include "net/url_request/url_request_status.h" | 19 #include "net/url_request/url_request_status.h" |
| 20 | 20 |
| 21 namespace policy { | 21 namespace policy { |
| 22 | 22 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 173 } |
| 174 | 174 |
| 175 void UploadJobImpl::Start() { | 175 void UploadJobImpl::Start() { |
| 176 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(thread_checker_.CalledOnValidThread()); |
| 177 // Cannot start an upload on a busy or failed instance. | 177 // Cannot start an upload on a busy or failed instance. |
| 178 DCHECK_EQ(IDLE, state_); | 178 DCHECK_EQ(IDLE, state_); |
| 179 if (state_ != IDLE) | 179 if (state_ != IDLE) |
| 180 return; | 180 return; |
| 181 DCHECK_EQ(0, retry_); | 181 DCHECK_EQ(0, retry_); |
| 182 | 182 |
| 183 CHROMEOS_SYSLOG(WARNING) << "Upload job started"; |
| 183 RequestAccessToken(); | 184 RequestAccessToken(); |
| 184 } | 185 } |
| 185 | 186 |
| 186 // static | 187 // static |
| 187 void UploadJobImpl::SetRetryDelayForTesting(long retry_delay_ms) { | 188 void UploadJobImpl::SetRetryDelayForTesting(long retry_delay_ms) { |
| 188 CHECK_GE(retry_delay_ms, 0); | 189 CHECK_GE(retry_delay_ms, 0); |
| 189 g_retry_delay_ms = retry_delay_ms; | 190 g_retry_delay_ms = retry_delay_ms; |
| 190 } | 191 } |
| 191 | 192 |
| 192 void UploadJobImpl::RequestAccessToken() { | 193 void UploadJobImpl::RequestAccessToken() { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 for (const auto& entry : data_segment->GetHeaderEntries()) { | 250 for (const auto& entry : data_segment->GetHeaderEntries()) { |
| 250 post_data_->append(entry.first + ": " + entry.second + "\r\n"); | 251 post_data_->append(entry.first + ": " + entry.second + "\r\n"); |
| 251 } | 252 } |
| 252 std::unique_ptr<std::string> data = data_segment->GetData(); | 253 std::unique_ptr<std::string> data = data_segment->GetData(); |
| 253 post_data_->append("\r\n" + *data + "\r\n"); | 254 post_data_->append("\r\n" + *data + "\r\n"); |
| 254 } | 255 } |
| 255 post_data_->append("--" + *mime_boundary_.get() + "--\r\n"); | 256 post_data_->append("--" + *mime_boundary_.get() + "--\r\n"); |
| 256 | 257 |
| 257 // Issues a warning if our buffer size estimate was too small. | 258 // Issues a warning if our buffer size estimate was too small. |
| 258 if (post_data_->size() > size) { | 259 if (post_data_->size() > size) { |
| 259 LOG(WARNING) | 260 CHROMEOS_SYSLOG(WARNING) |
| 260 << "Reallocation needed in POST data buffer. Expected maximum size " | 261 << "Reallocation needed in POST data buffer. Expected maximum size " |
| 261 << size << " bytes, actual size " << post_data_->size() << " bytes."; | 262 << size << " bytes, actual size " << post_data_->size() << " bytes."; |
| 262 } | 263 } |
| 263 | 264 |
| 264 // Discard the data segments as they are not needed anymore from here on. | 265 // Discard the data segments as they are not needed anymore from here on. |
| 265 data_segments_.clear(); | 266 data_segments_.clear(); |
| 266 | 267 |
| 267 return true; | 268 return true; |
| 268 } | 269 } |
| 269 | 270 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 281 upload_fetcher_->SetUploadData(content_type, *post_data_); | 282 upload_fetcher_->SetUploadData(content_type, *post_data_); |
| 282 upload_fetcher_->AddExtraRequestHeader( | 283 upload_fetcher_->AddExtraRequestHeader( |
| 283 base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); | 284 base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); |
| 284 upload_fetcher_->Start(); | 285 upload_fetcher_->Start(); |
| 285 } | 286 } |
| 286 | 287 |
| 287 void UploadJobImpl::StartUpload() { | 288 void UploadJobImpl::StartUpload() { |
| 288 DCHECK(thread_checker_.CalledOnValidThread()); | 289 DCHECK(thread_checker_.CalledOnValidThread()); |
| 289 | 290 |
| 290 if (!SetUpMultipart()) { | 291 if (!SetUpMultipart()) { |
| 291 LOG(ERROR) << "Multipart message assembly failed."; | 292 CHROMEOS_SYSLOG(ERROR) << "Multipart message assembly failed."; |
| 292 state_ = ERROR; | 293 state_ = ERROR; |
| 293 return; | 294 return; |
| 294 } | 295 } |
| 295 CreateAndStartURLFetcher(access_token_); | 296 CreateAndStartURLFetcher(access_token_); |
| 296 state_ = UPLOADING; | 297 state_ = UPLOADING; |
| 297 } | 298 } |
| 298 | 299 |
| 299 void UploadJobImpl::OnGetTokenSuccess( | 300 void UploadJobImpl::OnGetTokenSuccess( |
| 300 const OAuth2TokenService::Request* request, | 301 const OAuth2TokenService::Request* request, |
| 301 const std::string& access_token, | 302 const std::string& access_token, |
| 302 const base::Time& expiration_time) { | 303 const base::Time& expiration_time) { |
| 303 DCHECK_EQ(ACQUIRING_TOKEN, state_); | 304 DCHECK_EQ(ACQUIRING_TOKEN, state_); |
| 304 DCHECK_EQ(access_token_request_.get(), request); | 305 DCHECK_EQ(access_token_request_.get(), request); |
| 305 access_token_request_.reset(); | 306 access_token_request_.reset(); |
| 306 | 307 |
| 307 // Also cache the token locally, so that we can revoke it later if necessary. | 308 // Also cache the token locally, so that we can revoke it later if necessary. |
| 308 access_token_ = access_token; | 309 access_token_ = access_token; |
| 309 StartUpload(); | 310 StartUpload(); |
| 310 } | 311 } |
| 311 | 312 |
| 312 void UploadJobImpl::OnGetTokenFailure( | 313 void UploadJobImpl::OnGetTokenFailure( |
| 313 const OAuth2TokenService::Request* request, | 314 const OAuth2TokenService::Request* request, |
| 314 const GoogleServiceAuthError& error) { | 315 const GoogleServiceAuthError& error) { |
| 315 DCHECK_EQ(ACQUIRING_TOKEN, state_); | 316 DCHECK_EQ(ACQUIRING_TOKEN, state_); |
| 316 DCHECK_EQ(access_token_request_.get(), request); | 317 DCHECK_EQ(access_token_request_.get(), request); |
| 317 access_token_request_.reset(); | 318 access_token_request_.reset(); |
| 318 LOG(ERROR) << "Token request failed: " << error.ToString(); | 319 CHROMEOS_SYSLOG(ERROR) << "Token request failed: " << error.ToString(); |
| 319 HandleError(AUTHENTICATION_ERROR); | 320 HandleError(AUTHENTICATION_ERROR); |
| 320 } | 321 } |
| 321 | 322 |
| 322 void UploadJobImpl::HandleError(ErrorCode error_code) { | 323 void UploadJobImpl::HandleError(ErrorCode error_code) { |
| 323 retry_++; | 324 retry_++; |
| 324 upload_fetcher_.reset(); | 325 upload_fetcher_.reset(); |
| 325 | 326 |
| 326 LOG(ERROR) << "Upload failed, error code: " << error_code; | 327 CHROMEOS_SYSLOG(ERROR) << "Upload failed, error code: " << error_code; |
| 327 | 328 |
| 328 if (retry_ >= kMaxAttempts) { | 329 if (retry_ >= kMaxAttempts) { |
| 329 // Maximum number of attempts reached, failure. | 330 // Maximum number of attempts reached, failure. |
| 330 LOG(ERROR) << "Maximum number of attempts reached."; | 331 CHROMEOS_SYSLOG(ERROR) << "Maximum number of attempts reached."; |
| 331 access_token_.clear(); | 332 access_token_.clear(); |
| 332 post_data_.reset(); | 333 post_data_.reset(); |
| 333 state_ = ERROR; | 334 state_ = ERROR; |
| 334 delegate_->OnFailure(error_code); | 335 delegate_->OnFailure(error_code); |
| 335 } else { | 336 } else { |
| 336 if (error_code == AUTHENTICATION_ERROR) { | 337 if (error_code == AUTHENTICATION_ERROR) { |
| 337 LOG(ERROR) << "Retrying upload with a new token."; | 338 CHROMEOS_SYSLOG(ERROR) << "Retrying upload with a new token."; |
| 338 // Request new token and retry. | 339 // Request new token and retry. |
| 339 OAuth2TokenService::ScopeSet scope_set; | 340 OAuth2TokenService::ScopeSet scope_set; |
| 340 scope_set.insert(GaiaConstants::kDeviceManagementServiceOAuth); | 341 scope_set.insert(GaiaConstants::kDeviceManagementServiceOAuth); |
| 341 token_service_->InvalidateAccessToken(account_id_, scope_set, | 342 token_service_->InvalidateAccessToken(account_id_, scope_set, |
| 342 access_token_); | 343 access_token_); |
| 343 access_token_.clear(); | 344 access_token_.clear(); |
| 344 task_runner_->PostDelayedTask( | 345 task_runner_->PostDelayedTask( |
| 345 FROM_HERE, base::Bind(&UploadJobImpl::RequestAccessToken, | 346 FROM_HERE, base::Bind(&UploadJobImpl::RequestAccessToken, |
| 346 weak_factory_.GetWeakPtr()), | 347 weak_factory_.GetWeakPtr()), |
| 347 base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); | 348 base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); |
| 348 } else { | 349 } else { |
| 349 // Retry without a new token. | 350 // Retry without a new token. |
| 350 state_ = ACQUIRING_TOKEN; | 351 state_ = ACQUIRING_TOKEN; |
| 351 LOG(WARNING) << "Retrying upload with the same token."; | 352 CHROMEOS_SYSLOG(WARNING) << "Retrying upload with the same token."; |
| 352 task_runner_->PostDelayedTask( | 353 task_runner_->PostDelayedTask( |
| 353 FROM_HERE, | 354 FROM_HERE, |
| 354 base::Bind(&UploadJobImpl::StartUpload, weak_factory_.GetWeakPtr()), | 355 base::Bind(&UploadJobImpl::StartUpload, weak_factory_.GetWeakPtr()), |
| 355 base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); | 356 base::TimeDelta::FromMilliseconds(g_retry_delay_ms)); |
| 356 } | 357 } |
| 357 } | 358 } |
| 358 } | 359 } |
| 359 | 360 |
| 360 void UploadJobImpl::OnURLFetchComplete(const net::URLFetcher* source) { | 361 void UploadJobImpl::OnURLFetchComplete(const net::URLFetcher* source) { |
| 361 DCHECK_EQ(upload_fetcher_.get(), source); | 362 DCHECK_EQ(upload_fetcher_.get(), source); |
| 362 DCHECK_EQ(UPLOADING, state_); | 363 DCHECK_EQ(UPLOADING, state_); |
| 363 const net::URLRequestStatus& status = source->GetStatus(); | 364 const net::URLRequestStatus& status = source->GetStatus(); |
| 364 if (!status.is_success()) { | 365 if (!status.is_success()) { |
| 365 LOG(ERROR) << "URLRequestStatus error " << status.error(); | 366 CHROMEOS_SYSLOG(ERROR) << "URLRequestStatus error " << status.error(); |
| 366 HandleError(NETWORK_ERROR); | 367 HandleError(NETWORK_ERROR); |
| 367 } else { | 368 } else { |
| 368 const int response_code = source->GetResponseCode(); | 369 const int response_code = source->GetResponseCode(); |
| 369 if (response_code == net::HTTP_OK) { | 370 if (response_code == net::HTTP_OK) { |
| 370 // Successful upload | 371 // Successful upload |
| 371 upload_fetcher_.reset(); | 372 upload_fetcher_.reset(); |
| 372 access_token_.clear(); | 373 access_token_.clear(); |
| 373 post_data_.reset(); | 374 post_data_.reset(); |
| 374 state_ = SUCCESS; | 375 state_ = SUCCESS; |
| 375 delegate_->OnSuccess(); | 376 delegate_->OnSuccess(); |
| 376 } else if (response_code == net::HTTP_UNAUTHORIZED) { | 377 } else if (response_code == net::HTTP_UNAUTHORIZED) { |
| 377 LOG(ERROR) << "Unauthorized request."; | 378 CHROMEOS_SYSLOG(ERROR) << "Unauthorized request."; |
| 378 HandleError(AUTHENTICATION_ERROR); | 379 HandleError(AUTHENTICATION_ERROR); |
| 379 } else { | 380 } else { |
| 380 LOG(ERROR) << "POST request failed with HTTP status code " | 381 CHROMEOS_SYSLOG(ERROR) << "POST request failed with HTTP status code " |
| 381 << response_code << "."; | 382 << response_code << "."; |
| 382 HandleError(SERVER_ERROR); | 383 HandleError(SERVER_ERROR); |
| 383 } | 384 } |
| 384 } | 385 } |
| 385 } | 386 } |
| 386 | 387 |
| 387 } // namespace policy | 388 } // namespace policy |
| OLD | NEW |