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 "chrome/browser/google_apis/gdata_wapi_operations.h" | 5 #include "chrome/browser/google_apis/gdata_wapi_operations.h" |
6 | 6 |
7 #include "base/stringprintf.h" | 7 #include "base/stringprintf.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/browser/google_apis/gdata_wapi_parser.h" | 10 #include "chrome/browser/google_apis/gdata_wapi_parser.h" |
11 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h" | 11 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h" |
12 #include "chrome/browser/google_apis/time_util.h" | 12 #include "chrome/browser/google_apis/time_util.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "net/base/escape.h" | 14 #include "net/base/escape.h" |
15 #include "net/base/url_util.h" | 15 #include "net/base/url_util.h" |
16 #include "third_party/libxml/chromium/libxml_utils.h" | 16 #include "third_party/libxml/chromium/libxml_utils.h" |
17 | 17 |
18 using content::BrowserThread; | 18 using content::BrowserThread; |
19 using net::URLFetcher; | 19 using net::URLFetcher; |
20 | 20 |
| 21 namespace google_apis { |
| 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 // etag matching header. | 25 // etag matching header. |
24 const char kIfMatchAllHeader[] = "If-Match: *"; | 26 const char kIfMatchAllHeader[] = "If-Match: *"; |
25 const char kIfMatchHeaderPrefix[] = "If-Match: "; | 27 const char kIfMatchHeaderPrefix[] = "If-Match: "; |
26 | 28 |
27 const char kUploadContentRange[] = "Content-Range: bytes "; | 29 const char kUploadContentRange[] = "Content-Range: bytes "; |
28 | 30 |
29 const char kFeedField[] = "feed"; | 31 const char kFeedField[] = "feed"; |
30 | 32 |
31 // Returns If-Match header string for |etag|. | 33 // Returns If-Match header string for |etag|. |
32 // If |etag| is empty, the returned header should match any etag. | 34 // If |etag| is empty, the returned header should match any etag. |
33 std::string GenerateIfMatchHeader(const std::string& etag) { | 35 std::string GenerateIfMatchHeader(const std::string& etag) { |
34 return etag.empty() ? kIfMatchAllHeader : (kIfMatchHeaderPrefix + etag); | 36 return etag.empty() ? kIfMatchAllHeader : (kIfMatchHeaderPrefix + etag); |
35 } | 37 } |
36 | 38 |
| 39 // Parses the |value| to ResourceEntry with error handling. |
| 40 // This is designed to be used for ResumeUploadOperation and |
| 41 // GetUploadStatusOperation. |
| 42 scoped_ptr<ResourceEntry> ParseResourceEntry(scoped_ptr<base::Value> value) { |
| 43 scoped_ptr<ResourceEntry> entry; |
| 44 if (value.get()) { |
| 45 entry = ResourceEntry::ExtractAndParse(*value); |
| 46 |
| 47 // Note: |value| may be NULL, in particular if the callback is for a |
| 48 // failure. |
| 49 if (!entry.get()) |
| 50 LOG(WARNING) << "Invalid entry received on upload."; |
| 51 } |
| 52 |
| 53 return entry.Pass(); |
| 54 } |
| 55 |
37 } // namespace | 56 } // namespace |
38 | 57 |
39 namespace google_apis { | |
40 | |
41 //============================ Structs =========================== | 58 //============================ Structs =========================== |
42 | 59 |
43 UploadRangeResponse::UploadRangeResponse() | 60 UploadRangeResponse::UploadRangeResponse() |
44 : code(HTTP_SUCCESS), | 61 : code(HTTP_SUCCESS), |
45 start_position_received(0), | 62 start_position_received(0), |
46 end_position_received(0) { | 63 end_position_received(0) { |
47 } | 64 } |
48 | 65 |
49 UploadRangeResponse::UploadRangeResponse(GDataErrorCode code, | 66 UploadRangeResponse::UploadRangeResponse(GDataErrorCode code, |
50 int64 start_position_received, | 67 int64 start_position_received, |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // For uploading an empty document, just PUT an empty content. | 614 // For uploading an empty document, just PUT an empty content. |
598 DCHECK_EQ(start_position_, 0); | 615 DCHECK_EQ(start_position_, 0); |
599 DCHECK_EQ(end_position_, 0); | 616 DCHECK_EQ(end_position_, 0); |
600 return std::vector<std::string>(); | 617 return std::vector<std::string>(); |
601 } | 618 } |
602 | 619 |
603 // The header looks like | 620 // The header looks like |
604 // Content-Range: bytes <start_position>-<end_position>/<content_length> | 621 // Content-Range: bytes <start_position>-<end_position>/<content_length> |
605 // for example: | 622 // for example: |
606 // Content-Range: bytes 7864320-8388607/13851821 | 623 // Content-Range: bytes 7864320-8388607/13851821 |
607 // Use * for unknown/streaming content length. | |
608 // The header takes inclusive range, so we adjust by "end_position - 1". | 624 // The header takes inclusive range, so we adjust by "end_position - 1". |
609 DCHECK_GE(start_position_, 0); | 625 DCHECK_GE(start_position_, 0); |
610 DCHECK_GT(end_position_, 0); | 626 DCHECK_GT(end_position_, 0); |
611 DCHECK_GE(content_length_, -1); | 627 DCHECK_GE(content_length_, 0); |
612 | 628 |
613 std::vector<std::string> headers; | 629 std::vector<std::string> headers; |
614 headers.push_back( | 630 headers.push_back( |
615 std::string(kUploadContentRange) + | 631 std::string(kUploadContentRange) + |
616 base::Int64ToString(start_position_) + "-" + | 632 base::Int64ToString(start_position_) + "-" + |
617 base::Int64ToString(end_position_ - 1) + "/" + | 633 base::Int64ToString(end_position_ - 1) + "/" + |
618 (content_length_ == -1 ? "*" : | 634 base::Int64ToString(content_length_)); |
619 base::Int64ToString(content_length_))); | |
620 return headers; | 635 return headers; |
621 } | 636 } |
622 | 637 |
623 bool ResumeUploadOperation::GetContentData(std::string* upload_content_type, | 638 bool ResumeUploadOperation::GetContentData(std::string* upload_content_type, |
624 std::string* upload_content) { | 639 std::string* upload_content) { |
625 *upload_content_type = content_type_; | 640 *upload_content_type = content_type_; |
626 *upload_content = std::string(buf_->data(), end_position_ - start_position_); | 641 *upload_content = std::string(buf_->data(), end_position_ - start_position_); |
627 return true; | 642 return true; |
628 } | 643 } |
629 | 644 |
630 void ResumeUploadOperation::OnURLFetchUploadProgress( | 645 void ResumeUploadOperation::OnURLFetchUploadProgress( |
631 const URLFetcher* source, int64 current, int64 total) { | 646 const URLFetcher* source, int64 current, int64 total) { |
632 // Adjust the progress values according to the range currently uploaded. | 647 // Adjust the progress values according to the range currently uploaded. |
633 NotifyProgress(start_position_ + current, content_length_); | 648 NotifyProgress(start_position_ + current, content_length_); |
634 } | 649 } |
635 | 650 |
636 void ResumeUploadOperation::OnRangeOperationComplete( | 651 void ResumeUploadOperation::OnRangeOperationComplete( |
637 const UploadRangeResponse& response, scoped_ptr<base::Value> value) { | 652 const UploadRangeResponse& response, scoped_ptr<base::Value> value) { |
638 scoped_ptr<ResourceEntry> entry; | 653 callback_.Run(response, ParseResourceEntry(value.Pass())); |
639 if (value.get()) { | 654 } |
640 entry = ResourceEntry::ExtractAndParse(*value); | |
641 | 655 |
642 // Note: |value| may be NULL, in particular if the callback is for a | 656 //========================== GetUploadStatusOperation ========================== |
643 // failure. | |
644 if (!entry.get()) | |
645 LOG(WARNING) << "Invalid entry received on upload."; | |
646 } | |
647 | 657 |
648 callback_.Run(response, entry.Pass()); | 658 GetUploadStatusOperation::GetUploadStatusOperation( |
| 659 OperationRegistry* registry, |
| 660 net::URLRequestContextGetter* url_request_context_getter, |
| 661 const UploadRangeCallback& callback, |
| 662 UploadMode upload_mode, |
| 663 const base::FilePath& drive_file_path, |
| 664 const GURL& upload_url, |
| 665 int64 content_length) |
| 666 : UploadRangeOperationBase(registry, |
| 667 url_request_context_getter, |
| 668 upload_mode, |
| 669 drive_file_path, |
| 670 upload_url), |
| 671 callback_(callback), |
| 672 content_length_(content_length) {} |
| 673 |
| 674 GetUploadStatusOperation::~GetUploadStatusOperation() {} |
| 675 |
| 676 std::vector<std::string> |
| 677 GetUploadStatusOperation::GetExtraRequestHeaders() const { |
| 678 // The header looks like |
| 679 // Content-Range: bytes */<content_length> |
| 680 // for example: |
| 681 // Content-Range: bytes */13851821 |
| 682 DCHECK_GE(content_length_, 0); |
| 683 |
| 684 std::vector<std::string> headers; |
| 685 headers.push_back( |
| 686 std::string(kUploadContentRange) + "*/" + |
| 687 base::Int64ToString(content_length_)); |
| 688 return headers; |
| 689 } |
| 690 |
| 691 void GetUploadStatusOperation::OnRangeOperationComplete( |
| 692 const UploadRangeResponse& response, scoped_ptr<base::Value> value) { |
| 693 callback_.Run(response, ParseResourceEntry(value.Pass())); |
649 } | 694 } |
650 | 695 |
651 } // namespace google_apis | 696 } // namespace google_apis |
OLD | NEW |