OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "google_apis/drive/base_requests.h" | 5 #include "google_apis/drive/base_requests.h" |
6 | 6 |
7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/sequenced_task_runner.h" | 9 #include "base/sequenced_task_runner.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 // Template for initiate upload of both GData WAPI and Drive API v2. | 37 // Template for initiate upload of both GData WAPI and Drive API v2. |
38 const char kUploadContentType[] = "X-Upload-Content-Type: "; | 38 const char kUploadContentType[] = "X-Upload-Content-Type: "; |
39 const char kUploadContentLength[] = "X-Upload-Content-Length: "; | 39 const char kUploadContentLength[] = "X-Upload-Content-Length: "; |
40 const char kUploadResponseLocation[] = "location"; | 40 const char kUploadResponseLocation[] = "location"; |
41 | 41 |
42 // Template for upload data range of both GData WAPI and Drive API v2. | 42 // Template for upload data range of both GData WAPI and Drive API v2. |
43 const char kUploadContentRange[] = "Content-Range: bytes "; | 43 const char kUploadContentRange[] = "Content-Range: bytes "; |
44 const char kUploadResponseRange[] = "range"; | 44 const char kUploadResponseRange[] = "range"; |
45 | 45 |
46 // Parse JSON string to base::Value object. | 46 // Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on |
47 scoped_ptr<base::Value> ParseJsonInternal(const std::string& json) { | 47 // the calling thread when finished with either success or failure. |
48 int error_code = -1; | 48 // The callback must not be null. |
49 std::string error_message; | 49 void ParseJsonOnBlockingPool( |
50 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | 50 base::TaskRunner* blocking_task_runner, |
51 json, base::JSON_PARSE_RFC, &error_code, &error_message)); | 51 const std::string& json, |
52 | 52 const base::Callback<void(scoped_ptr<base::Value> value)>& callback) { |
53 if (!value.get()) { | 53 base::PostTaskAndReplyWithResult( |
54 std::string trimmed_json; | 54 blocking_task_runner, |
55 if (json.size() < 80) { | 55 FROM_HERE, |
56 trimmed_json = json; | 56 base::Bind(&google_apis::ParseJson, json), |
57 } else { | 57 callback); |
58 // Take the first 50 and the last 10 bytes. | |
59 trimmed_json = base::StringPrintf( | |
60 "%s [%s bytes] %s", | |
61 json.substr(0, 50).c_str(), | |
62 base::Uint64ToString(json.size() - 60).c_str(), | |
63 json.substr(json.size() - 10).c_str()); | |
64 } | |
65 LOG(WARNING) << "Error while parsing entry response: " << error_message | |
66 << ", code: " << error_code << ", json:\n" << trimmed_json; | |
67 } | |
68 return value.Pass(); | |
69 } | 58 } |
70 | 59 |
71 // Returns response headers as a string. Returns a warning message if | 60 // Returns response headers as a string. Returns a warning message if |
72 // |url_fetcher| does not contain a valid response. Used only for debugging. | 61 // |url_fetcher| does not contain a valid response. Used only for debugging. |
73 std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { | 62 std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { |
74 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores | 63 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores |
75 // all headers in their raw format, i.e each header is null-terminated. | 64 // all headers in their raw format, i.e each header is null-terminated. |
76 // So logging raw_headers() only shows the first header, which is probably | 65 // So logging raw_headers() only shows the first header, which is probably |
77 // the status line. GetNormalizedHeaders, on the other hand, will show all | 66 // the status line. GetNormalizedHeaders, on the other hand, will show all |
78 // the headers, one per line, which is probably what we want. | 67 // the headers, one per line, which is probably what we want. |
79 std::string headers; | 68 std::string headers; |
80 // Check that response code indicates response headers are valid (i.e. not | 69 // Check that response code indicates response headers are valid (i.e. not |
81 // malformed) before we retrieve the headers. | 70 // malformed) before we retrieve the headers. |
82 if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { | 71 if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { |
83 headers.assign("Response headers are malformed!!"); | 72 headers.assign("Response headers are malformed!!"); |
84 } else { | 73 } else { |
85 url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); | 74 url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); |
86 } | 75 } |
87 return headers; | 76 return headers; |
88 } | 77 } |
89 | 78 |
90 bool IsSuccessfulResponseCode(int response_code) { | 79 bool IsSuccessfulResponseCode(int response_code) { |
91 return 200 <= response_code && response_code <= 299; | 80 return 200 <= response_code && response_code <= 299; |
92 } | 81 } |
93 | 82 |
94 } // namespace | 83 } // namespace |
95 | 84 |
96 namespace google_apis { | 85 namespace google_apis { |
97 | 86 |
98 void ParseJson(base::TaskRunner* blocking_task_runner, | 87 scoped_ptr<base::Value> ParseJson(const std::string& json) { |
99 const std::string& json, | 88 int error_code = -1; |
100 const ParseJsonCallback& callback) { | 89 std::string error_message; |
101 base::PostTaskAndReplyWithResult( | 90 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( |
102 blocking_task_runner, | 91 json, base::JSON_PARSE_RFC, &error_code, &error_message)); |
103 FROM_HERE, | 92 |
104 base::Bind(&ParseJsonInternal, json), | 93 if (!value.get()) { |
105 callback); | 94 std::string trimmed_json; |
| 95 if (json.size() < 80) { |
| 96 trimmed_json = json; |
| 97 } else { |
| 98 // Take the first 50 and the last 10 bytes. |
| 99 trimmed_json = base::StringPrintf( |
| 100 "%s [%s bytes] %s", |
| 101 json.substr(0, 50).c_str(), |
| 102 base::Uint64ToString(json.size() - 60).c_str(), |
| 103 json.substr(json.size() - 10).c_str()); |
| 104 } |
| 105 LOG(WARNING) << "Error while parsing entry response: " << error_message |
| 106 << ", code: " << error_code << ", json:\n" << trimmed_json; |
| 107 } |
| 108 return value.Pass(); |
106 } | 109 } |
107 | 110 |
108 //=========================== ResponseWriter ================================== | 111 //=========================== ResponseWriter ================================== |
109 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, | 112 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, |
110 const base::FilePath& file_path, | 113 const base::FilePath& file_path, |
111 const GetContentCallback& get_content_callback) | 114 const GetContentCallback& get_content_callback) |
112 : get_content_callback_(get_content_callback), | 115 : get_content_callback_(get_content_callback), |
113 weak_ptr_factory_(this) { | 116 weak_ptr_factory_(this) { |
114 if (!file_path.empty()) { | 117 if (!file_path.empty()) { |
115 file_writer_.reset( | 118 file_writer_.reset( |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 DVLOG(1) << response_writer_->data(); | 355 DVLOG(1) << response_writer_->data(); |
353 | 356 |
354 const char kErrorKey[] = "error"; | 357 const char kErrorKey[] = "error"; |
355 const char kErrorErrorsKey[] = "errors"; | 358 const char kErrorErrorsKey[] = "errors"; |
356 const char kErrorReasonKey[] = "reason"; | 359 const char kErrorReasonKey[] = "reason"; |
357 const char kErrorMessageKey[] = "message"; | 360 const char kErrorMessageKey[] = "message"; |
358 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; | 361 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; |
359 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; | 362 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; |
360 const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; | 363 const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; |
361 | 364 |
362 scoped_ptr<base::Value> value(ParseJsonInternal(response_writer_->data())); | 365 scoped_ptr<base::Value> value(ParseJson(response_writer_->data())); |
363 base::DictionaryValue* dictionary = NULL; | 366 base::DictionaryValue* dictionary = NULL; |
364 base::DictionaryValue* error = NULL; | 367 base::DictionaryValue* error = NULL; |
365 if (value && | 368 if (value && |
366 value->GetAsDictionary(&dictionary) && | 369 value->GetAsDictionary(&dictionary) && |
367 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { | 370 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { |
368 // Get error message. | 371 // Get error message. |
369 std::string message; | 372 std::string message; |
370 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); | 373 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); |
371 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; | 374 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; |
372 | 375 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 | 430 |
428 void EntryActionRequest::ProcessURLFetchResults(const URLFetcher* source) { | 431 void EntryActionRequest::ProcessURLFetchResults(const URLFetcher* source) { |
429 callback_.Run(GetErrorCode()); | 432 callback_.Run(GetErrorCode()); |
430 OnProcessURLFetchResultsComplete(); | 433 OnProcessURLFetchResultsComplete(); |
431 } | 434 } |
432 | 435 |
433 void EntryActionRequest::RunCallbackOnPrematureFailure(GDataErrorCode code) { | 436 void EntryActionRequest::RunCallbackOnPrematureFailure(GDataErrorCode code) { |
434 callback_.Run(code); | 437 callback_.Run(code); |
435 } | 438 } |
436 | 439 |
437 //============================== GetDataRequest ============================== | |
438 | |
439 GetDataRequest::GetDataRequest(RequestSender* sender, | |
440 const GetDataCallback& callback) | |
441 : UrlFetchRequestBase(sender), | |
442 callback_(callback), | |
443 weak_ptr_factory_(this) { | |
444 DCHECK(!callback_.is_null()); | |
445 } | |
446 | |
447 GetDataRequest::~GetDataRequest() {} | |
448 | |
449 void GetDataRequest::ParseResponse(GDataErrorCode fetch_error_code, | |
450 const std::string& data) { | |
451 DCHECK(CalledOnValidThread()); | |
452 | |
453 VLOG(1) << "JSON received from " << GetURL().spec() << ": " | |
454 << data.size() << " bytes"; | |
455 ParseJson(blocking_task_runner(), | |
456 data, | |
457 base::Bind(&GetDataRequest::OnDataParsed, | |
458 weak_ptr_factory_.GetWeakPtr(), | |
459 fetch_error_code)); | |
460 } | |
461 | |
462 void GetDataRequest::ProcessURLFetchResults(const URLFetcher* source) { | |
463 GDataErrorCode fetch_error_code = GetErrorCode(); | |
464 | |
465 switch (fetch_error_code) { | |
466 case HTTP_SUCCESS: | |
467 case HTTP_CREATED: | |
468 ParseResponse(fetch_error_code, response_writer()->data()); | |
469 break; | |
470 default: | |
471 RunCallbackOnPrematureFailure(fetch_error_code); | |
472 OnProcessURLFetchResultsComplete(); | |
473 break; | |
474 } | |
475 } | |
476 | |
477 void GetDataRequest::RunCallbackOnPrematureFailure( | |
478 GDataErrorCode fetch_error_code) { | |
479 callback_.Run(fetch_error_code, scoped_ptr<base::Value>()); | |
480 } | |
481 | |
482 void GetDataRequest::OnDataParsed(GDataErrorCode fetch_error_code, | |
483 scoped_ptr<base::Value> value) { | |
484 DCHECK(CalledOnValidThread()); | |
485 | |
486 if (!value.get()) | |
487 fetch_error_code = GDATA_PARSE_ERROR; | |
488 | |
489 callback_.Run(fetch_error_code, value.Pass()); | |
490 OnProcessURLFetchResultsComplete(); | |
491 } | |
492 | |
493 //========================= InitiateUploadRequestBase ======================== | 440 //========================= InitiateUploadRequestBase ======================== |
494 | 441 |
495 InitiateUploadRequestBase::InitiateUploadRequestBase( | 442 InitiateUploadRequestBase::InitiateUploadRequestBase( |
496 RequestSender* sender, | 443 RequestSender* sender, |
497 const InitiateUploadCallback& callback, | 444 const InitiateUploadCallback& callback, |
498 const std::string& content_type, | 445 const std::string& content_type, |
499 int64 content_length) | 446 int64 content_length) |
500 : UrlFetchRequestBase(sender), | 447 : UrlFetchRequestBase(sender), |
501 callback_(callback), | 448 callback_(callback), |
502 content_type_(content_type), | 449 content_type_(content_type), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 | 558 |
612 OnRangeRequestComplete(UploadRangeResponse(code, | 559 OnRangeRequestComplete(UploadRangeResponse(code, |
613 start_position_received, | 560 start_position_received, |
614 end_position_received), | 561 end_position_received), |
615 scoped_ptr<base::Value>()); | 562 scoped_ptr<base::Value>()); |
616 | 563 |
617 OnProcessURLFetchResultsComplete(); | 564 OnProcessURLFetchResultsComplete(); |
618 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { | 565 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { |
619 // The upload is successfully done. Parse the response which should be | 566 // The upload is successfully done. Parse the response which should be |
620 // the entry's metadata. | 567 // the entry's metadata. |
621 ParseJson(blocking_task_runner(), | 568 ParseJsonOnBlockingPool(blocking_task_runner(), |
622 response_writer()->data(), | 569 response_writer()->data(), |
623 base::Bind(&UploadRangeRequestBase::OnDataParsed, | 570 base::Bind(&UploadRangeRequestBase::OnDataParsed, |
624 weak_ptr_factory_.GetWeakPtr(), | 571 weak_ptr_factory_.GetWeakPtr(), |
625 code)); | 572 code)); |
626 } else { | 573 } else { |
627 // Failed to upload. Run callbacks to notify the error. | 574 // Failed to upload. Run callbacks to notify the error. |
628 OnRangeRequestComplete( | 575 OnRangeRequestComplete( |
629 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); | 576 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); |
630 OnProcessURLFetchResultsComplete(); | 577 OnProcessURLFetchResultsComplete(); |
631 } | 578 } |
632 } | 579 } |
633 | 580 |
634 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, | 581 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, |
635 scoped_ptr<base::Value> value) { | 582 scoped_ptr<base::Value> value) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 download_action_callback_.Run(code, temp_file); | 739 download_action_callback_.Run(code, temp_file); |
793 OnProcessURLFetchResultsComplete(); | 740 OnProcessURLFetchResultsComplete(); |
794 } | 741 } |
795 | 742 |
796 void DownloadFileRequestBase::RunCallbackOnPrematureFailure( | 743 void DownloadFileRequestBase::RunCallbackOnPrematureFailure( |
797 GDataErrorCode code) { | 744 GDataErrorCode code) { |
798 download_action_callback_.Run(code, base::FilePath()); | 745 download_action_callback_.Run(code, base::FilePath()); |
799 } | 746 } |
800 | 747 |
801 } // namespace google_apis | 748 } // namespace google_apis |
OLD | NEW |