Fix build break
[chromium-blink-merge.git] / chrome / browser / google_apis / gdata_wapi_operations.cc
blob0b78d67e070d04515baf3f4c8e79378b16546fa3
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.
5 #include "chrome/browser/google_apis/gdata_wapi_operations.h"
7 #include "base/stringprintf.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/task_runner_util.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "base/values.h"
12 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
13 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h"
14 #include "chrome/browser/google_apis/operation_util.h"
15 #include "chrome/browser/google_apis/time_util.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "net/base/escape.h"
18 #include "net/base/url_util.h"
19 #include "third_party/libxml/chromium/libxml_utils.h"
21 using content::BrowserThread;
22 using net::URLFetcher;
24 namespace google_apis {
26 namespace {
29 const char kUploadContentRange[] = "Content-Range: bytes ";
31 const char kFeedField[] = "feed";
33 // Templates for file uploading.
34 const char kUploadResponseRange[] = "range";
36 // Parses the JSON value to ResourceList.
37 scoped_ptr<ResourceList> ParseResourceListOnBlockingPool(
38 scoped_ptr<base::Value> value) {
39 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
40 DCHECK(value);
42 return ResourceList::ExtractAndParse(*value);
45 // Runs |callback| with |error| and |value|, but replace the error code with
46 // GDATA_PARSE_ERROR, if there was a parsing error.
47 void DidParseResourceListOnBlockingPool(
48 const GetResourceListCallback& callback,
49 GDataErrorCode error,
50 scoped_ptr<ResourceList> resource_list) {
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 DCHECK(!callback.is_null());
54 // resource_list being NULL indicates there was a parsing error.
55 if (!resource_list)
56 error = GDATA_PARSE_ERROR;
58 callback.Run(error, resource_list.Pass());
61 // Parses the JSON value to ResourceList on the blocking pool and runs
62 // |callback| on the UI thread once parsing is done.
63 void ParseResourceListAndRun(const GetResourceListCallback& callback,
64 GDataErrorCode error,
65 scoped_ptr<base::Value> value) {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
67 DCHECK(!callback.is_null());
69 if (!value) {
70 callback.Run(error, scoped_ptr<ResourceList>());
71 return;
74 base::PostTaskAndReplyWithResult(
75 BrowserThread::GetBlockingPool(),
76 FROM_HERE,
77 base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
78 base::Bind(&DidParseResourceListOnBlockingPool, callback, error));
81 // Parses the JSON value to AccountMetadata and runs |callback| on the UI
82 // thread once parsing is done.
83 void ParseAccounetMetadataAndRun(const GetAccountMetadataCallback& callback,
84 GDataErrorCode error,
85 scoped_ptr<base::Value> value) {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87 DCHECK(!callback.is_null());
89 if (!value) {
90 callback.Run(error, scoped_ptr<AccountMetadata>());
91 return;
94 // Parsing AccountMetadata is cheap enough to do on UI thread.
95 scoped_ptr<AccountMetadata> entry =
96 google_apis::AccountMetadata::CreateFrom(*value);
97 if (!entry) {
98 callback.Run(GDATA_PARSE_ERROR, scoped_ptr<AccountMetadata>());
99 return;
102 callback.Run(error, entry.Pass());
105 // Parses the |value| to ResourceEntry with error handling.
106 // This is designed to be used for ResumeUploadOperation and
107 // GetUploadStatusOperation.
108 scoped_ptr<ResourceEntry> ParseResourceEntry(scoped_ptr<base::Value> value) {
109 scoped_ptr<ResourceEntry> entry;
110 if (value.get()) {
111 entry = ResourceEntry::ExtractAndParse(*value);
113 // Note: |value| may be NULL, in particular if the callback is for a
114 // failure.
115 if (!entry.get())
116 LOG(WARNING) << "Invalid entry received on upload.";
119 return entry.Pass();
122 // Extracts the open link url from the JSON Feed. Used by AuthorizeApp().
123 void ParseOpenLinkAndRun(const std::string& app_id,
124 const AuthorizeAppCallback& callback,
125 GDataErrorCode error,
126 scoped_ptr<base::Value> value) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 DCHECK(!callback.is_null());
130 if (!value) {
131 callback.Run(error, GURL());
132 return;
135 // Parsing ResourceEntry is cheap enough to do on UI thread.
136 scoped_ptr<ResourceEntry> resource_entry = ParseResourceEntry(value.Pass());
137 if (!resource_entry) {
138 callback.Run(GDATA_PARSE_ERROR, GURL());
139 return;
142 // Look for the link to open the file with the app with |app_id|.
143 const ScopedVector<Link>& resource_links = resource_entry->links();
144 GURL open_link;
145 for (size_t i = 0; i < resource_links.size(); ++i) {
146 const Link& link = *resource_links[i];
147 if (link.type() == google_apis::Link::LINK_OPEN_WITH &&
148 link.app_id() == app_id) {
149 open_link = link.href();
150 break;
154 callback.Run(error, open_link);
157 } // namespace
159 //============================ GetResourceListOperation ========================
161 GetResourceListOperation::GetResourceListOperation(
162 OperationRegistry* registry,
163 net::URLRequestContextGetter* url_request_context_getter,
164 const GDataWapiUrlGenerator& url_generator,
165 const GURL& override_url,
166 int start_changestamp,
167 const std::string& search_string,
168 const std::string& directory_resource_id,
169 const GetResourceListCallback& callback)
170 : GetDataOperation(registry, url_request_context_getter,
171 base::Bind(&ParseResourceListAndRun, callback)),
172 url_generator_(url_generator),
173 override_url_(override_url),
174 start_changestamp_(start_changestamp),
175 search_string_(search_string),
176 directory_resource_id_(directory_resource_id) {
177 DCHECK(!callback.is_null());
180 GetResourceListOperation::~GetResourceListOperation() {}
182 GURL GetResourceListOperation::GetURL() const {
183 return url_generator_.GenerateResourceListUrl(override_url_,
184 start_changestamp_,
185 search_string_,
186 directory_resource_id_);
189 //============================ GetResourceEntryOperation =======================
191 GetResourceEntryOperation::GetResourceEntryOperation(
192 OperationRegistry* registry,
193 net::URLRequestContextGetter* url_request_context_getter,
194 const GDataWapiUrlGenerator& url_generator,
195 const std::string& resource_id,
196 const GetDataCallback& callback)
197 : GetDataOperation(registry, url_request_context_getter, callback),
198 url_generator_(url_generator),
199 resource_id_(resource_id) {
200 DCHECK(!callback.is_null());
203 GetResourceEntryOperation::~GetResourceEntryOperation() {}
205 GURL GetResourceEntryOperation::GetURL() const {
206 return url_generator_.GenerateEditUrl(resource_id_);
209 //========================= GetAccountMetadataOperation ========================
211 GetAccountMetadataOperation::GetAccountMetadataOperation(
212 OperationRegistry* registry,
213 net::URLRequestContextGetter* url_request_context_getter,
214 const GDataWapiUrlGenerator& url_generator,
215 const GetAccountMetadataCallback& callback,
216 bool include_installed_apps)
217 : GetDataOperation(registry, url_request_context_getter,
218 base::Bind(&ParseAccounetMetadataAndRun, callback)),
219 url_generator_(url_generator),
220 include_installed_apps_(include_installed_apps) {
221 DCHECK(!callback.is_null());
224 GetAccountMetadataOperation::~GetAccountMetadataOperation() {}
226 GURL GetAccountMetadataOperation::GetURL() const {
227 return url_generator_.GenerateAccountMetadataUrl(include_installed_apps_);
230 //=========================== DeleteResourceOperation ==========================
232 DeleteResourceOperation::DeleteResourceOperation(
233 OperationRegistry* registry,
234 net::URLRequestContextGetter* url_request_context_getter,
235 const GDataWapiUrlGenerator& url_generator,
236 const EntryActionCallback& callback,
237 const std::string& resource_id,
238 const std::string& etag)
239 : EntryActionOperation(registry, url_request_context_getter, callback),
240 url_generator_(url_generator),
241 resource_id_(resource_id),
242 etag_(etag) {
243 DCHECK(!callback.is_null());
246 DeleteResourceOperation::~DeleteResourceOperation() {}
248 GURL DeleteResourceOperation::GetURL() const {
249 return url_generator_.GenerateEditUrl(resource_id_);
252 URLFetcher::RequestType DeleteResourceOperation::GetRequestType() const {
253 return URLFetcher::DELETE_REQUEST;
256 std::vector<std::string>
257 DeleteResourceOperation::GetExtraRequestHeaders() const {
258 std::vector<std::string> headers;
259 headers.push_back(util::GenerateIfMatchHeader(etag_));
260 return headers;
263 //========================== CreateDirectoryOperation ==========================
265 CreateDirectoryOperation::CreateDirectoryOperation(
266 OperationRegistry* registry,
267 net::URLRequestContextGetter* url_request_context_getter,
268 const GDataWapiUrlGenerator& url_generator,
269 const GetDataCallback& callback,
270 const std::string& parent_resource_id,
271 const std::string& directory_name)
272 : GetDataOperation(registry, url_request_context_getter, callback),
273 url_generator_(url_generator),
274 parent_resource_id_(parent_resource_id),
275 directory_name_(directory_name) {
276 DCHECK(!callback.is_null());
279 CreateDirectoryOperation::~CreateDirectoryOperation() {}
281 GURL CreateDirectoryOperation::GetURL() const {
282 return url_generator_.GenerateContentUrl(parent_resource_id_);
285 URLFetcher::RequestType
286 CreateDirectoryOperation::GetRequestType() const {
287 return URLFetcher::POST;
290 bool CreateDirectoryOperation::GetContentData(std::string* upload_content_type,
291 std::string* upload_content) {
292 upload_content_type->assign("application/atom+xml");
293 XmlWriter xml_writer;
294 xml_writer.StartWriting();
295 xml_writer.StartElement("entry");
296 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
298 xml_writer.StartElement("category");
299 xml_writer.AddAttribute("scheme",
300 "http://schemas.google.com/g/2005#kind");
301 xml_writer.AddAttribute("term",
302 "http://schemas.google.com/docs/2007#folder");
303 xml_writer.EndElement(); // Ends "category" element.
305 xml_writer.WriteElement("title", directory_name_);
307 xml_writer.EndElement(); // Ends "entry" element.
308 xml_writer.StopWriting();
309 upload_content->assign(xml_writer.GetWrittenString());
310 DVLOG(1) << "CreateDirectory data: " << *upload_content_type << ", ["
311 << *upload_content << "]";
312 return true;
315 //============================ CopyHostedDocumentOperation =====================
317 CopyHostedDocumentOperation::CopyHostedDocumentOperation(
318 OperationRegistry* registry,
319 net::URLRequestContextGetter* url_request_context_getter,
320 const GDataWapiUrlGenerator& url_generator,
321 const GetDataCallback& callback,
322 const std::string& resource_id,
323 const std::string& new_name)
324 : GetDataOperation(registry, url_request_context_getter, callback),
325 url_generator_(url_generator),
326 resource_id_(resource_id),
327 new_name_(new_name) {
328 DCHECK(!callback.is_null());
331 CopyHostedDocumentOperation::~CopyHostedDocumentOperation() {}
333 URLFetcher::RequestType CopyHostedDocumentOperation::GetRequestType() const {
334 return URLFetcher::POST;
337 GURL CopyHostedDocumentOperation::GetURL() const {
338 return url_generator_.GenerateResourceListRootUrl();
341 bool CopyHostedDocumentOperation::GetContentData(
342 std::string* upload_content_type,
343 std::string* upload_content) {
344 upload_content_type->assign("application/atom+xml");
345 XmlWriter xml_writer;
346 xml_writer.StartWriting();
347 xml_writer.StartElement("entry");
348 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
350 xml_writer.WriteElement("id", resource_id_);
351 xml_writer.WriteElement("title", new_name_);
353 xml_writer.EndElement(); // Ends "entry" element.
354 xml_writer.StopWriting();
355 upload_content->assign(xml_writer.GetWrittenString());
356 DVLOG(1) << "CopyHostedDocumentOperation data: " << *upload_content_type
357 << ", [" << *upload_content << "]";
358 return true;
361 //=========================== RenameResourceOperation ==========================
363 RenameResourceOperation::RenameResourceOperation(
364 OperationRegistry* registry,
365 net::URLRequestContextGetter* url_request_context_getter,
366 const GDataWapiUrlGenerator& url_generator,
367 const EntryActionCallback& callback,
368 const std::string& resource_id,
369 const std::string& new_name)
370 : EntryActionOperation(registry, url_request_context_getter, callback),
371 url_generator_(url_generator),
372 resource_id_(resource_id),
373 new_name_(new_name) {
374 DCHECK(!callback.is_null());
377 RenameResourceOperation::~RenameResourceOperation() {}
379 URLFetcher::RequestType RenameResourceOperation::GetRequestType() const {
380 return URLFetcher::PUT;
383 std::vector<std::string>
384 RenameResourceOperation::GetExtraRequestHeaders() const {
385 std::vector<std::string> headers;
386 headers.push_back(util::kIfMatchAllHeader);
387 return headers;
390 GURL RenameResourceOperation::GetURL() const {
391 return url_generator_.GenerateEditUrl(resource_id_);
394 bool RenameResourceOperation::GetContentData(std::string* upload_content_type,
395 std::string* upload_content) {
396 upload_content_type->assign("application/atom+xml");
397 XmlWriter xml_writer;
398 xml_writer.StartWriting();
399 xml_writer.StartElement("entry");
400 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
402 xml_writer.WriteElement("title", new_name_);
404 xml_writer.EndElement(); // Ends "entry" element.
405 xml_writer.StopWriting();
406 upload_content->assign(xml_writer.GetWrittenString());
407 DVLOG(1) << "RenameResourceOperation data: " << *upload_content_type << ", ["
408 << *upload_content << "]";
409 return true;
412 //=========================== AuthorizeAppOperation ==========================
414 AuthorizeAppOperation::AuthorizeAppOperation(
415 OperationRegistry* registry,
416 net::URLRequestContextGetter* url_request_context_getter,
417 const GDataWapiUrlGenerator& url_generator,
418 const AuthorizeAppCallback& callback,
419 const std::string& resource_id,
420 const std::string& app_id)
421 : GetDataOperation(registry, url_request_context_getter,
422 base::Bind(&ParseOpenLinkAndRun, app_id, callback)),
423 url_generator_(url_generator),
424 resource_id_(resource_id),
425 app_id_(app_id) {
426 DCHECK(!callback.is_null());
429 AuthorizeAppOperation::~AuthorizeAppOperation() {}
431 URLFetcher::RequestType AuthorizeAppOperation::GetRequestType() const {
432 return URLFetcher::PUT;
435 std::vector<std::string>
436 AuthorizeAppOperation::GetExtraRequestHeaders() const {
437 std::vector<std::string> headers;
438 headers.push_back(util::kIfMatchAllHeader);
439 return headers;
442 bool AuthorizeAppOperation::GetContentData(std::string* upload_content_type,
443 std::string* upload_content) {
444 upload_content_type->assign("application/atom+xml");
445 XmlWriter xml_writer;
446 xml_writer.StartWriting();
447 xml_writer.StartElement("entry");
448 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
449 xml_writer.AddAttribute("xmlns:docs", "http://schemas.google.com/docs/2007");
450 xml_writer.WriteElement("docs:authorizedApp", app_id_);
452 xml_writer.EndElement(); // Ends "entry" element.
453 xml_writer.StopWriting();
454 upload_content->assign(xml_writer.GetWrittenString());
455 DVLOG(1) << "AuthorizeAppOperation data: " << *upload_content_type << ", ["
456 << *upload_content << "]";
457 return true;
460 GURL AuthorizeAppOperation::GetURL() const {
461 return url_generator_.GenerateEditUrl(resource_id_);
464 //======================= AddResourceToDirectoryOperation ======================
466 AddResourceToDirectoryOperation::AddResourceToDirectoryOperation(
467 OperationRegistry* registry,
468 net::URLRequestContextGetter* url_request_context_getter,
469 const GDataWapiUrlGenerator& url_generator,
470 const EntryActionCallback& callback,
471 const std::string& parent_resource_id,
472 const std::string& resource_id)
473 : EntryActionOperation(registry, url_request_context_getter, callback),
474 url_generator_(url_generator),
475 parent_resource_id_(parent_resource_id),
476 resource_id_(resource_id) {
477 DCHECK(!callback.is_null());
480 AddResourceToDirectoryOperation::~AddResourceToDirectoryOperation() {}
482 GURL AddResourceToDirectoryOperation::GetURL() const {
483 return url_generator_.GenerateContentUrl(parent_resource_id_);
486 URLFetcher::RequestType
487 AddResourceToDirectoryOperation::GetRequestType() const {
488 return URLFetcher::POST;
491 bool AddResourceToDirectoryOperation::GetContentData(
492 std::string* upload_content_type, std::string* upload_content) {
493 upload_content_type->assign("application/atom+xml");
494 XmlWriter xml_writer;
495 xml_writer.StartWriting();
496 xml_writer.StartElement("entry");
497 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
499 xml_writer.WriteElement(
500 "id", url_generator_.GenerateEditUrlWithoutParams(resource_id_).spec());
502 xml_writer.EndElement(); // Ends "entry" element.
503 xml_writer.StopWriting();
504 upload_content->assign(xml_writer.GetWrittenString());
505 DVLOG(1) << "AddResourceToDirectoryOperation data: " << *upload_content_type
506 << ", [" << *upload_content << "]";
507 return true;
510 //==================== RemoveResourceFromDirectoryOperation ====================
512 RemoveResourceFromDirectoryOperation::RemoveResourceFromDirectoryOperation(
513 OperationRegistry* registry,
514 net::URLRequestContextGetter* url_request_context_getter,
515 const GDataWapiUrlGenerator& url_generator,
516 const EntryActionCallback& callback,
517 const std::string& parent_resource_id,
518 const std::string& document_resource_id)
519 : EntryActionOperation(registry, url_request_context_getter, callback),
520 url_generator_(url_generator),
521 resource_id_(document_resource_id),
522 parent_resource_id_(parent_resource_id) {
523 DCHECK(!callback.is_null());
526 RemoveResourceFromDirectoryOperation::~RemoveResourceFromDirectoryOperation() {
529 GURL RemoveResourceFromDirectoryOperation::GetURL() const {
530 return url_generator_.GenerateResourceUrlForRemoval(
531 parent_resource_id_, resource_id_);
534 URLFetcher::RequestType
535 RemoveResourceFromDirectoryOperation::GetRequestType() const {
536 return URLFetcher::DELETE_REQUEST;
539 std::vector<std::string>
540 RemoveResourceFromDirectoryOperation::GetExtraRequestHeaders() const {
541 std::vector<std::string> headers;
542 headers.push_back(util::kIfMatchAllHeader);
543 return headers;
546 //======================= InitiateUploadNewFileOperation =======================
548 InitiateUploadNewFileOperation::InitiateUploadNewFileOperation(
549 OperationRegistry* registry,
550 net::URLRequestContextGetter* url_request_context_getter,
551 const GDataWapiUrlGenerator& url_generator,
552 const InitiateUploadCallback& callback,
553 const base::FilePath& drive_file_path,
554 const std::string& content_type,
555 int64 content_length,
556 const std::string& parent_resource_id,
557 const std::string& title)
558 : InitiateUploadOperationBase(registry,
559 url_request_context_getter,
560 callback,
561 drive_file_path,
562 content_type,
563 content_length),
564 url_generator_(url_generator),
565 parent_resource_id_(parent_resource_id),
566 title_(title) {
569 InitiateUploadNewFileOperation::~InitiateUploadNewFileOperation() {}
571 GURL InitiateUploadNewFileOperation::GetURL() const {
572 return url_generator_.GenerateInitiateUploadNewFileUrl(parent_resource_id_);
575 net::URLFetcher::RequestType
576 InitiateUploadNewFileOperation::GetRequestType() const {
577 return net::URLFetcher::POST;
580 bool InitiateUploadNewFileOperation::GetContentData(
581 std::string* upload_content_type,
582 std::string* upload_content) {
583 upload_content_type->assign("application/atom+xml");
584 XmlWriter xml_writer;
585 xml_writer.StartWriting();
586 xml_writer.StartElement("entry");
587 xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
588 xml_writer.AddAttribute("xmlns:docs",
589 "http://schemas.google.com/docs/2007");
590 xml_writer.WriteElement("title", title_);
591 xml_writer.EndElement(); // Ends "entry" element.
592 xml_writer.StopWriting();
593 upload_content->assign(xml_writer.GetWrittenString());
594 DVLOG(1) << "InitiateUploadNewFile: " << *upload_content_type << ", ["
595 << *upload_content << "]";
596 return true;
599 //===================== InitiateUploadExistingFileOperation ====================
601 InitiateUploadExistingFileOperation::InitiateUploadExistingFileOperation(
602 OperationRegistry* registry,
603 net::URLRequestContextGetter* url_request_context_getter,
604 const GDataWapiUrlGenerator& url_generator,
605 const InitiateUploadCallback& callback,
606 const base::FilePath& drive_file_path,
607 const std::string& content_type,
608 int64 content_length,
609 const std::string& resource_id,
610 const std::string& etag)
611 : InitiateUploadOperationBase(registry,
612 url_request_context_getter,
613 callback,
614 drive_file_path,
615 content_type,
616 content_length),
617 url_generator_(url_generator),
618 resource_id_(resource_id),
619 etag_(etag) {
622 InitiateUploadExistingFileOperation::~InitiateUploadExistingFileOperation() {}
624 GURL InitiateUploadExistingFileOperation::GetURL() const {
625 return url_generator_.GenerateInitiateUploadExistingFileUrl(resource_id_);
628 net::URLFetcher::RequestType
629 InitiateUploadExistingFileOperation::GetRequestType() const {
630 return net::URLFetcher::PUT;
633 bool InitiateUploadExistingFileOperation::GetContentData(
634 std::string* upload_content_type,
635 std::string* upload_content) {
636 // According to the document there is no need to send the content-type.
637 // However, the server would return 500 server error without the
638 // content-type.
639 // As its workaround, send "text/plain" content-type here.
640 *upload_content_type = "text/plain";
641 *upload_content = "";
642 return true;
645 std::vector<std::string>
646 InitiateUploadExistingFileOperation::GetExtraRequestHeaders() const {
647 std::vector<std::string> headers(
648 InitiateUploadOperationBase::GetExtraRequestHeaders());
649 headers.push_back(util::GenerateIfMatchHeader(etag_));
650 return headers;
653 //============================ ResumeUploadOperation ===========================
655 ResumeUploadOperation::ResumeUploadOperation(
656 OperationRegistry* registry,
657 net::URLRequestContextGetter* url_request_context_getter,
658 const UploadRangeCallback& callback,
659 const ProgressCallback& progress_callback,
660 UploadMode upload_mode,
661 const base::FilePath& drive_file_path,
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 scoped_refptr<net::IOBuffer>& buf)
668 : ResumeUploadOperationBase(registry,
669 url_request_context_getter,
670 upload_mode,
671 drive_file_path,
672 upload_location,
673 start_position,
674 end_position,
675 content_length,
676 content_type,
677 buf),
678 callback_(callback),
679 progress_callback_(progress_callback) {
680 DCHECK(!callback_.is_null());
683 ResumeUploadOperation::~ResumeUploadOperation() {}
685 void ResumeUploadOperation::OnRangeOperationComplete(
686 const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
687 callback_.Run(response, ParseResourceEntry(value.Pass()));
690 void ResumeUploadOperation::OnURLFetchUploadProgress(
691 const URLFetcher* source, int64 current, int64 total) {
692 ResumeUploadOperationBase::OnURLFetchUploadProgress(source, current, total);
693 if (!progress_callback_.is_null())
694 progress_callback_.Run(current, total);
697 //========================== GetUploadStatusOperation ==========================
699 GetUploadStatusOperation::GetUploadStatusOperation(
700 OperationRegistry* registry,
701 net::URLRequestContextGetter* url_request_context_getter,
702 const UploadRangeCallback& callback,
703 UploadMode upload_mode,
704 const base::FilePath& drive_file_path,
705 const GURL& upload_url,
706 int64 content_length)
707 : UploadRangeOperationBase(registry,
708 url_request_context_getter,
709 upload_mode,
710 drive_file_path,
711 upload_url),
712 callback_(callback),
713 content_length_(content_length) {}
715 GetUploadStatusOperation::~GetUploadStatusOperation() {}
717 std::vector<std::string>
718 GetUploadStatusOperation::GetExtraRequestHeaders() const {
719 // The header looks like
720 // Content-Range: bytes */<content_length>
721 // for example:
722 // Content-Range: bytes */13851821
723 DCHECK_GE(content_length_, 0);
725 std::vector<std::string> headers;
726 headers.push_back(
727 std::string(kUploadContentRange) + "*/" +
728 base::Int64ToString(content_length_));
729 return headers;
732 void GetUploadStatusOperation::OnRangeOperationComplete(
733 const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
734 callback_.Run(response, ParseResourceEntry(value.Pass()));
737 } // namespace google_apis