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

Side by Side Diff: google_apis/drive/base_requests.cc

Issue 442193002: Parse Drive API responses all at once in the blocking pool. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
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
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( 62 std::string GetResponseHeadersAsString(
74 const URLFetcher* url_fetcher) { 63 const URLFetcher* url_fetcher) {
75 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores 64 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores
76 // all headers in their raw format, i.e each header is null-terminated. 65 // all headers in their raw format, i.e each header is null-terminated.
77 // So logging raw_headers() only shows the first header, which is probably 66 // So logging raw_headers() only shows the first header, which is probably
78 // the status line. GetNormalizedHeaders, on the other hand, will show all 67 // the status line. GetNormalizedHeaders, on the other hand, will show all
(...skipping 10 matching lines...) Expand all
89 } 78 }
90 79
91 bool IsSuccessfulResponseCode(int response_code) { 80 bool IsSuccessfulResponseCode(int response_code) {
92 return 200 <= response_code && response_code <= 299; 81 return 200 <= response_code && response_code <= 299;
93 } 82 }
94 83
95 } // namespace 84 } // namespace
96 85
97 namespace google_apis { 86 namespace google_apis {
98 87
99 void ParseJson(base::TaskRunner* blocking_task_runner, 88 scoped_ptr<base::Value> ParseJson(const std::string& json) {
100 const std::string& json, 89 int error_code = -1;
101 const ParseJsonCallback& callback) { 90 std::string error_message;
102 base::PostTaskAndReplyWithResult( 91 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
103 blocking_task_runner, 92 json, base::JSON_PARSE_RFC, &error_code, &error_message));
104 FROM_HERE, 93
105 base::Bind(&ParseJsonInternal, json), 94 if (!value.get()) {
106 callback); 95 std::string trimmed_json;
96 if (json.size() < 80) {
97 trimmed_json = json;
98 } else {
99 // Take the first 50 and the last 10 bytes.
100 trimmed_json = base::StringPrintf(
101 "%s [%s bytes] %s",
102 json.substr(0, 50).c_str(),
103 base::Uint64ToString(json.size() - 60).c_str(),
104 json.substr(json.size() - 10).c_str());
105 }
106 LOG(WARNING) << "Error while parsing entry response: " << error_message
107 << ", code: " << error_code << ", json:\n" << trimmed_json;
108 }
109 return value.Pass();
107 } 110 }
108 111
109 //=========================== ResponseWriter ================================== 112 //=========================== ResponseWriter ==================================
110 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, 113 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner,
111 const base::FilePath& file_path, 114 const base::FilePath& file_path,
112 const GetContentCallback& get_content_callback) 115 const GetContentCallback& get_content_callback)
113 : get_content_callback_(get_content_callback), 116 : get_content_callback_(get_content_callback),
114 weak_ptr_factory_(this) { 117 weak_ptr_factory_(this) {
115 if (!file_path.empty()) { 118 if (!file_path.empty()) {
116 file_writer_.reset( 119 file_writer_.reset(
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 DVLOG(1) << response_writer_->data(); 356 DVLOG(1) << response_writer_->data();
354 357
355 const char kErrorKey[] = "error"; 358 const char kErrorKey[] = "error";
356 const char kErrorErrorsKey[] = "errors"; 359 const char kErrorErrorsKey[] = "errors";
357 const char kErrorReasonKey[] = "reason"; 360 const char kErrorReasonKey[] = "reason";
358 const char kErrorMessageKey[] = "message"; 361 const char kErrorMessageKey[] = "message";
359 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; 362 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded";
360 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; 363 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded";
361 const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; 364 const char kErrorReasonQuotaExceeded[] = "quotaExceeded";
362 365
363 scoped_ptr<base::Value> value(ParseJsonInternal(response_writer_->data())); 366 scoped_ptr<base::Value> value(ParseJson(response_writer_->data()));
364 base::DictionaryValue* dictionary = NULL; 367 base::DictionaryValue* dictionary = NULL;
365 base::DictionaryValue* error = NULL; 368 base::DictionaryValue* error = NULL;
366 if (value && 369 if (value &&
367 value->GetAsDictionary(&dictionary) && 370 value->GetAsDictionary(&dictionary) &&
368 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { 371 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) {
369 // Get error message. 372 // Get error message.
370 std::string message; 373 std::string message;
371 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); 374 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message);
372 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; 375 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message;
373 376
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 } 449 }
447 450
448 GetDataRequest::~GetDataRequest() {} 451 GetDataRequest::~GetDataRequest() {}
449 452
450 void GetDataRequest::ParseResponse(GDataErrorCode fetch_error_code, 453 void GetDataRequest::ParseResponse(GDataErrorCode fetch_error_code,
451 const std::string& data) { 454 const std::string& data) {
452 DCHECK(CalledOnValidThread()); 455 DCHECK(CalledOnValidThread());
453 456
454 VLOG(1) << "JSON received from " << GetURL().spec() << ": " 457 VLOG(1) << "JSON received from " << GetURL().spec() << ": "
455 << data.size() << " bytes"; 458 << data.size() << " bytes";
456 ParseJson(blocking_task_runner(), 459 ParseJsonOnBlockingPool(blocking_task_runner(),
457 data, 460 data,
458 base::Bind(&GetDataRequest::OnDataParsed, 461 base::Bind(&GetDataRequest::OnDataParsed,
459 weak_ptr_factory_.GetWeakPtr(), 462 weak_ptr_factory_.GetWeakPtr(),
460 fetch_error_code)); 463 fetch_error_code));
461 } 464 }
462 465
463 void GetDataRequest::ProcessURLFetchResults(const URLFetcher* source) { 466 void GetDataRequest::ProcessURLFetchResults(const URLFetcher* source) {
464 GDataErrorCode fetch_error_code = GetErrorCode(); 467 GDataErrorCode fetch_error_code = GetErrorCode();
465 468
466 switch (fetch_error_code) { 469 switch (fetch_error_code) {
467 case HTTP_SUCCESS: 470 case HTTP_SUCCESS:
468 case HTTP_CREATED: 471 case HTTP_CREATED:
469 ParseResponse(fetch_error_code, response_writer()->data()); 472 ParseResponse(fetch_error_code, response_writer()->data());
470 break; 473 break;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 615
613 OnRangeRequestComplete(UploadRangeResponse(code, 616 OnRangeRequestComplete(UploadRangeResponse(code,
614 start_position_received, 617 start_position_received,
615 end_position_received), 618 end_position_received),
616 scoped_ptr<base::Value>()); 619 scoped_ptr<base::Value>());
617 620
618 OnProcessURLFetchResultsComplete(); 621 OnProcessURLFetchResultsComplete();
619 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { 622 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) {
620 // The upload is successfully done. Parse the response which should be 623 // The upload is successfully done. Parse the response which should be
621 // the entry's metadata. 624 // the entry's metadata.
622 ParseJson(blocking_task_runner(), 625 ParseJsonOnBlockingPool(blocking_task_runner(),
623 response_writer()->data(), 626 response_writer()->data(),
624 base::Bind(&UploadRangeRequestBase::OnDataParsed, 627 base::Bind(&UploadRangeRequestBase::OnDataParsed,
625 weak_ptr_factory_.GetWeakPtr(), 628 weak_ptr_factory_.GetWeakPtr(),
626 code)); 629 code));
627 } else { 630 } else {
628 // Failed to upload. Run callbacks to notify the error. 631 // Failed to upload. Run callbacks to notify the error.
629 OnRangeRequestComplete( 632 OnRangeRequestComplete(
630 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); 633 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>());
631 OnProcessURLFetchResultsComplete(); 634 OnProcessURLFetchResultsComplete();
632 } 635 }
633 } 636 }
634 637
635 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, 638 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code,
636 scoped_ptr<base::Value> value) { 639 scoped_ptr<base::Value> value) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 download_action_callback_.Run(code, temp_file); 796 download_action_callback_.Run(code, temp_file);
794 OnProcessURLFetchResultsComplete(); 797 OnProcessURLFetchResultsComplete();
795 } 798 }
796 799
797 void DownloadFileRequestBase::RunCallbackOnPrematureFailure( 800 void DownloadFileRequestBase::RunCallbackOnPrematureFailure(
798 GDataErrorCode code) { 801 GDataErrorCode code) {
799 download_action_callback_.Run(code, base::FilePath()); 802 download_action_callback_.Run(code, base::FilePath());
800 } 803 }
801 804
802 } // namespace google_apis 805 } // namespace google_apis
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698