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/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.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" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 InitiateUploadParams::~InitiateUploadParams() { | 81 InitiateUploadParams::~InitiateUploadParams() { |
82 } | 82 } |
83 | 83 |
84 ResumeUploadParams::ResumeUploadParams( | 84 ResumeUploadParams::ResumeUploadParams( |
85 UploadMode upload_mode, | 85 UploadMode upload_mode, |
86 int64 start_position, | 86 int64 start_position, |
87 int64 end_position, | 87 int64 end_position, |
88 int64 content_length, | 88 int64 content_length, |
89 const std::string& content_type, | 89 const std::string& content_type, |
90 scoped_refptr<net::IOBuffer> buf, | 90 scoped_refptr<net::IOBuffer> buf, |
| 91 int64 buffer_offset, |
91 const GURL& upload_location, | 92 const GURL& upload_location, |
92 const FilePath& drive_file_path) : upload_mode(upload_mode), | 93 const FilePath& drive_file_path) : upload_mode(upload_mode), |
93 start_position(start_position), | 94 start_position(start_position), |
94 end_position(end_position), | 95 end_position(end_position), |
95 content_length(content_length), | 96 content_length(content_length), |
96 content_type(content_type), | 97 content_type(content_type), |
97 buf(buf), | 98 buf(buf), |
| 99 buffer_offset(buffer_offset), |
98 upload_location(upload_location), | 100 upload_location(upload_location), |
99 drive_file_path(drive_file_path) { | 101 drive_file_path(drive_file_path) { |
100 } | 102 } |
101 | 103 |
102 ResumeUploadParams::~ResumeUploadParams() { | 104 ResumeUploadParams::~ResumeUploadParams() { |
103 } | 105 } |
104 | 106 |
105 //============================ GetResourceListOperation ======================== | 107 //============================ GetResourceListOperation ======================== |
106 | 108 |
107 GetResourceListOperation::GetResourceListOperation( | 109 GetResourceListOperation::GetResourceListOperation( |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 "http://schemas.google.com/docs/2007"); | 665 "http://schemas.google.com/docs/2007"); |
664 xml_writer.WriteElement("title", params_.title); | 666 xml_writer.WriteElement("title", params_.title); |
665 xml_writer.EndElement(); // Ends "entry" element. | 667 xml_writer.EndElement(); // Ends "entry" element. |
666 xml_writer.StopWriting(); | 668 xml_writer.StopWriting(); |
667 upload_content->assign(xml_writer.GetWrittenString()); | 669 upload_content->assign(xml_writer.GetWrittenString()); |
668 DVLOG(1) << "Upload data: " << *upload_content_type << ", [" | 670 DVLOG(1) << "Upload data: " << *upload_content_type << ", [" |
669 << *upload_content << "]"; | 671 << *upload_content << "]"; |
670 return true; | 672 return true; |
671 } | 673 } |
672 | 674 |
673 //============================ ResumeUploadOperation =========================== | 675 namespace { |
674 | 676 |
675 ResumeUploadOperation::ResumeUploadOperation( | 677 bool ProcessURLFetchResultsImpl( |
676 OperationRegistry* registry, | 678 GDataErrorCode code, |
677 net::URLRequestContextGetter* url_request_context_getter, | 679 const URLFetcher* source, |
| 680 const FilePath& drive_file_path, |
678 const ResumeUploadCallback& callback, | 681 const ResumeUploadCallback& callback, |
679 const ResumeUploadParams& params) | 682 const ParseJsonCallback& json_callback) { |
680 : UrlFetchOperationBase(registry, | |
681 url_request_context_getter, | |
682 OPERATION_UPLOAD, | |
683 params.drive_file_path), | |
684 callback_(callback), | |
685 params_(params), | |
686 last_chunk_completed_(false), | |
687 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
688 DCHECK(!callback_.is_null()); | |
689 } | |
690 | |
691 ResumeUploadOperation::~ResumeUploadOperation() {} | |
692 | |
693 GURL ResumeUploadOperation::GetURL() const { | |
694 // This is very tricky to get json from this operation. To do that, &alt=json | |
695 // has to be appended not here but in InitiateUploadOperation::GetURL(). | |
696 return params_.upload_location; | |
697 } | |
698 | |
699 void ResumeUploadOperation::ProcessURLFetchResults(const URLFetcher* source) { | |
700 GDataErrorCode code = GetErrorCode(source); | |
701 net::HttpResponseHeaders* hdrs = source->GetResponseHeaders(); | 683 net::HttpResponseHeaders* hdrs = source->GetResponseHeaders(); |
702 | 684 |
703 if (code == HTTP_RESUME_INCOMPLETE) { | 685 if (code == HTTP_RESUME_INCOMPLETE) { |
704 // Retrieve value of the first "Range" header. | 686 // Retrieve value of the first "Range" header. |
705 int64 start_position_received = -1; | 687 int64 start_position_received = -1; |
706 int64 end_position_received = -1; | 688 int64 end_position_received = -1; |
707 std::string range_received; | 689 std::string range_received; |
708 hdrs->EnumerateHeader(NULL, kUploadResponseRange, &range_received); | 690 hdrs->EnumerateHeader(NULL, kUploadResponseRange, &range_received); |
709 if (!range_received.empty()) { // Parse the range header. | 691 if (!range_received.empty()) { // Parse the range header. |
710 std::vector<net::HttpByteRange> ranges; | 692 std::vector<net::HttpByteRange> ranges; |
711 if (net::HttpUtil::ParseRangeHeader(range_received, &ranges) && | 693 if (net::HttpUtil::ParseRangeHeader(range_received, &ranges) && |
712 !ranges.empty() ) { | 694 !ranges.empty() ) { |
713 // We only care about the first start-end pair in the range. | 695 // We only care about the first start-end pair in the range. |
714 // | 696 // |
715 // Range header represents the range inclusively, while we are treating | 697 // Range header represents the range inclusively, while we are treating |
716 // ranges exclusively (i.e., end_position_received should be one passed | 698 // ranges exclusively (i.e., end_position_received should be one passed |
717 // the last valid index). So "+ 1" is added. | 699 // the last valid index). So "+ 1" is added. |
718 start_position_received = ranges[0].first_byte_position(); | 700 start_position_received = ranges[0].first_byte_position(); |
719 end_position_received = ranges[0].last_byte_position() + 1; | 701 end_position_received = ranges[0].last_byte_position() + 1; |
720 } | 702 } |
721 } | 703 } |
722 DVLOG(1) << "Got response for [" << params_.drive_file_path.value() | 704 DVLOG(1) << "Got response for [" << drive_file_path.value() |
723 << "]: code=" << code | 705 << "]: code=" << code |
724 << ", range_hdr=[" << range_received | 706 << ", range_hdr=[" << range_received |
725 << "], range_parsed=" << start_position_received | 707 << "], range_parsed=" << start_position_received |
726 << "," << end_position_received; | 708 << "," << end_position_received; |
727 | 709 |
728 callback_.Run(ResumeUploadResponse(code, | 710 callback.Run(ResumeUploadResponse(code, |
729 start_position_received, | 711 start_position_received, |
730 end_position_received), | 712 end_position_received), |
731 scoped_ptr<ResourceEntry>()); | 713 scoped_ptr<ResourceEntry>()); |
| 714 return true; |
| 715 } |
732 | 716 |
733 OnProcessURLFetchResultsComplete(true); | 717 // There might be explanation of unexpected error code in response. |
734 } else { | 718 std::string response_content; |
735 // There might be explanation of unexpected error code in response. | 719 source->GetResponseAsString(&response_content); |
736 std::string response_content; | 720 DVLOG(1) << "Got response for [" << drive_file_path.value() |
737 source->GetResponseAsString(&response_content); | 721 << "]: code=" << code |
738 DVLOG(1) << "Got response for [" << params_.drive_file_path.value() | 722 << ", content=[\n" << response_content << "\n]"; |
739 << "]: code=" << code | |
740 << ", content=[\n" << response_content << "\n]"; | |
741 | 723 |
742 ParseJson(response_content, | 724 ParseJson(response_content, json_callback); |
743 base::Bind(&ResumeUploadOperation::OnDataParsed, | 725 return false; |
744 weak_ptr_factory_.GetWeakPtr(), | |
745 code)); | |
746 } | |
747 } | 726 } |
748 | 727 |
749 void ResumeUploadOperation::OnDataParsed(GDataErrorCode code, | 728 bool OnDataParsedImpl( |
750 scoped_ptr<base::Value> value) { | 729 UploadMode upload_mode, |
| 730 const ResumeUploadCallback& callback, |
| 731 GDataErrorCode code, |
| 732 scoped_ptr<base::Value> value) { |
751 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 733 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
752 | 734 |
753 // For a new file, HTTP_CREATED is returned. | |
754 // For an existing file, HTTP_SUCCESS is returned. | |
755 if ((params_.upload_mode == UPLOAD_NEW_FILE && code == HTTP_CREATED) || | |
756 (params_.upload_mode == UPLOAD_EXISTING_FILE && code == HTTP_SUCCESS)) { | |
757 last_chunk_completed_ = true; | |
758 } | |
759 | |
760 scoped_ptr<ResourceEntry> entry; | 735 scoped_ptr<ResourceEntry> entry; |
761 if (value.get()) | 736 if (value.get()) |
762 entry = ResourceEntry::ExtractAndParse(*(value.get())); | 737 entry = ResourceEntry::ExtractAndParse(*(value.get())); |
763 | 738 |
764 if (!entry.get()) | 739 if (!entry.get()) |
765 LOG(WARNING) << "Invalid entry received on upload."; | 740 LOG(WARNING) << "Invalid entry received on upload."; |
766 | 741 |
767 callback_.Run(ResumeUploadResponse(code, -1, -1), entry.Pass()); | 742 callback.Run(ResumeUploadResponse(code, -1, -1), entry.Pass()); |
| 743 |
| 744 // For a new file, HTTP_CREATED is returned. |
| 745 // For an existing file, HTTP_SUCCESS is returned. |
| 746 return (upload_mode == UPLOAD_NEW_FILE && code == HTTP_CREATED) || |
| 747 (upload_mode == UPLOAD_EXISTING_FILE && code == HTTP_SUCCESS); |
| 748 } |
| 749 |
| 750 } // namespace |
| 751 |
| 752 //============================ ResumeUploadOperation =========================== |
| 753 |
| 754 ResumeUploadOperation::ResumeUploadOperation( |
| 755 OperationRegistry* registry, |
| 756 net::URLRequestContextGetter* url_request_context_getter, |
| 757 const ResumeUploadCallback& callback, |
| 758 const ResumeUploadParams& params) |
| 759 : UrlFetchOperationBase(registry, |
| 760 url_request_context_getter, |
| 761 OPERATION_UPLOAD, |
| 762 params.drive_file_path), |
| 763 callback_(callback), |
| 764 params_(params), |
| 765 last_chunk_completed_(false), |
| 766 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 767 DCHECK(!callback_.is_null()); |
| 768 } |
| 769 |
| 770 ResumeUploadOperation::~ResumeUploadOperation() {} |
| 771 |
| 772 GURL ResumeUploadOperation::GetURL() const { |
| 773 // This is very tricky to get json from this operation. To do that, &alt=json |
| 774 // has to be appended not here but in InitiateUploadOperation::GetURL(). |
| 775 return params_.upload_location; |
| 776 } |
| 777 |
| 778 void ResumeUploadOperation::ProcessURLFetchResults(const URLFetcher* source) { |
| 779 GDataErrorCode code = GetErrorCode(source); |
| 780 if (ProcessURLFetchResultsImpl( |
| 781 code, source, params_.drive_file_path, callback_, |
| 782 base::Bind(&ResumeUploadOperation::OnDataParsed, |
| 783 weak_ptr_factory_.GetWeakPtr(), |
| 784 code))) { |
| 785 OnProcessURLFetchResultsComplete(true); |
| 786 } |
| 787 } |
| 788 |
| 789 void ResumeUploadOperation::OnDataParsed(GDataErrorCode code, |
| 790 scoped_ptr<base::Value> value) { |
| 791 last_chunk_completed_ = OnDataParsedImpl( |
| 792 params_.upload_mode, callback_, code, value.Pass()); |
768 OnProcessURLFetchResultsComplete(last_chunk_completed_); | 793 OnProcessURLFetchResultsComplete(last_chunk_completed_); |
769 } | 794 } |
770 | 795 |
771 void ResumeUploadOperation::NotifyStartToOperationRegistry() { | 796 void ResumeUploadOperation::NotifyStartToOperationRegistry() { |
772 NotifyResume(); | 797 NotifyResume(); |
773 } | 798 } |
774 | 799 |
775 void ResumeUploadOperation::NotifySuccessToOperationRegistry() { | 800 void ResumeUploadOperation::NotifySuccessToOperationRegistry() { |
776 if (last_chunk_completed_) | 801 if (last_chunk_completed_) |
777 NotifyFinish(OPERATION_COMPLETED); | 802 NotifyFinish(OPERATION_COMPLETED); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 base::Int64ToString(params_.start_position) + "-" + | 837 base::Int64ToString(params_.start_position) + "-" + |
813 base::Int64ToString(params_.end_position - 1) + "/" + | 838 base::Int64ToString(params_.end_position - 1) + "/" + |
814 (params_.content_length == -1 ? "*" : | 839 (params_.content_length == -1 ? "*" : |
815 base::Int64ToString(params_.content_length))); | 840 base::Int64ToString(params_.content_length))); |
816 return headers; | 841 return headers; |
817 } | 842 } |
818 | 843 |
819 bool ResumeUploadOperation::GetContentData(std::string* upload_content_type, | 844 bool ResumeUploadOperation::GetContentData(std::string* upload_content_type, |
820 std::string* upload_content) { | 845 std::string* upload_content) { |
821 *upload_content_type = params_.content_type; | 846 *upload_content_type = params_.content_type; |
822 *upload_content = std::string(params_.buf->data(), | 847 *upload_content = std::string(params_.buf->data() + params_.buffer_offset, |
823 params_.end_position - params_.start_position); | 848 params_.end_position - params_.start_position); |
824 return true; | 849 return true; |
825 } | 850 } |
826 | 851 |
827 void ResumeUploadOperation::OnURLFetchUploadProgress( | 852 void ResumeUploadOperation::OnURLFetchUploadProgress( |
828 const URLFetcher* source, int64 current, int64 total) { | 853 const URLFetcher* source, int64 current, int64 total) { |
829 // Adjust the progress values according to the range currently uploaded. | 854 // Adjust the progress values according to the range currently uploaded. |
830 NotifyProgress(params_.start_position + current, params_.content_length); | 855 NotifyProgress(params_.start_position + current, params_.content_length); |
831 } | 856 } |
832 | 857 |
| 858 //============================ GetUploadStateOperation ========================= |
| 859 |
| 860 GetUploadStateOperation::GetUploadStateOperation( |
| 861 OperationRegistry* registry, |
| 862 net::URLRequestContextGetter* url_request_context_getter, |
| 863 const ResumeUploadCallback& callback, |
| 864 const UploadMode upload_mode, |
| 865 const FilePath& drive_file_path, |
| 866 const GURL& upload_url, |
| 867 int64 content_length) |
| 868 : UrlFetchOperationBase(registry, url_request_context_getter), |
| 869 callback_(callback), |
| 870 upload_mode_(upload_mode), |
| 871 drive_file_path_(drive_file_path), |
| 872 upload_url_(upload_url), |
| 873 content_length_(content_length), |
| 874 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 875 } |
| 876 |
| 877 GetUploadStateOperation::~GetUploadStateOperation() { |
| 878 } |
| 879 |
| 880 GURL GetUploadStateOperation::GetURL() const { |
| 881 return upload_url_; |
| 882 } |
| 883 |
| 884 net::URLFetcher::RequestType GetUploadStateOperation::GetRequestType() const { |
| 885 return net::URLFetcher::PUT_WITHOUT_BODY; |
| 886 } |
| 887 |
| 888 void GetUploadStateOperation::ProcessURLFetchResults( |
| 889 const net::URLFetcher* source) { |
| 890 GDataErrorCode code = GetErrorCode(source); |
| 891 if (ProcessURLFetchResultsImpl( |
| 892 code, source, drive_file_path_, callback_, |
| 893 base::Bind(&GetUploadStateOperation::OnDataParsed, |
| 894 weak_ptr_factory_.GetWeakPtr(), |
| 895 code))) { |
| 896 OnProcessURLFetchResultsComplete(true); |
| 897 } |
| 898 } |
| 899 |
| 900 void GetUploadStateOperation::RunCallbackOnPrematureFailure( |
| 901 GDataErrorCode code) { |
| 902 callback_.Run(ResumeUploadResponse(code, 0, 0), scoped_ptr<ResourceEntry>()); |
| 903 } |
| 904 |
| 905 std::vector<std::string> |
| 906 GetUploadStateOperation::GetExtraRequestHeaders() const { |
| 907 // The header looks like |
| 908 // Content-Range: bytes */<content_length> |
| 909 // for example: |
| 910 // Content-Range: bytes */13851821 |
| 911 // Use * for unknown/streaming content length. |
| 912 // The header takes inclusive range, so we adjust by "end_position - 1". |
| 913 DCHECK_GE(content_length_, -1); |
| 914 |
| 915 std::vector<std::string> headers; |
| 916 headers.push_back( |
| 917 std::string(kUploadContentRange) + "*/" + |
| 918 (content_length_ == -1 ? "*" : base::Int64ToString(content_length_))); |
| 919 return headers; |
| 920 } |
| 921 |
| 922 void GetUploadStateOperation::OnDataParsed( |
| 923 GDataErrorCode code, scoped_ptr<base::Value> value) { |
| 924 OnProcessURLFetchResultsComplete( |
| 925 OnDataParsedImpl( |
| 926 upload_mode_, callback_, code, value.Pass())); |
| 927 } |
| 928 |
833 } // namespace google_apis | 929 } // namespace google_apis |
OLD | NEW |