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 // Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on | 46 // Parse JSON string to base::Value object. |
47 // the calling thread when finished with either success or failure. | 47 scoped_ptr<base::Value> ParseJsonInternal(const std::string& json) { |
48 // The callback must not be null. | 48 int error_code = -1; |
49 void ParseJsonOnBlockingPool( | 49 std::string error_message; |
50 base::TaskRunner* blocking_task_runner, | 50 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( |
51 const std::string& json, | 51 json, base::JSON_PARSE_RFC, &error_code, &error_message)); |
52 const base::Callback<void(scoped_ptr<base::Value> value)>& callback) { | 52 |
53 base::PostTaskAndReplyWithResult( | 53 if (!value.get()) { |
54 blocking_task_runner, | 54 std::string trimmed_json; |
55 FROM_HERE, | 55 if (json.size() < 80) { |
56 base::Bind(&google_apis::ParseJson, json), | 56 trimmed_json = json; |
57 callback); | 57 } else { |
| 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(); |
58 } | 69 } |
59 | 70 |
60 // Returns response headers as a string. Returns a warning message if | 71 // Returns response headers as a string. Returns a warning message if |
61 // |url_fetcher| does not contain a valid response. Used only for debugging. | 72 // |url_fetcher| does not contain a valid response. Used only for debugging. |
62 std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { | 73 std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { |
63 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores | 74 // net::HttpResponseHeaders::raw_headers(), as the name implies, stores |
64 // all headers in their raw format, i.e each header is null-terminated. | 75 // all headers in their raw format, i.e each header is null-terminated. |
65 // So logging raw_headers() only shows the first header, which is probably | 76 // So logging raw_headers() only shows the first header, which is probably |
66 // the status line. GetNormalizedHeaders, on the other hand, will show all | 77 // the status line. GetNormalizedHeaders, on the other hand, will show all |
67 // the headers, one per line, which is probably what we want. | 78 // the headers, one per line, which is probably what we want. |
68 std::string headers; | 79 std::string headers; |
69 // Check that response code indicates response headers are valid (i.e. not | 80 // Check that response code indicates response headers are valid (i.e. not |
70 // malformed) before we retrieve the headers. | 81 // malformed) before we retrieve the headers. |
71 if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { | 82 if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { |
72 headers.assign("Response headers are malformed!!"); | 83 headers.assign("Response headers are malformed!!"); |
73 } else { | 84 } else { |
74 url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); | 85 url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); |
75 } | 86 } |
76 return headers; | 87 return headers; |
77 } | 88 } |
78 | 89 |
79 bool IsSuccessfulResponseCode(int response_code) { | 90 bool IsSuccessfulResponseCode(int response_code) { |
80 return 200 <= response_code && response_code <= 299; | 91 return 200 <= response_code && response_code <= 299; |
81 } | 92 } |
82 | 93 |
83 } // namespace | 94 } // namespace |
84 | 95 |
85 namespace google_apis { | 96 namespace google_apis { |
86 | 97 |
87 scoped_ptr<base::Value> ParseJson(const std::string& json) { | 98 void ParseJson(base::TaskRunner* blocking_task_runner, |
88 int error_code = -1; | 99 const std::string& json, |
89 std::string error_message; | 100 const ParseJsonCallback& callback) { |
90 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | 101 base::PostTaskAndReplyWithResult( |
91 json, base::JSON_PARSE_RFC, &error_code, &error_message)); | 102 blocking_task_runner, |
92 | 103 FROM_HERE, |
93 if (!value.get()) { | 104 base::Bind(&ParseJsonInternal, json), |
94 std::string trimmed_json; | 105 callback); |
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(); | |
109 } | 106 } |
110 | 107 |
111 //=========================== ResponseWriter ================================== | 108 //=========================== ResponseWriter ================================== |
112 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, | 109 ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, |
113 const base::FilePath& file_path, | 110 const base::FilePath& file_path, |
114 const GetContentCallback& get_content_callback) | 111 const GetContentCallback& get_content_callback) |
115 : get_content_callback_(get_content_callback), | 112 : get_content_callback_(get_content_callback), |
116 weak_ptr_factory_(this) { | 113 weak_ptr_factory_(this) { |
117 if (!file_path.empty()) { | 114 if (!file_path.empty()) { |
118 file_writer_.reset( | 115 file_writer_.reset( |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 DVLOG(1) << response_writer_->data(); | 352 DVLOG(1) << response_writer_->data(); |
356 | 353 |
357 const char kErrorKey[] = "error"; | 354 const char kErrorKey[] = "error"; |
358 const char kErrorErrorsKey[] = "errors"; | 355 const char kErrorErrorsKey[] = "errors"; |
359 const char kErrorReasonKey[] = "reason"; | 356 const char kErrorReasonKey[] = "reason"; |
360 const char kErrorMessageKey[] = "message"; | 357 const char kErrorMessageKey[] = "message"; |
361 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; | 358 const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; |
362 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; | 359 const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; |
363 const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; | 360 const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; |
364 | 361 |
365 scoped_ptr<base::Value> value(ParseJson(response_writer_->data())); | 362 scoped_ptr<base::Value> value(ParseJsonInternal(response_writer_->data())); |
366 base::DictionaryValue* dictionary = NULL; | 363 base::DictionaryValue* dictionary = NULL; |
367 base::DictionaryValue* error = NULL; | 364 base::DictionaryValue* error = NULL; |
368 if (value && | 365 if (value && |
369 value->GetAsDictionary(&dictionary) && | 366 value->GetAsDictionary(&dictionary) && |
370 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { | 367 dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { |
371 // Get error message. | 368 // Get error message. |
372 std::string message; | 369 std::string message; |
373 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); | 370 error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); |
374 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; | 371 DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; |
375 | 372 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 | 427 |
431 void EntryActionRequest::ProcessURLFetchResults(const URLFetcher* source) { | 428 void EntryActionRequest::ProcessURLFetchResults(const URLFetcher* source) { |
432 callback_.Run(GetErrorCode()); | 429 callback_.Run(GetErrorCode()); |
433 OnProcessURLFetchResultsComplete(); | 430 OnProcessURLFetchResultsComplete(); |
434 } | 431 } |
435 | 432 |
436 void EntryActionRequest::RunCallbackOnPrematureFailure(GDataErrorCode code) { | 433 void EntryActionRequest::RunCallbackOnPrematureFailure(GDataErrorCode code) { |
437 callback_.Run(code); | 434 callback_.Run(code); |
438 } | 435 } |
439 | 436 |
| 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 |
440 //========================= InitiateUploadRequestBase ======================== | 493 //========================= InitiateUploadRequestBase ======================== |
441 | 494 |
442 InitiateUploadRequestBase::InitiateUploadRequestBase( | 495 InitiateUploadRequestBase::InitiateUploadRequestBase( |
443 RequestSender* sender, | 496 RequestSender* sender, |
444 const InitiateUploadCallback& callback, | 497 const InitiateUploadCallback& callback, |
445 const std::string& content_type, | 498 const std::string& content_type, |
446 int64 content_length) | 499 int64 content_length) |
447 : UrlFetchRequestBase(sender), | 500 : UrlFetchRequestBase(sender), |
448 callback_(callback), | 501 callback_(callback), |
449 content_type_(content_type), | 502 content_type_(content_type), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 | 611 |
559 OnRangeRequestComplete(UploadRangeResponse(code, | 612 OnRangeRequestComplete(UploadRangeResponse(code, |
560 start_position_received, | 613 start_position_received, |
561 end_position_received), | 614 end_position_received), |
562 scoped_ptr<base::Value>()); | 615 scoped_ptr<base::Value>()); |
563 | 616 |
564 OnProcessURLFetchResultsComplete(); | 617 OnProcessURLFetchResultsComplete(); |
565 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { | 618 } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { |
566 // The upload is successfully done. Parse the response which should be | 619 // The upload is successfully done. Parse the response which should be |
567 // the entry's metadata. | 620 // the entry's metadata. |
568 ParseJsonOnBlockingPool(blocking_task_runner(), | 621 ParseJson(blocking_task_runner(), |
569 response_writer()->data(), | 622 response_writer()->data(), |
570 base::Bind(&UploadRangeRequestBase::OnDataParsed, | 623 base::Bind(&UploadRangeRequestBase::OnDataParsed, |
571 weak_ptr_factory_.GetWeakPtr(), | 624 weak_ptr_factory_.GetWeakPtr(), |
572 code)); | 625 code)); |
573 } else { | 626 } else { |
574 // Failed to upload. Run callbacks to notify the error. | 627 // Failed to upload. Run callbacks to notify the error. |
575 OnRangeRequestComplete( | 628 OnRangeRequestComplete( |
576 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); | 629 UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); |
577 OnProcessURLFetchResultsComplete(); | 630 OnProcessURLFetchResultsComplete(); |
578 } | 631 } |
579 } | 632 } |
580 | 633 |
581 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, | 634 void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, |
582 scoped_ptr<base::Value> value) { | 635 scoped_ptr<base::Value> value) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 download_action_callback_.Run(code, temp_file); | 792 download_action_callback_.Run(code, temp_file); |
740 OnProcessURLFetchResultsComplete(); | 793 OnProcessURLFetchResultsComplete(); |
741 } | 794 } |
742 | 795 |
743 void DownloadFileRequestBase::RunCallbackOnPrematureFailure( | 796 void DownloadFileRequestBase::RunCallbackOnPrematureFailure( |
744 GDataErrorCode code) { | 797 GDataErrorCode code) { |
745 download_action_callback_.Run(code, base::FilePath()); | 798 download_action_callback_.Run(code, base::FilePath()); |
746 } | 799 } |
747 | 800 |
748 } // namespace google_apis | 801 } // namespace google_apis |
OLD | NEW |