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