• 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/gdata_wapi_requests.h"
6 
7 #include "base/location.h"
8 #include "base/sequenced_task_runner.h"
9 #include "base/task_runner_util.h"
10 #include "base/values.h"
11 #include "google_apis/drive/gdata_wapi_parser.h"
12 #include "google_apis/drive/gdata_wapi_url_generator.h"
13 #include "google_apis/drive/request_sender.h"
14 #include "google_apis/drive/request_util.h"
15 #include "third_party/libxml/chromium/libxml_utils.h"
16 
17 using net::URLFetcher;
18 
19 namespace google_apis {
20 
21 namespace {
22 
23 // Parses the JSON value to ResourceList.
ParseResourceListOnBlockingPool(scoped_ptr<base::Value> value)24 scoped_ptr<ResourceList> ParseResourceListOnBlockingPool(
25     scoped_ptr<base::Value> value) {
26   DCHECK(value);
27 
28   return ResourceList::ExtractAndParse(*value);
29 }
30 
31 // Runs |callback| with |error| and |resource_list|, but replace the error code
32 // with GDATA_PARSE_ERROR, if there was a parsing error.
DidParseResourceListOnBlockingPool(const GetResourceListCallback & callback,GDataErrorCode error,scoped_ptr<ResourceList> resource_list)33 void DidParseResourceListOnBlockingPool(
34     const GetResourceListCallback& callback,
35     GDataErrorCode error,
36     scoped_ptr<ResourceList> resource_list) {
37   DCHECK(!callback.is_null());
38 
39   // resource_list being NULL indicates there was a parsing error.
40   if (!resource_list)
41     error = GDATA_PARSE_ERROR;
42 
43   callback.Run(error, resource_list.Pass());
44 }
45 
46 // Parses the JSON value to ResourceList on the blocking pool and runs
47 // |callback| on the UI thread once parsing is done.
ParseResourceListAndRun(scoped_refptr<base::TaskRunner> blocking_task_runner,const GetResourceListCallback & callback,GDataErrorCode error,scoped_ptr<base::Value> value)48 void ParseResourceListAndRun(
49     scoped_refptr<base::TaskRunner> blocking_task_runner,
50     const GetResourceListCallback& callback,
51     GDataErrorCode error,
52     scoped_ptr<base::Value> value) {
53   DCHECK(!callback.is_null());
54 
55   if (!value) {
56     callback.Run(error, scoped_ptr<ResourceList>());
57     return;
58   }
59 
60   base::PostTaskAndReplyWithResult(
61       blocking_task_runner,
62       FROM_HERE,
63       base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
64       base::Bind(&DidParseResourceListOnBlockingPool, callback, error));
65 }
66 
67 // Parses the JSON value to AccountMetadata and runs |callback| on the UI
68 // thread once parsing is done.
ParseAccounetMetadataAndRun(const GetAccountMetadataCallback & callback,GDataErrorCode error,scoped_ptr<base::Value> value)69 void ParseAccounetMetadataAndRun(const GetAccountMetadataCallback& callback,
70                                  GDataErrorCode error,
71                                  scoped_ptr<base::Value> value) {
72   DCHECK(!callback.is_null());
73 
74   if (!value) {
75     callback.Run(error, scoped_ptr<AccountMetadata>());
76     return;
77   }
78 
79   // Parsing AccountMetadata is cheap enough to do on UI thread.
80   scoped_ptr<AccountMetadata> entry =
81       google_apis::AccountMetadata::CreateFrom(*value);
82   if (!entry) {
83     callback.Run(GDATA_PARSE_ERROR, scoped_ptr<AccountMetadata>());
84     return;
85   }
86 
87   callback.Run(error, entry.Pass());
88 }
89 
90 // Parses the |value| to ResourceEntry with error handling.
91 // This is designed to be used for ResumeUploadRequest and
92 // GetUploadStatusRequest.
ParseResourceEntry(scoped_ptr<base::Value> value)93 scoped_ptr<ResourceEntry> ParseResourceEntry(scoped_ptr<base::Value> value) {
94   scoped_ptr<ResourceEntry> entry;
95   if (value.get()) {
96     entry = ResourceEntry::ExtractAndParse(*value);
97 
98     // Note: |value| may be NULL, in particular if the callback is for a
99     // failure.
100     if (!entry.get())
101       LOG(WARNING) << "Invalid entry received on upload.";
102   }
103 
104   return entry.Pass();
105 }
106 
107 // Extracts the open link url from the JSON Feed. Used by AuthorizeApp().
ParseOpenLinkAndRun(const std::string & app_id,const AuthorizeAppCallback & callback,GDataErrorCode error,scoped_ptr<base::Value> value)108 void ParseOpenLinkAndRun(const std::string& app_id,
109                          const AuthorizeAppCallback& callback,
110                          GDataErrorCode error,
111                          scoped_ptr<base::Value> value) {
112   DCHECK(!callback.is_null());
113 
114   if (!value) {
115     callback.Run(error, GURL());
116     return;
117   }
118 
119   // Parsing ResourceEntry is cheap enough to do on UI thread.
120   scoped_ptr<ResourceEntry> resource_entry = ParseResourceEntry(value.Pass());
121   if (!resource_entry) {
122     callback.Run(GDATA_PARSE_ERROR, GURL());
123     return;
124   }
125 
126   // Look for the link to open the file with the app with |app_id|.
127   const ScopedVector<Link>& resource_links = resource_entry->links();
128   GURL open_link;
129   for (size_t i = 0; i < resource_links.size(); ++i) {
130     const Link& link = *resource_links[i];
131     if (link.type() == Link::LINK_OPEN_WITH && link.app_id() == app_id) {
132       open_link = link.href();
133       break;
134     }
135   }
136 
137   if (open_link.is_empty())
138     error = GDATA_OTHER_ERROR;
139 
140   callback.Run(error, open_link);
141 }
142 
143 }  // namespace
144 
145 //============================ GetResourceListRequest ========================
146 
GetResourceListRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const GURL & override_url,int64 start_changestamp,const std::string & search_string,const std::string & directory_resource_id,const GetResourceListCallback & callback)147 GetResourceListRequest::GetResourceListRequest(
148     RequestSender* sender,
149     const GDataWapiUrlGenerator& url_generator,
150     const GURL& override_url,
151     int64 start_changestamp,
152     const std::string& search_string,
153     const std::string& directory_resource_id,
154     const GetResourceListCallback& callback)
155     : GetDataRequest(
156           sender,
157           base::Bind(&ParseResourceListAndRun,
158                      make_scoped_refptr(sender->blocking_task_runner()),
159                      callback)),
160       url_generator_(url_generator),
161       override_url_(override_url),
162       start_changestamp_(start_changestamp),
163       search_string_(search_string),
164       directory_resource_id_(directory_resource_id) {
165   DCHECK(!callback.is_null());
166 }
167 
~GetResourceListRequest()168 GetResourceListRequest::~GetResourceListRequest() {}
169 
GetURL() const170 GURL GetResourceListRequest::GetURL() const {
171   return url_generator_.GenerateResourceListUrl(override_url_,
172                                                 start_changestamp_,
173                                                 search_string_,
174                                                 directory_resource_id_);
175 }
176 
177 //============================ SearchByTitleRequest ==========================
178 
SearchByTitleRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const std::string & title,const std::string & directory_resource_id,const GetResourceListCallback & callback)179 SearchByTitleRequest::SearchByTitleRequest(
180     RequestSender* sender,
181     const GDataWapiUrlGenerator& url_generator,
182     const std::string& title,
183     const std::string& directory_resource_id,
184     const GetResourceListCallback& callback)
185     : GetDataRequest(
186           sender,
187           base::Bind(&ParseResourceListAndRun,
188                      make_scoped_refptr(sender->blocking_task_runner()),
189                      callback)),
190       url_generator_(url_generator),
191       title_(title),
192       directory_resource_id_(directory_resource_id) {
193   DCHECK(!callback.is_null());
194 }
195 
~SearchByTitleRequest()196 SearchByTitleRequest::~SearchByTitleRequest() {}
197 
GetURL() const198 GURL SearchByTitleRequest::GetURL() const {
199   return url_generator_.GenerateSearchByTitleUrl(
200       title_, directory_resource_id_);
201 }
202 
203 //============================ GetResourceEntryRequest =======================
204 
GetResourceEntryRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const std::string & resource_id,const GURL & embed_origin,const GetDataCallback & callback)205 GetResourceEntryRequest::GetResourceEntryRequest(
206     RequestSender* sender,
207     const GDataWapiUrlGenerator& url_generator,
208     const std::string& resource_id,
209     const GURL& embed_origin,
210     const GetDataCallback& callback)
211     : GetDataRequest(sender, callback),
212       url_generator_(url_generator),
213       resource_id_(resource_id),
214       embed_origin_(embed_origin) {
215   DCHECK(!callback.is_null());
216 }
217 
~GetResourceEntryRequest()218 GetResourceEntryRequest::~GetResourceEntryRequest() {}
219 
GetURL() const220 GURL GetResourceEntryRequest::GetURL() const {
221   return url_generator_.GenerateEditUrlWithEmbedOrigin(
222       resource_id_, embed_origin_);
223 }
224 
225 //========================= GetAccountMetadataRequest ========================
226 
GetAccountMetadataRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const GetAccountMetadataCallback & callback,bool include_installed_apps)227 GetAccountMetadataRequest::GetAccountMetadataRequest(
228     RequestSender* sender,
229     const GDataWapiUrlGenerator& url_generator,
230     const GetAccountMetadataCallback& callback,
231     bool include_installed_apps)
232     : GetDataRequest(sender,
233                      base::Bind(&ParseAccounetMetadataAndRun, callback)),
234       url_generator_(url_generator),
235       include_installed_apps_(include_installed_apps) {
236   DCHECK(!callback.is_null());
237 }
238 
~GetAccountMetadataRequest()239 GetAccountMetadataRequest::~GetAccountMetadataRequest() {}
240 
GetURL() const241 GURL GetAccountMetadataRequest::GetURL() const {
242   return url_generator_.GenerateAccountMetadataUrl(include_installed_apps_);
243 }
244 
245 //=========================== DeleteResourceRequest ==========================
246 
DeleteResourceRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const EntryActionCallback & callback,const std::string & resource_id,const std::string & etag)247 DeleteResourceRequest::DeleteResourceRequest(
248     RequestSender* sender,
249     const GDataWapiUrlGenerator& url_generator,
250     const EntryActionCallback& callback,
251     const std::string& resource_id,
252     const std::string& etag)
253     : EntryActionRequest(sender, callback),
254       url_generator_(url_generator),
255       resource_id_(resource_id),
256       etag_(etag) {
257   DCHECK(!callback.is_null());
258 }
259 
~DeleteResourceRequest()260 DeleteResourceRequest::~DeleteResourceRequest() {}
261 
GetURL() const262 GURL DeleteResourceRequest::GetURL() const {
263   return url_generator_.GenerateEditUrl(resource_id_);
264 }
265 
GetRequestType() const266 URLFetcher::RequestType DeleteResourceRequest::GetRequestType() const {
267   return URLFetcher::DELETE_REQUEST;
268 }
269 
270 std::vector<std::string>
GetExtraRequestHeaders() const271 DeleteResourceRequest::GetExtraRequestHeaders() const {
272   std::vector<std::string> headers;
273   headers.push_back(util::GenerateIfMatchHeader(etag_));
274   return headers;
275 }
276 
277 //========================== CreateDirectoryRequest ==========================
278 
CreateDirectoryRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const GetDataCallback & callback,const std::string & parent_resource_id,const std::string & directory_title)279 CreateDirectoryRequest::CreateDirectoryRequest(
280     RequestSender* sender,
281     const GDataWapiUrlGenerator& url_generator,
282     const GetDataCallback& callback,
283     const std::string& parent_resource_id,
284     const std::string& directory_title)
285     : GetDataRequest(sender, callback),
286       url_generator_(url_generator),
287       parent_resource_id_(parent_resource_id),
288       directory_title_(directory_title) {
289   DCHECK(!callback.is_null());
290 }
291 
~CreateDirectoryRequest()292 CreateDirectoryRequest::~CreateDirectoryRequest() {}
293 
GetURL() const294 GURL CreateDirectoryRequest::GetURL() const {
295   return url_generator_.GenerateContentUrl(parent_resource_id_);
296 }
297 
298 URLFetcher::RequestType
GetRequestType() const299 CreateDirectoryRequest::GetRequestType() const {
300   return URLFetcher::POST;
301 }
302 
GetContentData(std::string * upload_content_type,std::string * upload_content)303 bool CreateDirectoryRequest::GetContentData(std::string* upload_content_type,
304                                             std::string* upload_content) {
305   upload_content_type->assign("application/atom+xml");
306   XmlWriter xml_writer;
307   xml_writer.StartWriting();
308   xml_writer.StartElement("entry");
309   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
310 
311   xml_writer.StartElement("category");
312   xml_writer.AddAttribute("scheme",
313                           "http://schemas.google.com/g/2005#kind");
314   xml_writer.AddAttribute("term",
315                           "http://schemas.google.com/docs/2007#folder");
316   xml_writer.EndElement();  // Ends "category" element.
317 
318   xml_writer.WriteElement("title", directory_title_);
319 
320   xml_writer.EndElement();  // Ends "entry" element.
321   xml_writer.StopWriting();
322   upload_content->assign(xml_writer.GetWrittenString());
323   DVLOG(1) << "CreateDirectory data: " << *upload_content_type << ", ["
324            << *upload_content << "]";
325   return true;
326 }
327 
328 //=========================== RenameResourceRequest ==========================
329 
RenameResourceRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const EntryActionCallback & callback,const std::string & resource_id,const std::string & new_title)330 RenameResourceRequest::RenameResourceRequest(
331     RequestSender* sender,
332     const GDataWapiUrlGenerator& url_generator,
333     const EntryActionCallback& callback,
334     const std::string& resource_id,
335     const std::string& new_title)
336     : EntryActionRequest(sender, callback),
337       url_generator_(url_generator),
338       resource_id_(resource_id),
339       new_title_(new_title) {
340   DCHECK(!callback.is_null());
341 }
342 
~RenameResourceRequest()343 RenameResourceRequest::~RenameResourceRequest() {}
344 
GetRequestType() const345 URLFetcher::RequestType RenameResourceRequest::GetRequestType() const {
346   return URLFetcher::PUT;
347 }
348 
349 std::vector<std::string>
GetExtraRequestHeaders() const350 RenameResourceRequest::GetExtraRequestHeaders() const {
351   std::vector<std::string> headers;
352   headers.push_back(util::kIfMatchAllHeader);
353   return headers;
354 }
355 
GetURL() const356 GURL RenameResourceRequest::GetURL() const {
357   return url_generator_.GenerateEditUrl(resource_id_);
358 }
359 
GetContentData(std::string * upload_content_type,std::string * upload_content)360 bool RenameResourceRequest::GetContentData(std::string* upload_content_type,
361                                            std::string* upload_content) {
362   upload_content_type->assign("application/atom+xml");
363   XmlWriter xml_writer;
364   xml_writer.StartWriting();
365   xml_writer.StartElement("entry");
366   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
367 
368   xml_writer.WriteElement("title", new_title_);
369 
370   xml_writer.EndElement();  // Ends "entry" element.
371   xml_writer.StopWriting();
372   upload_content->assign(xml_writer.GetWrittenString());
373   DVLOG(1) << "RenameResourceRequest data: " << *upload_content_type << ", ["
374            << *upload_content << "]";
375   return true;
376 }
377 
378 //=========================== AuthorizeAppRequest ==========================
379 
AuthorizeAppRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const AuthorizeAppCallback & callback,const std::string & resource_id,const std::string & app_id)380 AuthorizeAppRequest::AuthorizeAppRequest(
381     RequestSender* sender,
382     const GDataWapiUrlGenerator& url_generator,
383     const AuthorizeAppCallback& callback,
384     const std::string& resource_id,
385     const std::string& app_id)
386     : GetDataRequest(sender,
387                      base::Bind(&ParseOpenLinkAndRun, app_id, callback)),
388       url_generator_(url_generator),
389       resource_id_(resource_id),
390       app_id_(app_id) {
391   DCHECK(!callback.is_null());
392 }
393 
~AuthorizeAppRequest()394 AuthorizeAppRequest::~AuthorizeAppRequest() {}
395 
GetRequestType() const396 URLFetcher::RequestType AuthorizeAppRequest::GetRequestType() const {
397   return URLFetcher::PUT;
398 }
399 
400 std::vector<std::string>
GetExtraRequestHeaders() const401 AuthorizeAppRequest::GetExtraRequestHeaders() const {
402   std::vector<std::string> headers;
403   headers.push_back(util::kIfMatchAllHeader);
404   return headers;
405 }
406 
GetContentData(std::string * upload_content_type,std::string * upload_content)407 bool AuthorizeAppRequest::GetContentData(std::string* upload_content_type,
408                                          std::string* upload_content) {
409   upload_content_type->assign("application/atom+xml");
410   XmlWriter xml_writer;
411   xml_writer.StartWriting();
412   xml_writer.StartElement("entry");
413   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
414   xml_writer.AddAttribute("xmlns:docs", "http://schemas.google.com/docs/2007");
415   xml_writer.WriteElement("docs:authorizedApp", app_id_);
416 
417   xml_writer.EndElement();  // Ends "entry" element.
418   xml_writer.StopWriting();
419   upload_content->assign(xml_writer.GetWrittenString());
420   DVLOG(1) << "AuthorizeAppRequest data: " << *upload_content_type << ", ["
421            << *upload_content << "]";
422   return true;
423 }
424 
GetURL() const425 GURL AuthorizeAppRequest::GetURL() const {
426   return url_generator_.GenerateEditUrl(resource_id_);
427 }
428 
429 //======================= AddResourceToDirectoryRequest ======================
430 
AddResourceToDirectoryRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const EntryActionCallback & callback,const std::string & parent_resource_id,const std::string & resource_id)431 AddResourceToDirectoryRequest::AddResourceToDirectoryRequest(
432     RequestSender* sender,
433     const GDataWapiUrlGenerator& url_generator,
434     const EntryActionCallback& callback,
435     const std::string& parent_resource_id,
436     const std::string& resource_id)
437     : EntryActionRequest(sender, callback),
438       url_generator_(url_generator),
439       parent_resource_id_(parent_resource_id),
440       resource_id_(resource_id) {
441   DCHECK(!callback.is_null());
442 }
443 
~AddResourceToDirectoryRequest()444 AddResourceToDirectoryRequest::~AddResourceToDirectoryRequest() {}
445 
GetURL() const446 GURL AddResourceToDirectoryRequest::GetURL() const {
447   return url_generator_.GenerateContentUrl(parent_resource_id_);
448 }
449 
450 URLFetcher::RequestType
GetRequestType() const451 AddResourceToDirectoryRequest::GetRequestType() const {
452   return URLFetcher::POST;
453 }
454 
GetContentData(std::string * upload_content_type,std::string * upload_content)455 bool AddResourceToDirectoryRequest::GetContentData(
456     std::string* upload_content_type, std::string* upload_content) {
457   upload_content_type->assign("application/atom+xml");
458   XmlWriter xml_writer;
459   xml_writer.StartWriting();
460   xml_writer.StartElement("entry");
461   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
462 
463   xml_writer.WriteElement(
464       "id", url_generator_.GenerateEditUrlWithoutParams(resource_id_).spec());
465 
466   xml_writer.EndElement();  // Ends "entry" element.
467   xml_writer.StopWriting();
468   upload_content->assign(xml_writer.GetWrittenString());
469   DVLOG(1) << "AddResourceToDirectoryRequest data: " << *upload_content_type
470            << ", [" << *upload_content << "]";
471   return true;
472 }
473 
474 //==================== RemoveResourceFromDirectoryRequest ====================
475 
RemoveResourceFromDirectoryRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const EntryActionCallback & callback,const std::string & parent_resource_id,const std::string & document_resource_id)476 RemoveResourceFromDirectoryRequest::RemoveResourceFromDirectoryRequest(
477     RequestSender* sender,
478     const GDataWapiUrlGenerator& url_generator,
479     const EntryActionCallback& callback,
480     const std::string& parent_resource_id,
481     const std::string& document_resource_id)
482     : EntryActionRequest(sender, callback),
483       url_generator_(url_generator),
484       resource_id_(document_resource_id),
485       parent_resource_id_(parent_resource_id) {
486   DCHECK(!callback.is_null());
487 }
488 
~RemoveResourceFromDirectoryRequest()489 RemoveResourceFromDirectoryRequest::~RemoveResourceFromDirectoryRequest() {
490 }
491 
GetURL() const492 GURL RemoveResourceFromDirectoryRequest::GetURL() const {
493   return url_generator_.GenerateResourceUrlForRemoval(
494       parent_resource_id_, resource_id_);
495 }
496 
497 URLFetcher::RequestType
GetRequestType() const498 RemoveResourceFromDirectoryRequest::GetRequestType() const {
499   return URLFetcher::DELETE_REQUEST;
500 }
501 
502 std::vector<std::string>
GetExtraRequestHeaders() const503 RemoveResourceFromDirectoryRequest::GetExtraRequestHeaders() const {
504   std::vector<std::string> headers;
505   headers.push_back(util::kIfMatchAllHeader);
506   return headers;
507 }
508 
509 //======================= InitiateUploadNewFileRequest =======================
510 
InitiateUploadNewFileRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const InitiateUploadCallback & callback,const std::string & content_type,int64 content_length,const std::string & parent_resource_id,const std::string & title)511 InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
512     RequestSender* sender,
513     const GDataWapiUrlGenerator& url_generator,
514     const InitiateUploadCallback& callback,
515     const std::string& content_type,
516     int64 content_length,
517     const std::string& parent_resource_id,
518     const std::string& title)
519     : InitiateUploadRequestBase(sender, callback, content_type, content_length),
520       url_generator_(url_generator),
521       parent_resource_id_(parent_resource_id),
522       title_(title) {
523 }
524 
~InitiateUploadNewFileRequest()525 InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
526 
GetURL() const527 GURL InitiateUploadNewFileRequest::GetURL() const {
528   return url_generator_.GenerateInitiateUploadNewFileUrl(parent_resource_id_);
529 }
530 
531 net::URLFetcher::RequestType
GetRequestType() const532 InitiateUploadNewFileRequest::GetRequestType() const {
533   return net::URLFetcher::POST;
534 }
535 
GetContentData(std::string * upload_content_type,std::string * upload_content)536 bool InitiateUploadNewFileRequest::GetContentData(
537     std::string* upload_content_type,
538     std::string* upload_content) {
539   upload_content_type->assign("application/atom+xml");
540   XmlWriter xml_writer;
541   xml_writer.StartWriting();
542   xml_writer.StartElement("entry");
543   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
544   xml_writer.AddAttribute("xmlns:docs",
545                           "http://schemas.google.com/docs/2007");
546   xml_writer.WriteElement("title", title_);
547   xml_writer.EndElement();  // Ends "entry" element.
548   xml_writer.StopWriting();
549   upload_content->assign(xml_writer.GetWrittenString());
550   DVLOG(1) << "InitiateUploadNewFile: " << *upload_content_type << ", ["
551            << *upload_content << "]";
552   return true;
553 }
554 
555 //===================== InitiateUploadExistingFileRequest ====================
556 
InitiateUploadExistingFileRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const InitiateUploadCallback & callback,const std::string & content_type,int64 content_length,const std::string & resource_id,const std::string & etag)557 InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
558     RequestSender* sender,
559     const GDataWapiUrlGenerator& url_generator,
560     const InitiateUploadCallback& callback,
561     const std::string& content_type,
562     int64 content_length,
563     const std::string& resource_id,
564     const std::string& etag)
565     : InitiateUploadRequestBase(sender, callback, content_type, content_length),
566       url_generator_(url_generator),
567       resource_id_(resource_id),
568       etag_(etag) {
569 }
570 
~InitiateUploadExistingFileRequest()571 InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
572 
GetURL() const573 GURL InitiateUploadExistingFileRequest::GetURL() const {
574   return url_generator_.GenerateInitiateUploadExistingFileUrl(resource_id_);
575 }
576 
577 net::URLFetcher::RequestType
GetRequestType() const578 InitiateUploadExistingFileRequest::GetRequestType() const {
579   return net::URLFetcher::PUT;
580 }
581 
GetContentData(std::string * upload_content_type,std::string * upload_content)582 bool InitiateUploadExistingFileRequest::GetContentData(
583     std::string* upload_content_type,
584     std::string* upload_content) {
585   // According to the document there is no need to send the content-type.
586   // However, the server would return 500 server error without the
587   // content-type.
588   // As its workaround, send "text/plain" content-type here.
589   *upload_content_type = "text/plain";
590   *upload_content = "";
591   return true;
592 }
593 
594 std::vector<std::string>
GetExtraRequestHeaders() const595 InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
596   std::vector<std::string> headers(
597       InitiateUploadRequestBase::GetExtraRequestHeaders());
598   headers.push_back(util::GenerateIfMatchHeader(etag_));
599   return headers;
600 }
601 
602 //============================ ResumeUploadRequest ===========================
603 
ResumeUploadRequest(RequestSender * sender,const UploadRangeCallback & callback,const ProgressCallback & progress_callback,const GURL & upload_location,int64 start_position,int64 end_position,int64 content_length,const std::string & content_type,const base::FilePath & local_file_path)604 ResumeUploadRequest::ResumeUploadRequest(
605     RequestSender* sender,
606     const UploadRangeCallback& callback,
607     const ProgressCallback& progress_callback,
608     const GURL& upload_location,
609     int64 start_position,
610     int64 end_position,
611     int64 content_length,
612     const std::string& content_type,
613     const base::FilePath& local_file_path)
614     : ResumeUploadRequestBase(sender,
615                               upload_location,
616                               start_position,
617                               end_position,
618                               content_length,
619                               content_type,
620                               local_file_path),
621       callback_(callback),
622       progress_callback_(progress_callback) {
623   DCHECK(!callback_.is_null());
624 }
625 
~ResumeUploadRequest()626 ResumeUploadRequest::~ResumeUploadRequest() {}
627 
OnRangeRequestComplete(const UploadRangeResponse & response,scoped_ptr<base::Value> value)628 void ResumeUploadRequest::OnRangeRequestComplete(
629     const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
630   callback_.Run(response, ParseResourceEntry(value.Pass()));
631 }
632 
OnURLFetchUploadProgress(const URLFetcher * source,int64 current,int64 total)633 void ResumeUploadRequest::OnURLFetchUploadProgress(
634     const URLFetcher* source, int64 current, int64 total) {
635   if (!progress_callback_.is_null())
636     progress_callback_.Run(current, total);
637 }
638 
639 //========================== GetUploadStatusRequest ==========================
640 
GetUploadStatusRequest(RequestSender * sender,const UploadRangeCallback & callback,const GURL & upload_url,int64 content_length)641 GetUploadStatusRequest::GetUploadStatusRequest(
642     RequestSender* sender,
643     const UploadRangeCallback& callback,
644     const GURL& upload_url,
645     int64 content_length)
646     : GetUploadStatusRequestBase(sender, upload_url, content_length),
647       callback_(callback) {
648   DCHECK(!callback.is_null());
649 }
650 
~GetUploadStatusRequest()651 GetUploadStatusRequest::~GetUploadStatusRequest() {}
652 
OnRangeRequestComplete(const UploadRangeResponse & response,scoped_ptr<base::Value> value)653 void GetUploadStatusRequest::OnRangeRequestComplete(
654     const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
655   callback_.Run(response, ParseResourceEntry(value.Pass()));
656 }
657 
658 //========================== DownloadFileRequest ==========================
659 
DownloadFileRequest(RequestSender * sender,const GDataWapiUrlGenerator & url_generator,const DownloadActionCallback & download_action_callback,const GetContentCallback & get_content_callback,const ProgressCallback & progress_callback,const std::string & resource_id,const base::FilePath & output_file_path)660 DownloadFileRequest::DownloadFileRequest(
661     RequestSender* sender,
662     const GDataWapiUrlGenerator& url_generator,
663     const DownloadActionCallback& download_action_callback,
664     const GetContentCallback& get_content_callback,
665     const ProgressCallback& progress_callback,
666     const std::string& resource_id,
667     const base::FilePath& output_file_path)
668     : DownloadFileRequestBase(
669           sender,
670           download_action_callback,
671           get_content_callback,
672           progress_callback,
673           url_generator.GenerateDownloadFileUrl(resource_id),
674           output_file_path) {
675 }
676 
~DownloadFileRequest()677 DownloadFileRequest::~DownloadFileRequest() {
678 }
679 
680 }  // namespace google_apis
681