• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "google_apis/drive/drive_api_requests.h"
6 
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/json/json_writer.h"
10 #include "base/location.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/task_runner_util.h"
13 #include "base/values.h"
14 #include "google_apis/drive/drive_api_parser.h"
15 #include "google_apis/drive/request_sender.h"
16 #include "google_apis/drive/request_util.h"
17 #include "google_apis/drive/time_util.h"
18 #include "net/base/url_util.h"
19 
20 namespace google_apis {
21 namespace {
22 
23 const char kContentTypeApplicationJson[] = "application/json";
24 const char kParentLinkKind[] = "drive#fileLink";
25 
26 // Parses the JSON value to a resource typed |T| and runs |callback| on the UI
27 // thread once parsing is done.
28 template<typename T>
ParseJsonAndRun(const base::Callback<void (GDataErrorCode,scoped_ptr<T>)> & callback,GDataErrorCode error,scoped_ptr<base::Value> value)29 void ParseJsonAndRun(
30     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
31     GDataErrorCode error,
32     scoped_ptr<base::Value> value) {
33   DCHECK(!callback.is_null());
34 
35   scoped_ptr<T> resource;
36   if (value) {
37     resource = T::CreateFrom(*value);
38     if (!resource) {
39       // Failed to parse the JSON value, although the JSON value is available,
40       // so let the callback know the parsing error.
41       error = GDATA_PARSE_ERROR;
42     }
43   }
44 
45   callback.Run(error, resource.Pass());
46 }
47 
48 // Thin adapter of T::CreateFrom.
49 template<typename T>
ParseJsonOnBlockingPool(scoped_ptr<base::Value> value)50 scoped_ptr<T> ParseJsonOnBlockingPool(scoped_ptr<base::Value> value) {
51   return T::CreateFrom(*value);
52 }
53 
54 // Runs |callback| with given |error| and |value|. If |value| is null,
55 // overwrites |error| to GDATA_PARSE_ERROR.
56 template<typename T>
ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask(const base::Callback<void (GDataErrorCode,scoped_ptr<T>)> & callback,GDataErrorCode error,scoped_ptr<T> value)57 void ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask(
58     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
59     GDataErrorCode error, scoped_ptr<T> value) {
60   if (!value)
61     error = GDATA_PARSE_ERROR;
62   callback.Run(error, value.Pass());
63 }
64 
65 // Parses the JSON value to a resource typed |T| and runs |callback| on
66 // blocking pool, and then run on the current thread.
67 // TODO(hidehiko): Move this and ParseJsonAndRun defined above into base with
68 // merging the tasks running on blocking pool into one.
69 template<typename T>
ParseJsonOnBlockingPoolAndRun(scoped_refptr<base::TaskRunner> blocking_task_runner,const base::Callback<void (GDataErrorCode,scoped_ptr<T>)> & callback,GDataErrorCode error,scoped_ptr<base::Value> value)70 void ParseJsonOnBlockingPoolAndRun(
71     scoped_refptr<base::TaskRunner> blocking_task_runner,
72     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
73     GDataErrorCode error,
74     scoped_ptr<base::Value> value) {
75   DCHECK(!callback.is_null());
76 
77   if (!value) {
78     callback.Run(error, scoped_ptr<T>());
79     return;
80   }
81 
82   base::PostTaskAndReplyWithResult(
83       blocking_task_runner,
84       FROM_HERE,
85       base::Bind(&ParseJsonOnBlockingPool<T>, base::Passed(&value)),
86       base::Bind(&ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask<T>,
87                  callback, error));
88 }
89 
90 // Parses the JSON value to FileResource instance and runs |callback| on the
91 // UI thread once parsing is done.
92 // This is customized version of ParseJsonAndRun defined above to adapt the
93 // remaining response type.
ParseFileResourceWithUploadRangeAndRun(const drive::UploadRangeCallback & callback,const UploadRangeResponse & response,scoped_ptr<base::Value> value)94 void ParseFileResourceWithUploadRangeAndRun(
95     const drive::UploadRangeCallback& callback,
96     const UploadRangeResponse& response,
97     scoped_ptr<base::Value> value) {
98   DCHECK(!callback.is_null());
99 
100   scoped_ptr<FileResource> file_resource;
101   if (value) {
102     file_resource = FileResource::CreateFrom(*value);
103     if (!file_resource) {
104       callback.Run(
105           UploadRangeResponse(GDATA_PARSE_ERROR,
106                               response.start_position_received,
107                               response.end_position_received),
108           scoped_ptr<FileResource>());
109       return;
110     }
111   }
112 
113   callback.Run(response, file_resource.Pass());
114 }
115 
116 }  // namespace
117 
118 namespace drive {
119 
120 //============================ DriveApiDataRequest ===========================
121 
DriveApiDataRequest(RequestSender * sender,const GetDataCallback & callback)122 DriveApiDataRequest::DriveApiDataRequest(RequestSender* sender,
123                                          const GetDataCallback& callback)
124     : GetDataRequest(sender, callback) {
125 }
126 
~DriveApiDataRequest()127 DriveApiDataRequest::~DriveApiDataRequest() {
128 }
129 
GetURL() const130 GURL DriveApiDataRequest::GetURL() const {
131   GURL url = GetURLInternal();
132   if (!fields_.empty())
133     url = net::AppendOrReplaceQueryParameter(url, "fields", fields_);
134   return url;
135 }
136 
137 //=============================== FilesGetRequest =============================
138 
FilesGetRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileResourceCallback & callback)139 FilesGetRequest::FilesGetRequest(
140     RequestSender* sender,
141     const DriveApiUrlGenerator& url_generator,
142     const FileResourceCallback& callback)
143     : DriveApiDataRequest(
144           sender,
145           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
146       url_generator_(url_generator) {
147   DCHECK(!callback.is_null());
148 }
149 
~FilesGetRequest()150 FilesGetRequest::~FilesGetRequest() {}
151 
GetURLInternal() const152 GURL FilesGetRequest::GetURLInternal() const {
153   return url_generator_.GetFilesGetUrl(file_id_);
154 }
155 
156 //============================ FilesInsertRequest ============================
157 
FilesInsertRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileResourceCallback & callback)158 FilesInsertRequest::FilesInsertRequest(
159     RequestSender* sender,
160     const DriveApiUrlGenerator& url_generator,
161     const FileResourceCallback& callback)
162     : DriveApiDataRequest(
163           sender,
164           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
165       url_generator_(url_generator) {
166   DCHECK(!callback.is_null());
167 }
168 
~FilesInsertRequest()169 FilesInsertRequest::~FilesInsertRequest() {}
170 
GetRequestType() const171 net::URLFetcher::RequestType FilesInsertRequest::GetRequestType() const {
172   return net::URLFetcher::POST;
173 }
174 
GetContentData(std::string * upload_content_type,std::string * upload_content)175 bool FilesInsertRequest::GetContentData(std::string* upload_content_type,
176                                         std::string* upload_content) {
177   *upload_content_type = kContentTypeApplicationJson;
178 
179   base::DictionaryValue root;
180 
181   if (!mime_type_.empty())
182     root.SetString("mimeType", mime_type_);
183 
184   if (!parents_.empty()) {
185     base::ListValue* parents_value = new base::ListValue;
186     for (size_t i = 0; i < parents_.size(); ++i) {
187       base::DictionaryValue* parent = new base::DictionaryValue;
188       parent->SetString("id", parents_[i]);
189       parents_value->Append(parent);
190     }
191     root.Set("parents", parents_value);
192   }
193 
194   if (!title_.empty())
195     root.SetString("title", title_);
196 
197   base::JSONWriter::Write(&root, upload_content);
198   DVLOG(1) << "FilesInsert data: " << *upload_content_type << ", ["
199            << *upload_content << "]";
200   return true;
201 }
202 
GetURLInternal() const203 GURL FilesInsertRequest::GetURLInternal() const {
204   return url_generator_.GetFilesInsertUrl();
205 }
206 
207 //============================== FilesPatchRequest ============================
208 
FilesPatchRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileResourceCallback & callback)209 FilesPatchRequest::FilesPatchRequest(
210     RequestSender* sender,
211     const DriveApiUrlGenerator& url_generator,
212     const FileResourceCallback& callback)
213     : DriveApiDataRequest(
214           sender,
215           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
216       url_generator_(url_generator),
217       set_modified_date_(false),
218       update_viewed_date_(true) {
219   DCHECK(!callback.is_null());
220 }
221 
~FilesPatchRequest()222 FilesPatchRequest::~FilesPatchRequest() {}
223 
GetRequestType() const224 net::URLFetcher::RequestType FilesPatchRequest::GetRequestType() const {
225   return net::URLFetcher::PATCH;
226 }
227 
GetExtraRequestHeaders() const228 std::vector<std::string> FilesPatchRequest::GetExtraRequestHeaders() const {
229   std::vector<std::string> headers;
230   headers.push_back(util::kIfMatchAllHeader);
231   return headers;
232 }
233 
GetURLInternal() const234 GURL FilesPatchRequest::GetURLInternal() const {
235   return url_generator_.GetFilesPatchUrl(
236       file_id_, set_modified_date_, update_viewed_date_);
237 }
238 
GetContentData(std::string * upload_content_type,std::string * upload_content)239 bool FilesPatchRequest::GetContentData(std::string* upload_content_type,
240                                        std::string* upload_content) {
241   if (title_.empty() &&
242       modified_date_.is_null() &&
243       last_viewed_by_me_date_.is_null() &&
244       parents_.empty())
245     return false;
246 
247   *upload_content_type = kContentTypeApplicationJson;
248 
249   base::DictionaryValue root;
250   if (!title_.empty())
251     root.SetString("title", title_);
252 
253   if (!modified_date_.is_null())
254     root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
255 
256   if (!last_viewed_by_me_date_.is_null()) {
257     root.SetString("lastViewedByMeDate",
258                    util::FormatTimeAsString(last_viewed_by_me_date_));
259   }
260 
261   if (!parents_.empty()) {
262     base::ListValue* parents_value = new base::ListValue;
263     for (size_t i = 0; i < parents_.size(); ++i) {
264       base::DictionaryValue* parent = new base::DictionaryValue;
265       parent->SetString("id", parents_[i]);
266       parents_value->Append(parent);
267     }
268     root.Set("parents", parents_value);
269   }
270 
271   base::JSONWriter::Write(&root, upload_content);
272   DVLOG(1) << "FilesPatch data: " << *upload_content_type << ", ["
273            << *upload_content << "]";
274   return true;
275 }
276 
277 //============================= FilesCopyRequest ==============================
278 
FilesCopyRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileResourceCallback & callback)279 FilesCopyRequest::FilesCopyRequest(
280     RequestSender* sender,
281     const DriveApiUrlGenerator& url_generator,
282     const FileResourceCallback& callback)
283     : DriveApiDataRequest(
284           sender,
285           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
286       url_generator_(url_generator) {
287   DCHECK(!callback.is_null());
288 }
289 
~FilesCopyRequest()290 FilesCopyRequest::~FilesCopyRequest() {
291 }
292 
GetRequestType() const293 net::URLFetcher::RequestType FilesCopyRequest::GetRequestType() const {
294   return net::URLFetcher::POST;
295 }
296 
GetURLInternal() const297 GURL FilesCopyRequest::GetURLInternal() const {
298   return url_generator_.GetFilesCopyUrl(file_id_);
299 }
300 
GetContentData(std::string * upload_content_type,std::string * upload_content)301 bool FilesCopyRequest::GetContentData(std::string* upload_content_type,
302                                       std::string* upload_content) {
303   if (parents_.empty() && title_.empty())
304     return false;
305 
306   *upload_content_type = kContentTypeApplicationJson;
307 
308   base::DictionaryValue root;
309 
310   if (!modified_date_.is_null())
311     root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
312 
313   if (!parents_.empty()) {
314     base::ListValue* parents_value = new base::ListValue;
315     for (size_t i = 0; i < parents_.size(); ++i) {
316       base::DictionaryValue* parent = new base::DictionaryValue;
317       parent->SetString("id", parents_[i]);
318       parents_value->Append(parent);
319     }
320     root.Set("parents", parents_value);
321   }
322 
323   if (!title_.empty())
324     root.SetString("title", title_);
325 
326   base::JSONWriter::Write(&root, upload_content);
327   DVLOG(1) << "FilesCopy data: " << *upload_content_type << ", ["
328            << *upload_content << "]";
329   return true;
330 }
331 
332 //============================= FilesListRequest =============================
333 
FilesListRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileListCallback & callback)334 FilesListRequest::FilesListRequest(
335     RequestSender* sender,
336     const DriveApiUrlGenerator& url_generator,
337     const FileListCallback& callback)
338     : DriveApiDataRequest(
339           sender,
340           base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>,
341                      make_scoped_refptr(sender->blocking_task_runner()),
342                      callback)),
343       url_generator_(url_generator),
344       max_results_(100) {
345   DCHECK(!callback.is_null());
346 }
347 
~FilesListRequest()348 FilesListRequest::~FilesListRequest() {}
349 
GetURLInternal() const350 GURL FilesListRequest::GetURLInternal() const {
351   return url_generator_.GetFilesListUrl(max_results_, page_token_, q_);
352 }
353 
354 //======================== FilesListNextPageRequest =========================
355 
FilesListNextPageRequest(RequestSender * sender,const FileListCallback & callback)356 FilesListNextPageRequest::FilesListNextPageRequest(
357     RequestSender* sender,
358     const FileListCallback& callback)
359     : DriveApiDataRequest(
360           sender,
361           base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>,
362                      make_scoped_refptr(sender->blocking_task_runner()),
363                      callback)) {
364   DCHECK(!callback.is_null());
365 }
366 
~FilesListNextPageRequest()367 FilesListNextPageRequest::~FilesListNextPageRequest() {
368 }
369 
GetURLInternal() const370 GURL FilesListNextPageRequest::GetURLInternal() const {
371   return next_link_;
372 }
373 
374 //============================ FilesDeleteRequest =============================
375 
FilesDeleteRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const EntryActionCallback & callback)376 FilesDeleteRequest::FilesDeleteRequest(
377     RequestSender* sender,
378     const DriveApiUrlGenerator& url_generator,
379     const EntryActionCallback& callback)
380     : EntryActionRequest(sender, callback),
381       url_generator_(url_generator) {
382   DCHECK(!callback.is_null());
383 }
384 
~FilesDeleteRequest()385 FilesDeleteRequest::~FilesDeleteRequest() {}
386 
GetRequestType() const387 net::URLFetcher::RequestType FilesDeleteRequest::GetRequestType() const {
388   return net::URLFetcher::DELETE_REQUEST;
389 }
390 
GetURL() const391 GURL FilesDeleteRequest::GetURL() const {
392   return url_generator_.GetFilesDeleteUrl(file_id_);
393 }
394 
GetExtraRequestHeaders() const395 std::vector<std::string> FilesDeleteRequest::GetExtraRequestHeaders() const {
396   std::vector<std::string> headers(
397       EntryActionRequest::GetExtraRequestHeaders());
398   headers.push_back(util::GenerateIfMatchHeader(etag_));
399   return headers;
400 }
401 
402 //============================ FilesTrashRequest =============================
403 
FilesTrashRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const FileResourceCallback & callback)404 FilesTrashRequest::FilesTrashRequest(
405     RequestSender* sender,
406     const DriveApiUrlGenerator& url_generator,
407     const FileResourceCallback& callback)
408     : DriveApiDataRequest(
409           sender,
410           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
411       url_generator_(url_generator) {
412   DCHECK(!callback.is_null());
413 }
414 
~FilesTrashRequest()415 FilesTrashRequest::~FilesTrashRequest() {}
416 
GetRequestType() const417 net::URLFetcher::RequestType FilesTrashRequest::GetRequestType() const {
418   return net::URLFetcher::POST;
419 }
420 
GetURLInternal() const421 GURL FilesTrashRequest::GetURLInternal() const {
422   return url_generator_.GetFilesTrashUrl(file_id_);
423 }
424 
425 //============================== AboutGetRequest =============================
426 
AboutGetRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const AboutResourceCallback & callback)427 AboutGetRequest::AboutGetRequest(
428     RequestSender* sender,
429     const DriveApiUrlGenerator& url_generator,
430     const AboutResourceCallback& callback)
431     : DriveApiDataRequest(
432           sender,
433           base::Bind(&ParseJsonAndRun<AboutResource>, callback)),
434       url_generator_(url_generator) {
435   DCHECK(!callback.is_null());
436 }
437 
~AboutGetRequest()438 AboutGetRequest::~AboutGetRequest() {}
439 
GetURLInternal() const440 GURL AboutGetRequest::GetURLInternal() const {
441   return url_generator_.GetAboutGetUrl();
442 }
443 
444 //============================ ChangesListRequest ===========================
445 
ChangesListRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const ChangeListCallback & callback)446 ChangesListRequest::ChangesListRequest(
447     RequestSender* sender,
448     const DriveApiUrlGenerator& url_generator,
449     const ChangeListCallback& callback)
450     : DriveApiDataRequest(
451           sender,
452           base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>,
453                      make_scoped_refptr(sender->blocking_task_runner()),
454                      callback)),
455       url_generator_(url_generator),
456       include_deleted_(true),
457       max_results_(100),
458       start_change_id_(0) {
459   DCHECK(!callback.is_null());
460 }
461 
~ChangesListRequest()462 ChangesListRequest::~ChangesListRequest() {}
463 
GetURLInternal() const464 GURL ChangesListRequest::GetURLInternal() const {
465   return url_generator_.GetChangesListUrl(
466       include_deleted_, max_results_, page_token_, start_change_id_);
467 }
468 
469 //======================== ChangesListNextPageRequest =========================
470 
ChangesListNextPageRequest(RequestSender * sender,const ChangeListCallback & callback)471 ChangesListNextPageRequest::ChangesListNextPageRequest(
472     RequestSender* sender,
473     const ChangeListCallback& callback)
474     : DriveApiDataRequest(
475           sender,
476           base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>,
477                      make_scoped_refptr(sender->blocking_task_runner()),
478                      callback)) {
479   DCHECK(!callback.is_null());
480 }
481 
~ChangesListNextPageRequest()482 ChangesListNextPageRequest::~ChangesListNextPageRequest() {
483 }
484 
GetURLInternal() const485 GURL ChangesListNextPageRequest::GetURLInternal() const {
486   return next_link_;
487 }
488 
489 //============================== AppsListRequest ===========================
490 
AppsListRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const AppListCallback & callback)491 AppsListRequest::AppsListRequest(
492     RequestSender* sender,
493     const DriveApiUrlGenerator& url_generator,
494     const AppListCallback& callback)
495     : DriveApiDataRequest(
496           sender,
497           base::Bind(&ParseJsonAndRun<AppList>, callback)),
498       url_generator_(url_generator) {
499   DCHECK(!callback.is_null());
500 }
501 
~AppsListRequest()502 AppsListRequest::~AppsListRequest() {}
503 
GetURLInternal() const504 GURL AppsListRequest::GetURLInternal() const {
505   return url_generator_.GetAppsListUrl();
506 }
507 
508 //========================== ChildrenInsertRequest ============================
509 
ChildrenInsertRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const EntryActionCallback & callback)510 ChildrenInsertRequest::ChildrenInsertRequest(
511     RequestSender* sender,
512     const DriveApiUrlGenerator& url_generator,
513     const EntryActionCallback& callback)
514     : EntryActionRequest(sender, callback),
515       url_generator_(url_generator) {
516   DCHECK(!callback.is_null());
517 }
518 
~ChildrenInsertRequest()519 ChildrenInsertRequest::~ChildrenInsertRequest() {}
520 
GetRequestType() const521 net::URLFetcher::RequestType ChildrenInsertRequest::GetRequestType() const {
522   return net::URLFetcher::POST;
523 }
524 
GetURL() const525 GURL ChildrenInsertRequest::GetURL() const {
526   return url_generator_.GetChildrenInsertUrl(folder_id_);
527 }
528 
GetContentData(std::string * upload_content_type,std::string * upload_content)529 bool ChildrenInsertRequest::GetContentData(std::string* upload_content_type,
530                                            std::string* upload_content) {
531   *upload_content_type = kContentTypeApplicationJson;
532 
533   base::DictionaryValue root;
534   root.SetString("id", id_);
535 
536   base::JSONWriter::Write(&root, upload_content);
537   DVLOG(1) << "InsertResource data: " << *upload_content_type << ", ["
538            << *upload_content << "]";
539   return true;
540 }
541 
542 //========================== ChildrenDeleteRequest ============================
543 
ChildrenDeleteRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const EntryActionCallback & callback)544 ChildrenDeleteRequest::ChildrenDeleteRequest(
545     RequestSender* sender,
546     const DriveApiUrlGenerator& url_generator,
547     const EntryActionCallback& callback)
548     : EntryActionRequest(sender, callback),
549       url_generator_(url_generator) {
550   DCHECK(!callback.is_null());
551 }
552 
~ChildrenDeleteRequest()553 ChildrenDeleteRequest::~ChildrenDeleteRequest() {}
554 
GetRequestType() const555 net::URLFetcher::RequestType ChildrenDeleteRequest::GetRequestType() const {
556   return net::URLFetcher::DELETE_REQUEST;
557 }
558 
GetURL() const559 GURL ChildrenDeleteRequest::GetURL() const {
560   return url_generator_.GetChildrenDeleteUrl(child_id_, folder_id_);
561 }
562 
563 //======================= InitiateUploadNewFileRequest =======================
564 
InitiateUploadNewFileRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const std::string & content_type,int64 content_length,const std::string & parent_resource_id,const std::string & title,const InitiateUploadCallback & callback)565 InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
566     RequestSender* sender,
567     const DriveApiUrlGenerator& url_generator,
568     const std::string& content_type,
569     int64 content_length,
570     const std::string& parent_resource_id,
571     const std::string& title,
572     const InitiateUploadCallback& callback)
573     : InitiateUploadRequestBase(sender,
574                                 callback,
575                                 content_type,
576                                 content_length),
577       url_generator_(url_generator),
578       parent_resource_id_(parent_resource_id),
579       title_(title) {
580 }
581 
~InitiateUploadNewFileRequest()582 InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
583 
GetURL() const584 GURL InitiateUploadNewFileRequest::GetURL() const {
585   return url_generator_.GetInitiateUploadNewFileUrl();
586 }
587 
588 net::URLFetcher::RequestType
GetRequestType() const589 InitiateUploadNewFileRequest::GetRequestType() const {
590   return net::URLFetcher::POST;
591 }
592 
GetContentData(std::string * upload_content_type,std::string * upload_content)593 bool InitiateUploadNewFileRequest::GetContentData(
594     std::string* upload_content_type,
595     std::string* upload_content) {
596   *upload_content_type = kContentTypeApplicationJson;
597 
598   base::DictionaryValue root;
599   root.SetString("title", title_);
600 
601   // Fill parent link.
602   {
603     scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue);
604     parent->SetString("kind", kParentLinkKind);
605     parent->SetString("id", parent_resource_id_);
606 
607     scoped_ptr<base::ListValue> parents(new base::ListValue);
608     parents->Append(parent.release());
609 
610     root.Set("parents", parents.release());
611   }
612 
613   base::JSONWriter::Write(&root, upload_content);
614 
615   DVLOG(1) << "InitiateUploadNewFile data: " << *upload_content_type << ", ["
616            << *upload_content << "]";
617   return true;
618 }
619 
620 //===================== InitiateUploadExistingFileRequest ====================
621 
InitiateUploadExistingFileRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const std::string & content_type,int64 content_length,const std::string & resource_id,const std::string & etag,const InitiateUploadCallback & callback)622 InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
623     RequestSender* sender,
624     const DriveApiUrlGenerator& url_generator,
625     const std::string& content_type,
626     int64 content_length,
627     const std::string& resource_id,
628     const std::string& etag,
629     const InitiateUploadCallback& callback)
630     : InitiateUploadRequestBase(sender,
631                                 callback,
632                                 content_type,
633                                 content_length),
634       url_generator_(url_generator),
635       resource_id_(resource_id),
636       etag_(etag) {
637 }
638 
~InitiateUploadExistingFileRequest()639 InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
640 
GetURL() const641 GURL InitiateUploadExistingFileRequest::GetURL() const {
642   return url_generator_.GetInitiateUploadExistingFileUrl(resource_id_);
643 }
644 
645 net::URLFetcher::RequestType
GetRequestType() const646 InitiateUploadExistingFileRequest::GetRequestType() const {
647   return net::URLFetcher::PUT;
648 }
649 
650 std::vector<std::string>
GetExtraRequestHeaders() const651 InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
652   std::vector<std::string> headers(
653       InitiateUploadRequestBase::GetExtraRequestHeaders());
654   headers.push_back(util::GenerateIfMatchHeader(etag_));
655   return headers;
656 }
657 
658 //============================ ResumeUploadRequest ===========================
659 
ResumeUploadRequest(RequestSender * sender,const GURL & upload_location,int64 start_position,int64 end_position,int64 content_length,const std::string & content_type,const base::FilePath & local_file_path,const UploadRangeCallback & callback,const ProgressCallback & progress_callback)660 ResumeUploadRequest::ResumeUploadRequest(
661     RequestSender* sender,
662     const GURL& upload_location,
663     int64 start_position,
664     int64 end_position,
665     int64 content_length,
666     const std::string& content_type,
667     const base::FilePath& local_file_path,
668     const UploadRangeCallback& callback,
669     const ProgressCallback& progress_callback)
670     : ResumeUploadRequestBase(sender,
671                               upload_location,
672                               start_position,
673                               end_position,
674                               content_length,
675                               content_type,
676                               local_file_path),
677       callback_(callback),
678       progress_callback_(progress_callback) {
679   DCHECK(!callback_.is_null());
680 }
681 
~ResumeUploadRequest()682 ResumeUploadRequest::~ResumeUploadRequest() {}
683 
OnRangeRequestComplete(const UploadRangeResponse & response,scoped_ptr<base::Value> value)684 void ResumeUploadRequest::OnRangeRequestComplete(
685     const UploadRangeResponse& response,
686     scoped_ptr<base::Value> value) {
687   DCHECK(CalledOnValidThread());
688   ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
689 }
690 
OnURLFetchUploadProgress(const net::URLFetcher * source,int64 current,int64 total)691 void ResumeUploadRequest::OnURLFetchUploadProgress(
692     const net::URLFetcher* source, int64 current, int64 total) {
693   if (!progress_callback_.is_null())
694     progress_callback_.Run(current, total);
695 }
696 
697 //========================== GetUploadStatusRequest ==========================
698 
GetUploadStatusRequest(RequestSender * sender,const GURL & upload_url,int64 content_length,const UploadRangeCallback & callback)699 GetUploadStatusRequest::GetUploadStatusRequest(
700     RequestSender* sender,
701     const GURL& upload_url,
702     int64 content_length,
703     const UploadRangeCallback& callback)
704     : GetUploadStatusRequestBase(sender,
705                                  upload_url,
706                                  content_length),
707       callback_(callback) {
708   DCHECK(!callback.is_null());
709 }
710 
~GetUploadStatusRequest()711 GetUploadStatusRequest::~GetUploadStatusRequest() {}
712 
OnRangeRequestComplete(const UploadRangeResponse & response,scoped_ptr<base::Value> value)713 void GetUploadStatusRequest::OnRangeRequestComplete(
714     const UploadRangeResponse& response,
715     scoped_ptr<base::Value> value) {
716   DCHECK(CalledOnValidThread());
717   ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
718 }
719 
720 //========================== DownloadFileRequest ==========================
721 
DownloadFileRequest(RequestSender * sender,const DriveApiUrlGenerator & url_generator,const std::string & resource_id,const base::FilePath & output_file_path,const DownloadActionCallback & download_action_callback,const GetContentCallback & get_content_callback,const ProgressCallback & progress_callback)722 DownloadFileRequest::DownloadFileRequest(
723     RequestSender* sender,
724     const DriveApiUrlGenerator& url_generator,
725     const std::string& resource_id,
726     const base::FilePath& output_file_path,
727     const DownloadActionCallback& download_action_callback,
728     const GetContentCallback& get_content_callback,
729     const ProgressCallback& progress_callback)
730     : DownloadFileRequestBase(
731           sender,
732           download_action_callback,
733           get_content_callback,
734           progress_callback,
735           url_generator.GenerateDownloadFileUrl(resource_id),
736           output_file_path) {
737 }
738 
~DownloadFileRequest()739 DownloadFileRequest::~DownloadFileRequest() {
740 }
741 
742 }  // namespace drive
743 }  // namespace google_apis
744