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

Side by Side Diff: chrome/browser/drive/fake_drive_service.cc

Issue 17140009: Support contents upload on FakeDriveService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: split out indentation fix Created 7 years, 6 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 "chrome/browser/drive/fake_drive_service.h" 5 #include "chrome/browser/drive/fake_drive_service.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_util.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/md5.h"
10 #include "base/message_loop.h" 12 #include "base/message_loop.h"
11 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
13 #include "base/strings/string_tokenizer.h" 15 #include "base/strings/string_tokenizer.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/google_apis/drive_api_parser.h" 19 #include "chrome/browser/google_apis/drive_api_parser.h"
18 #include "chrome/browser/google_apis/gdata_wapi_parser.h" 20 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
19 #include "chrome/browser/google_apis/test_util.h" 21 #include "chrome/browser/google_apis/test_util.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // TODO(peria): Deal with other attributes than title. 91 // TODO(peria): Deal with other attributes than title.
90 if (!key.empty() && key != "title") 92 if (!key.empty() && key != "title")
91 return false; 93 return false;
92 // Search query in the title. 94 // Search query in the title.
93 if (entry.title().find(value) == std::string::npos) 95 if (entry.title().find(value) == std::string::npos)
94 return false; 96 return false;
95 } 97 }
96 return true; 98 return true;
97 } 99 }
98 100
99 // Gets the upload URL from the given entry. Returns an empty URL if not
100 // found.
101 GURL GetUploadUrl(const base::DictionaryValue& entry) {
102 std::string upload_url;
103 const base::ListValue* links = NULL;
104 if (entry.GetList("link", &links) && links) {
105 for (size_t link_index = 0;
106 link_index < links->GetSize();
107 ++link_index) {
108 const base::DictionaryValue* link = NULL;
109 std::string rel;
110 if (links->GetDictionary(link_index, &link) &&
111 link && link->GetString("rel", &rel) &&
112 rel == kUploadUrlRel &&
113 link->GetString("href", &upload_url)) {
114 break;
115 }
116 }
117 }
118 return GURL(upload_url);
119 }
120
121 // Returns |url| without query parameter. 101 // Returns |url| without query parameter.
122 GURL RemoveQueryParameter(const GURL& url) { 102 GURL RemoveQueryParameter(const GURL& url) {
123 GURL::Replacements replacements; 103 GURL::Replacements replacements;
124 replacements.ClearQuery(); 104 replacements.ClearQuery();
125 return url.ReplaceComponents(replacements); 105 return url.ReplaceComponents(replacements);
126 } 106 }
127 107
128 } // namespace 108 } // namespace
129 109
110 struct FakeDriveService::UploadSession {
111 std::string content_type;
112 int64 content_length;
113 std::string parent_resource_id;
114 std::string resource_id;
115 std::string etag;
116 std::string title;
117
118 int64 uploaded_size;
119
120 UploadSession()
121 : content_length(0),
122 uploaded_size(0) {}
123
124 UploadSession(
125 std::string content_type,
126 int64 content_length,
127 std::string parent_resource_id,
128 std::string resource_id,
129 std::string etag,
130 std::string title)
131 : content_type(content_type),
132 content_length(content_length),
133 parent_resource_id(parent_resource_id),
134 resource_id(resource_id),
135 etag(etag),
136 title(title),
137 uploaded_size(0) {
138 }
139 };
140
130 FakeDriveService::FakeDriveService() 141 FakeDriveService::FakeDriveService()
131 : largest_changestamp_(0), 142 : largest_changestamp_(0),
132 published_date_seq_(0), 143 published_date_seq_(0),
144 next_upload_sequence_number_(0),
133 default_max_results_(0), 145 default_max_results_(0),
134 resource_id_count_(0), 146 resource_id_count_(0),
135 resource_list_load_count_(0), 147 resource_list_load_count_(0),
136 change_list_load_count_(0), 148 change_list_load_count_(0),
137 directory_load_count_(0), 149 directory_load_count_(0),
138 about_resource_load_count_(0), 150 about_resource_load_count_(0),
139 offline_(false) { 151 offline_(false),
152 weak_factory_(this) {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141 } 154 }
142 155
143 FakeDriveService::~FakeDriveService() { 156 FakeDriveService::~FakeDriveService() {
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
145 } 158 }
146 159
147 bool FakeDriveService::LoadResourceListForWapi( 160 bool FakeDriveService::LoadResourceListForWapi(
148 const std::string& relative_path) { 161 const std::string& relative_path) {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 if (!entry) { 554 if (!entry) {
542 base::MessageLoopProxy::current()->PostTask( 555 base::MessageLoopProxy::current()->PostTask(
543 FROM_HERE, 556 FROM_HERE,
544 base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath())); 557 base::Bind(download_action_callback, HTTP_NOT_FOUND, base::FilePath()));
545 return CancelCallback(); 558 return CancelCallback();
546 } 559 }
547 560
548 // Write "x"s of the file size specified in the entry. 561 // Write "x"s of the file size specified in the entry.
549 std::string file_size_string; 562 std::string file_size_string;
550 entry->GetString("docs$size.$t", &file_size_string); 563 entry->GetString("docs$size.$t", &file_size_string);
551 // TODO(satorux): To be correct, we should update docs$md5Checksum.$t here.
552 int64 file_size = 0; 564 int64 file_size = 0;
553 if (base::StringToInt64(file_size_string, &file_size)) { 565 if (base::StringToInt64(file_size_string, &file_size)) {
554 base::BinaryValue* content_binary_data; 566 base::BinaryValue* content_binary_data;
555 std::string content_data; 567 std::string content_data;
556 if (entry->GetBinary("test$data", &content_binary_data)) { 568 if (entry->GetBinary("test$data", &content_binary_data)) {
557 content_data = std::string(content_binary_data->GetBuffer(), 569 content_data = std::string(content_binary_data->GetBuffer(),
558 content_binary_data->GetSize()); 570 content_binary_data->GetSize());
559 } 571 }
560 DCHECK_EQ(static_cast<size_t>(file_size), content_data.size()); 572 DCHECK_EQ(static_cast<size_t>(file_size), content_data.size());
561 573
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 897 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
886 DCHECK(!callback.is_null()); 898 DCHECK(!callback.is_null());
887 899
888 if (offline_) { 900 if (offline_) {
889 base::MessageLoop::current()->PostTask( 901 base::MessageLoop::current()->PostTask(
890 FROM_HERE, 902 FROM_HERE,
891 base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 903 base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
892 return CancelCallback(); 904 return CancelCallback();
893 } 905 }
894 906
895 // Content length should be zero, as we'll create an empty file first. The 907 if (parent_resource_id != GetRootResourceId() &&
896 // content will be added in ResumeUpload(). 908 !FindEntryByResourceId(parent_resource_id)) {
897 const base::DictionaryValue* new_entry = AddNewEntry(content_type,
898 "", // content_data
899 parent_resource_id,
900 title,
901 false, // shared_with_me
902 "file");
903 if (!new_entry) {
904 base::MessageLoop::current()->PostTask( 909 base::MessageLoop::current()->PostTask(
905 FROM_HERE, 910 FROM_HERE,
906 base::Bind(callback, HTTP_NOT_FOUND, GURL())); 911 base::Bind(callback, HTTP_NOT_FOUND, GURL()));
907 return CancelCallback(); 912 return CancelCallback();
908 } 913 }
909 const GURL upload_url = GetUploadUrl(*new_entry); 914
910 DCHECK(upload_url.is_valid()); 915 GURL session_url = net::AppendQueryParameter(
916 GetNewUploadSessionUrl(), "mode", "newfile");
917 upload_session_[session_url] =
918 UploadSession(content_type, content_length,
919 parent_resource_id,
920 "", // resource_id
921 "", // etag
922 title);
911 923
912 base::MessageLoop::current()->PostTask( 924 base::MessageLoop::current()->PostTask(
913 FROM_HERE, 925 FROM_HERE,
914 base::Bind(callback, HTTP_SUCCESS, 926 base::Bind(callback, HTTP_SUCCESS, session_url));
915 net::AppendQueryParameter(upload_url, "mode", "newfile")));
916 return CancelCallback(); 927 return CancelCallback();
917 } 928 }
918 929
919 CancelCallback FakeDriveService::InitiateUploadExistingFile( 930 CancelCallback FakeDriveService::InitiateUploadExistingFile(
920 const base::FilePath& drive_file_path, 931 const base::FilePath& drive_file_path,
921 const std::string& content_type, 932 const std::string& content_type,
922 int64 content_length, 933 int64 content_length,
923 const std::string& resource_id, 934 const std::string& resource_id,
924 const std::string& etag, 935 const std::string& etag,
925 const InitiateUploadCallback& callback) { 936 const InitiateUploadCallback& callback) {
(...skipping 16 matching lines...) Expand all
942 } 953 }
943 954
944 std::string entry_etag; 955 std::string entry_etag;
945 entry->GetString("gd$etag", &entry_etag); 956 entry->GetString("gd$etag", &entry_etag);
946 if (!etag.empty() && etag != entry_etag) { 957 if (!etag.empty() && etag != entry_etag) {
947 base::MessageLoop::current()->PostTask( 958 base::MessageLoop::current()->PostTask(
948 FROM_HERE, 959 FROM_HERE,
949 base::Bind(callback, HTTP_PRECONDITION, GURL())); 960 base::Bind(callback, HTTP_PRECONDITION, GURL()));
950 return CancelCallback(); 961 return CancelCallback();
951 } 962 }
952 entry->SetString("docs$size.$t", "0");
953 963
954 const GURL upload_url = GetUploadUrl(*entry); 964 GURL session_url = net::AppendQueryParameter(
955 DCHECK(upload_url.is_valid()); 965 GetNewUploadSessionUrl(), "mode", "existing");
966 upload_session_[session_url] =
967 UploadSession(content_type, content_length,
968 "", // parent_resource_id
969 resource_id,
970 entry_etag,
971 "" /* title */);
956 972
957 base::MessageLoop::current()->PostTask( 973 base::MessageLoop::current()->PostTask(
958 FROM_HERE, 974 FROM_HERE,
959 base::Bind(callback, HTTP_SUCCESS, 975 base::Bind(callback, HTTP_SUCCESS, session_url));
960 net::AppendQueryParameter(upload_url, "mode", "existing")));
961 return CancelCallback(); 976 return CancelCallback();
962 } 977 }
963 978
964 CancelCallback FakeDriveService::GetUploadStatus( 979 CancelCallback FakeDriveService::GetUploadStatus(
965 const base::FilePath& drive_file_path, 980 const base::FilePath& drive_file_path,
966 const GURL& upload_url, 981 const GURL& upload_url,
967 int64 content_length, 982 int64 content_length,
968 const UploadRangeCallback& callback) { 983 const UploadRangeCallback& callback) {
969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
970 DCHECK(!callback.is_null()); 985 DCHECK(!callback.is_null());
986
987 if (!ContainsKey(upload_session_, upload_url)) {
hashimoto 2013/06/21 04:16:21 nit: Hmn, I didn't know that we had this function
tzik 2013/06/21 05:06:52 Changed this to count(). They are exactly same in
988 base::MessageLoop::current()->PostTask(
989 FROM_HERE,
990 base::Bind(callback, UploadRangeResponse(HTTP_NOT_FOUND, 0, 0),
991 base::Passed(scoped_ptr<ResourceEntry>())));
992 return CancelCallback();
993 }
994
995 const UploadSession& session = upload_session_[upload_url];
996 if (session.uploaded_size == session.content_length) {
997 if (session.resource_id.empty()) {
998 base::MessageLoop::current()->PostTask(
999 FROM_HERE,
1000 base::Bind(callback, UploadRangeResponse(HTTP_CREATED, 0, 0),
1001 base::Passed(scoped_ptr<ResourceEntry>())));
hashimoto 2013/06/21 04:16:21 Why are you returning null pointers even in succes
tzik 2013/06/21 05:06:52 IIUC, the server doesn't return resource entry for
tzik 2013/06/21 05:35:04 Done. I move this part of change to another CL.
1002 return CancelCallback();
1003 }
1004
1005 base::MessageLoop::current()->PostTask(
1006 FROM_HERE,
1007 base::Bind(callback, UploadRangeResponse(HTTP_SUCCESS, 0, 0),
1008 base::Passed(scoped_ptr<ResourceEntry>())));
1009 return CancelCallback();
1010 }
1011
1012 base::MessageLoop::current()->PostTask(
1013 FROM_HERE,
1014 base::Bind(callback,
1015 UploadRangeResponse(HTTP_RESUME_INCOMPLETE,
1016 0, session.uploaded_size),
1017 base::Passed(scoped_ptr<ResourceEntry>())));
971 return CancelCallback(); 1018 return CancelCallback();
972 } 1019 }
973 1020
974 CancelCallback FakeDriveService::ResumeUpload( 1021 CancelCallback FakeDriveService::ResumeUpload(
975 const base::FilePath& drive_file_path, 1022 const base::FilePath& drive_file_path,
976 const GURL& upload_url, 1023 const GURL& upload_url,
977 int64 start_position, 1024 int64 start_position,
978 int64 end_position, 1025 int64 end_position,
979 int64 content_length, 1026 int64 content_length,
980 const std::string& content_type, 1027 const std::string& content_type,
981 const base::FilePath& local_file_path, 1028 const base::FilePath& local_file_path,
982 const UploadRangeCallback& callback, 1029 const UploadRangeCallback& callback,
983 const ProgressCallback& progress_callback) { 1030 const ProgressCallback& progress_callback) {
984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1031 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
985 DCHECK(!callback.is_null()); 1032 DCHECK(!callback.is_null());
986 1033
987 scoped_ptr<ResourceEntry> result_entry;
988
989 if (offline_) { 1034 if (offline_) {
990 base::MessageLoop::current()->PostTask( 1035 base::MessageLoop::current()->PostTask(
991 FROM_HERE, 1036 FROM_HERE,
992 base::Bind(callback, 1037 base::Bind(callback,
993 UploadRangeResponse(GDATA_NO_CONNECTION, 1038 UploadRangeResponse(GDATA_NO_CONNECTION,
994 start_position, 1039 start_position,
995 end_position), 1040 end_position),
996 base::Passed(&result_entry))); 1041 base::Passed(scoped_ptr<ResourceEntry>())));
997 return CancelCallback(); 1042 return CancelCallback();
998 } 1043 }
999 1044
1000 DictionaryValue* entry = NULL; 1045 if (!ContainsKey(upload_session_, upload_url)) {
1001 entry = FindEntryByUploadUrl(RemoveQueryParameter(upload_url));
1002 if (!entry) {
1003 base::MessageLoop::current()->PostTask( 1046 base::MessageLoop::current()->PostTask(
1004 FROM_HERE, 1047 FROM_HERE,
1005 base::Bind(callback, 1048 base::Bind(callback,
1006 UploadRangeResponse(HTTP_NOT_FOUND, 1049 UploadRangeResponse(HTTP_NOT_FOUND,
1007 start_position, 1050 start_position,
1008 end_position), 1051 end_position),
1009 base::Passed(&result_entry))); 1052 base::Passed(scoped_ptr<ResourceEntry>())));
1010 return CancelCallback(); 1053 return CancelCallback();
1011 } 1054 }
1012 1055
1056 UploadSession* session = &upload_session_[upload_url];
1057
1013 // Chunks are required to be sent in such a ways that they fill from the start 1058 // Chunks are required to be sent in such a ways that they fill from the start
1014 // of the not-yet-uploaded part with no gaps nor overlaps. 1059 // of the not-yet-uploaded part with no gaps nor overlaps.
1015 std::string current_size_string; 1060 int64 current_size = session->uploaded_size;
hashimoto 2013/06/21 04:16:21 nit: Do we need this variable?
tzik 2013/06/21 05:06:52 Done.
1016 int64 current_size; 1061 if (current_size != start_position) {
1017 if (!entry->GetString("docs$size.$t", &current_size_string) ||
1018 !base::StringToInt64(current_size_string, &current_size) ||
1019 current_size != start_position) {
1020 base::MessageLoop::current()->PostTask( 1062 base::MessageLoop::current()->PostTask(
1021 FROM_HERE, 1063 FROM_HERE,
1022 base::Bind(callback, 1064 base::Bind(callback,
1023 UploadRangeResponse(HTTP_BAD_REQUEST, 1065 UploadRangeResponse(HTTP_BAD_REQUEST,
1024 start_position, 1066 start_position,
1025 end_position), 1067 end_position),
1026 base::Passed(&result_entry))); 1068 base::Passed(scoped_ptr<ResourceEntry>())));
1027 return CancelCallback(); 1069 return CancelCallback();
1028 } 1070 }
1029 1071
1030 entry->SetString("docs$size.$t", base::Int64ToString(end_position));
1031
1032 if (!progress_callback.is_null()) { 1072 if (!progress_callback.is_null()) {
1033 // In the real GDataWapi/Drive DriveService, progress is reported in 1073 // In the real GDataWapi/Drive DriveService, progress is reported in
1034 // nondeterministic timing. In this fake implementation, we choose to call 1074 // nondeterministic timing. In this fake implementation, we choose to call
1035 // it twice per one ResumeUpload. This is for making sure that client code 1075 // it twice per one ResumeUpload. This is for making sure that client code
1036 // works fine even if the callback is invoked more than once; it is the 1076 // works fine even if the callback is invoked more than once; it is the
1037 // crucial difference of the progress callback from others. 1077 // crucial difference of the progress callback from others.
1038 // Note that progress is notified in the relative offset in each chunk. 1078 // Note that progress is notified in the relative offset in each chunk.
1039 const int64 chunk_size = end_position - start_position; 1079 const int64 chunk_size = end_position - start_position;
1040 base::MessageLoop::current()->PostTask( 1080 base::MessageLoop::current()->PostTask(
1041 FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size)); 1081 FROM_HERE, base::Bind(progress_callback, chunk_size / 2, chunk_size));
1042 base::MessageLoop::current()->PostTask( 1082 base::MessageLoop::current()->PostTask(
1043 FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size)); 1083 FROM_HERE, base::Bind(progress_callback, chunk_size, chunk_size));
1044 } 1084 }
1045 1085
1046 if (content_length != end_position) { 1086 if (content_length != end_position) {
1087 session->uploaded_size = end_position;
1047 base::MessageLoop::current()->PostTask( 1088 base::MessageLoop::current()->PostTask(
1048 FROM_HERE, 1089 FROM_HERE,
1049 base::Bind(callback, 1090 base::Bind(callback,
1050 UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 1091 UploadRangeResponse(HTTP_RESUME_INCOMPLETE,
1051 start_position, 1092 start_position,
1052 end_position), 1093 end_position),
1053 base::Passed(&result_entry))); 1094 base::Passed(scoped_ptr<ResourceEntry>())));
1054 return CancelCallback(); 1095 return CancelCallback();
1055 } 1096 }
1056 1097
1098 std::string content_data;
1099 if (!file_util::ReadFileToString(local_file_path, &content_data)) {
1100 base::MessageLoop::current()->PostTask(
1101 FROM_HERE,
1102 base::Bind(callback,
1103 UploadRangeResponse(GDATA_FILE_ERROR,
1104 start_position,
1105 end_position),
1106 base::Passed(scoped_ptr<ResourceEntry>())));
1107 return CancelCallback();
1108 }
1109 session->uploaded_size = end_position;
1110
1111 if (session->resource_id.empty()) {
hashimoto 2013/06/21 04:16:21 resource_id.empty() is true iff the upload is for
tzik 2013/06/21 05:06:52 Done.
1112 const DictionaryValue* new_entry = AddNewEntry(
1113 session->content_type,
1114 content_data,
1115 session->parent_resource_id,
1116 session->title,
1117 false, // shared_with_me
1118 "file");
1119 if (!new_entry) {
1120 base::MessageLoop::current()->PostTask(
1121 FROM_HERE,
1122 base::Bind(callback,
1123 UploadRangeResponse(HTTP_NOT_FOUND,
1124 start_position,
1125 end_position),
1126 base::Passed(scoped_ptr<ResourceEntry>())));
1127 return CancelCallback();
1128 }
1129
1130 base::MessageLoop::current()->PostTask(
1131 FROM_HERE,
1132 base::Bind(callback,
1133 UploadRangeResponse(HTTP_CREATED,
1134 start_position,
1135 end_position),
1136 base::Passed(ResourceEntry::CreateFrom(*new_entry))));
1137 return CancelCallback();
1138 }
1139
1140 DictionaryValue* entry = FindEntryByResourceId(session->resource_id);
1141 if (!entry) {
1142 base::MessageLoop::current()->PostTask(
1143 FROM_HERE,
1144 base::Bind(callback,
1145 UploadRangeResponse(HTTP_NOT_FOUND,
1146 start_position,
1147 end_position),
1148 base::Passed(scoped_ptr<ResourceEntry>())));
1149 return CancelCallback();
1150 }
1151
1152 std::string entry_etag;
1153 entry->GetString("gd$etag", &entry_etag);
1154 if (entry_etag.empty() || session->etag != entry_etag) {
1155 base::MessageLoop::current()->PostTask(
1156 FROM_HERE,
1157 base::Bind(callback,
1158 UploadRangeResponse(HTTP_PRECONDITION,
1159 start_position,
1160 end_position),
1161 base::Passed(scoped_ptr<ResourceEntry>())));
1162 return CancelCallback();
1163 }
1164
1165 entry->SetString("docs$md5Checksum.$t", base::MD5String(content_data));
1166 entry->Set("test$data",
1167 base::BinaryValue::CreateWithCopiedBuffer(
1168 content_data.data(), content_data.size()));
1169 entry->SetString("docs$size.$t", base::Int64ToString(end_position));
1057 AddNewChangestamp(entry); 1170 AddNewChangestamp(entry);
1058 result_entry = ResourceEntry::CreateFrom(*entry).Pass();
1059
1060 std::string upload_mode;
1061 bool upload_mode_found =
1062 net::GetValueForKeyInQuery(upload_url, "mode", &upload_mode);
1063 DCHECK(upload_mode_found &&
1064 (upload_mode == "newfile" || upload_mode == "existing"));
1065
1066 GDataErrorCode return_code =
1067 upload_mode == "newfile" ? HTTP_CREATED : HTTP_SUCCESS;
1068 1171
1069 base::MessageLoop::current()->PostTask( 1172 base::MessageLoop::current()->PostTask(
1070 FROM_HERE, 1173 FROM_HERE,
1071 base::Bind(callback, 1174 base::Bind(callback,
1072 UploadRangeResponse(return_code, 1175 UploadRangeResponse(HTTP_SUCCESS,
hashimoto 2013/06/21 04:16:21 Please return HTTP_CREATED for new files.
tzik 2013/06/21 05:06:52 Uploads for new file are handled around 1111, so t
hashimoto 2013/06/21 05:41:24 You're right, thanks.
1073 start_position, 1176 start_position,
1074 end_position), 1177 end_position),
1075 base::Passed(&result_entry))); 1178 base::Passed(ResourceEntry::CreateFrom(*entry))));
1076 return CancelCallback(); 1179 return CancelCallback();
1077 } 1180 }
1078 1181
1079 CancelCallback FakeDriveService::AuthorizeApp( 1182 CancelCallback FakeDriveService::AuthorizeApp(
1080 const std::string& resource_id, 1183 const std::string& resource_id,
1081 const std::string& app_id, 1184 const std::string& app_id,
1082 const AuthorizeAppCallback& callback) { 1185 const AuthorizeAppCallback& callback) {
1083 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1084 DCHECK(!callback.is_null()); 1187 DCHECK(!callback.is_null());
1085 return CancelCallback(); 1188 return CancelCallback();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 entry->GetString("content.src", &current_content_url) && 1310 entry->GetString("content.src", &current_content_url) &&
1208 content_url == GURL(current_content_url)) { 1311 content_url == GURL(current_content_url)) {
1209 return entry; 1312 return entry;
1210 } 1313 }
1211 } 1314 }
1212 } 1315 }
1213 1316
1214 return NULL; 1317 return NULL;
1215 } 1318 }
1216 1319
1217 base::DictionaryValue* FakeDriveService::FindEntryByUploadUrl(
1218 const GURL& upload_url) {
1219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1220
1221 base::ListValue* entries = NULL;
1222 // Go through entries and return the one that matches |upload_url|.
1223 if (resource_list_value_->GetList("entry", &entries)) {
1224 for (size_t i = 0; i < entries->GetSize(); ++i) {
1225 base::DictionaryValue* entry = NULL;
1226 base::ListValue* links = NULL;
1227 if (entries->GetDictionary(i, &entry) &&
1228 entry->GetList("link", &links) &&
1229 links) {
1230 for (size_t link_index = 0;
1231 link_index < links->GetSize();
1232 ++link_index) {
1233 base::DictionaryValue* link = NULL;
1234 std::string rel;
1235 std::string found_upload_url;
1236 if (links->GetDictionary(link_index, &link) &&
1237 link && link->GetString("rel", &rel) &&
1238 rel == kUploadUrlRel &&
1239 link->GetString("href", &found_upload_url) &&
1240 GURL(found_upload_url) == upload_url) {
1241 return entry;
1242 }
1243 }
1244 }
1245 }
1246 }
1247
1248 return NULL;
1249 }
1250
1251 std::string FakeDriveService::GetNewResourceId() { 1320 std::string FakeDriveService::GetNewResourceId() {
1252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1253 1322
1254 ++resource_id_count_; 1323 ++resource_id_count_;
1255 return base::StringPrintf("resource_id_%d", resource_id_count_); 1324 return base::StringPrintf("resource_id_%d", resource_id_count_);
1256 } 1325 }
1257 1326
1258 void FakeDriveService::AddNewChangestamp(base::DictionaryValue* entry) { 1327 void FakeDriveService::AddNewChangestamp(base::DictionaryValue* entry) {
hashimoto 2013/06/21 04:16:21 How about renaming this method to something like A
tzik 2013/06/21 05:06:52 Done.
1259 ++largest_changestamp_; 1328 ++largest_changestamp_;
1260 entry->SetString("docs$changestamp.value", 1329 entry->SetString("docs$changestamp.value",
1261 base::Int64ToString(largest_changestamp_)); 1330 base::Int64ToString(largest_changestamp_));
1331 entry->SetString("gd$etag",
1332 "etag_" + base::Int64ToString(largest_changestamp_));
1262 } 1333 }
1263 1334
1264 const base::DictionaryValue* FakeDriveService::AddNewEntry( 1335 const base::DictionaryValue* FakeDriveService::AddNewEntry(
1265 const std::string& content_type, 1336 const std::string& content_type,
1266 const std::string& content_data, 1337 const std::string& content_data,
1267 const std::string& parent_resource_id, 1338 const std::string& parent_resource_id,
1268 const std::string& title, 1339 const std::string& title,
1269 bool shared_with_me, 1340 bool shared_with_me,
1270 const std::string& entry_kind) { 1341 const std::string& entry_kind) {
1271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 11 matching lines...) Expand all
1283 new_entry->SetString("gd$resourceId.$t", resource_id); 1354 new_entry->SetString("gd$resourceId.$t", resource_id);
1284 new_entry->SetString("title.$t", title); 1355 new_entry->SetString("title.$t", title);
1285 new_entry->SetString("docs$filename", title); 1356 new_entry->SetString("docs$filename", title);
1286 // Set the contents, size and MD5 for a file. 1357 // Set the contents, size and MD5 for a file.
1287 if (entry_kind == "file") { 1358 if (entry_kind == "file") {
1288 new_entry->Set("test$data", 1359 new_entry->Set("test$data",
1289 base::BinaryValue::CreateWithCopiedBuffer( 1360 base::BinaryValue::CreateWithCopiedBuffer(
1290 content_data.c_str(), content_data.size())); 1361 content_data.c_str(), content_data.size()));
1291 new_entry->SetString("docs$size.$t", 1362 new_entry->SetString("docs$size.$t",
1292 base::Int64ToString(content_data.size())); 1363 base::Int64ToString(content_data.size()));
1293 // TODO(satorux): Set the correct MD5 here.
1294 new_entry->SetString("docs$md5Checksum.$t", 1364 new_entry->SetString("docs$md5Checksum.$t",
1295 "3b4385ebefec6e743574c76bbd0575de"); 1365 base::MD5String(content_data));
1296 } 1366 }
1297 1367
1298 // Add "category" which sets the resource type to |entry_kind|. 1368 // Add "category" which sets the resource type to |entry_kind|.
1299 base::ListValue* categories = new base::ListValue; 1369 base::ListValue* categories = new base::ListValue;
1300 base::DictionaryValue* category = new base::DictionaryValue; 1370 base::DictionaryValue* category = new base::DictionaryValue;
1301 category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); 1371 category->SetString("scheme", "http://schemas.google.com/g/2005#kind");
1302 category->SetString("term", "http://schemas.google.com/docs/2007#" + 1372 category->SetString("term", "http://schemas.google.com/docs/2007#" +
1303 entry_kind); 1373 entry_kind);
1304 categories->Append(category); 1374 categories->Append(category);
1305 new_entry->Set("category", categories); 1375 new_entry->Set("category", categories);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 1540
1471 if (load_counter) 1541 if (load_counter)
1472 *load_counter += 1; 1542 *load_counter += 1;
1473 base::MessageLoop::current()->PostTask( 1543 base::MessageLoop::current()->PostTask(
1474 FROM_HERE, 1544 FROM_HERE,
1475 base::Bind(callback, 1545 base::Bind(callback,
1476 HTTP_SUCCESS, 1546 HTTP_SUCCESS,
1477 base::Passed(&resource_list))); 1547 base::Passed(&resource_list)));
1478 } 1548 }
1479 1549
1550 GURL FakeDriveService::GetNewUploadSessionUrl() {
1551 return GURL("https://upload_session_url/" +
1552 base::Int64ToString(next_upload_sequence_number_++));
1553 }
1554
1480 } // namespace drive 1555 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698