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/request_sender.h" 15 #include "google_apis/drive/request_util.h" 16 #include "google_apis/drive/time_util.h" 17 #include "net/base/url_util.h" 18 19 namespace google_apis { 20 namespace { 21 22 const char kContentTypeApplicationJson[] = "application/json"; 23 const char kParentLinkKind[] = "drive#fileLink"; 24 25 // Parses the JSON value to FileResource instance and runs |callback| on the 26 // UI thread once parsing is done. 27 // This is customized version of ParseJsonAndRun defined above to adapt the 28 // remaining response type. 29 void ParseFileResourceWithUploadRangeAndRun( 30 const drive::UploadRangeCallback& callback, 31 const UploadRangeResponse& response, 32 scoped_ptr<base::Value> value) { 33 DCHECK(!callback.is_null()); 34 35 scoped_ptr<FileResource> file_resource; 36 if (value) { 37 file_resource = FileResource::CreateFrom(*value); 38 if (!file_resource) { 39 callback.Run( 40 UploadRangeResponse(GDATA_PARSE_ERROR, 41 response.start_position_received, 42 response.end_position_received), 43 scoped_ptr<FileResource>()); 44 return; 45 } 46 } 47 48 callback.Run(response, file_resource.Pass()); 49 } 50 51 // Creates a Parents value which can be used as a part of request body. 52 scoped_ptr<base::DictionaryValue> CreateParentValue( 53 const std::string& file_id) { 54 scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue); 55 parent->SetString("kind", kParentLinkKind); 56 parent->SetString("id", file_id); 57 return parent.Pass(); 58 } 59 60 } // namespace 61 62 namespace drive { 63 64 //============================ DriveApiPartialFieldRequest ==================== 65 66 DriveApiPartialFieldRequest::DriveApiPartialFieldRequest( 67 RequestSender* sender) : UrlFetchRequestBase(sender) { 68 } 69 70 DriveApiPartialFieldRequest::~DriveApiPartialFieldRequest() { 71 } 72 73 GURL DriveApiPartialFieldRequest::GetURL() const { 74 GURL url = GetURLInternal(); 75 if (!fields_.empty()) 76 url = net::AppendOrReplaceQueryParameter(url, "fields", fields_); 77 return url; 78 } 79 80 //=============================== FilesGetRequest ============================= 81 82 FilesGetRequest::FilesGetRequest( 83 RequestSender* sender, 84 const DriveApiUrlGenerator& url_generator, 85 const FileResourceCallback& callback) 86 : DriveApiDataRequest<FileResource>(sender, callback), 87 url_generator_(url_generator) { 88 DCHECK(!callback.is_null()); 89 } 90 91 FilesGetRequest::~FilesGetRequest() {} 92 93 GURL FilesGetRequest::GetURLInternal() const { 94 return url_generator_.GetFilesGetUrl(file_id_); 95 } 96 97 //============================ FilesAuthorizeRequest =========================== 98 99 FilesAuthorizeRequest::FilesAuthorizeRequest( 100 RequestSender* sender, 101 const DriveApiUrlGenerator& url_generator, 102 const FileResourceCallback& callback) 103 : DriveApiDataRequest<FileResource>(sender, callback), 104 url_generator_(url_generator) { 105 DCHECK(!callback.is_null()); 106 } 107 108 FilesAuthorizeRequest::~FilesAuthorizeRequest() {} 109 110 net::URLFetcher::RequestType FilesAuthorizeRequest::GetRequestType() const { 111 return net::URLFetcher::POST; 112 } 113 114 GURL FilesAuthorizeRequest::GetURLInternal() const { 115 return url_generator_.GetFilesAuthorizeUrl(file_id_, app_id_); 116 } 117 118 //============================ FilesInsertRequest ============================ 119 120 FilesInsertRequest::FilesInsertRequest( 121 RequestSender* sender, 122 const DriveApiUrlGenerator& url_generator, 123 const FileResourceCallback& callback) 124 : DriveApiDataRequest<FileResource>(sender, callback), 125 url_generator_(url_generator) { 126 DCHECK(!callback.is_null()); 127 } 128 129 FilesInsertRequest::~FilesInsertRequest() {} 130 131 net::URLFetcher::RequestType FilesInsertRequest::GetRequestType() const { 132 return net::URLFetcher::POST; 133 } 134 135 bool FilesInsertRequest::GetContentData(std::string* upload_content_type, 136 std::string* upload_content) { 137 *upload_content_type = kContentTypeApplicationJson; 138 139 base::DictionaryValue root; 140 141 if (!last_viewed_by_me_date_.is_null()) { 142 root.SetString("lastViewedByMeDate", 143 util::FormatTimeAsString(last_viewed_by_me_date_)); 144 } 145 146 if (!mime_type_.empty()) 147 root.SetString("mimeType", mime_type_); 148 149 if (!modified_date_.is_null()) 150 root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_)); 151 152 if (!parents_.empty()) { 153 base::ListValue* parents_value = new base::ListValue; 154 for (size_t i = 0; i < parents_.size(); ++i) { 155 base::DictionaryValue* parent = new base::DictionaryValue; 156 parent->SetString("id", parents_[i]); 157 parents_value->Append(parent); 158 } 159 root.Set("parents", parents_value); 160 } 161 162 if (!title_.empty()) 163 root.SetString("title", title_); 164 165 base::JSONWriter::Write(&root, upload_content); 166 DVLOG(1) << "FilesInsert data: " << *upload_content_type << ", [" 167 << *upload_content << "]"; 168 return true; 169 } 170 171 GURL FilesInsertRequest::GetURLInternal() const { 172 return url_generator_.GetFilesInsertUrl(); 173 } 174 175 //============================== FilesPatchRequest ============================ 176 177 FilesPatchRequest::FilesPatchRequest( 178 RequestSender* sender, 179 const DriveApiUrlGenerator& url_generator, 180 const FileResourceCallback& callback) 181 : DriveApiDataRequest<FileResource>(sender, callback), 182 url_generator_(url_generator), 183 set_modified_date_(false), 184 update_viewed_date_(true) { 185 DCHECK(!callback.is_null()); 186 } 187 188 FilesPatchRequest::~FilesPatchRequest() {} 189 190 net::URLFetcher::RequestType FilesPatchRequest::GetRequestType() const { 191 return net::URLFetcher::PATCH; 192 } 193 194 std::vector<std::string> FilesPatchRequest::GetExtraRequestHeaders() const { 195 std::vector<std::string> headers; 196 headers.push_back(util::kIfMatchAllHeader); 197 return headers; 198 } 199 200 GURL FilesPatchRequest::GetURLInternal() const { 201 return url_generator_.GetFilesPatchUrl( 202 file_id_, set_modified_date_, update_viewed_date_); 203 } 204 205 bool FilesPatchRequest::GetContentData(std::string* upload_content_type, 206 std::string* upload_content) { 207 if (title_.empty() && 208 modified_date_.is_null() && 209 last_viewed_by_me_date_.is_null() && 210 parents_.empty()) 211 return false; 212 213 *upload_content_type = kContentTypeApplicationJson; 214 215 base::DictionaryValue root; 216 if (!title_.empty()) 217 root.SetString("title", title_); 218 219 if (!modified_date_.is_null()) 220 root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_)); 221 222 if (!last_viewed_by_me_date_.is_null()) { 223 root.SetString("lastViewedByMeDate", 224 util::FormatTimeAsString(last_viewed_by_me_date_)); 225 } 226 227 if (!parents_.empty()) { 228 base::ListValue* parents_value = new base::ListValue; 229 for (size_t i = 0; i < parents_.size(); ++i) { 230 base::DictionaryValue* parent = new base::DictionaryValue; 231 parent->SetString("id", parents_[i]); 232 parents_value->Append(parent); 233 } 234 root.Set("parents", parents_value); 235 } 236 237 base::JSONWriter::Write(&root, upload_content); 238 DVLOG(1) << "FilesPatch data: " << *upload_content_type << ", [" 239 << *upload_content << "]"; 240 return true; 241 } 242 243 //============================= FilesCopyRequest ============================== 244 245 FilesCopyRequest::FilesCopyRequest( 246 RequestSender* sender, 247 const DriveApiUrlGenerator& url_generator, 248 const FileResourceCallback& callback) 249 : DriveApiDataRequest<FileResource>(sender, callback), 250 url_generator_(url_generator) { 251 DCHECK(!callback.is_null()); 252 } 253 254 FilesCopyRequest::~FilesCopyRequest() { 255 } 256 257 net::URLFetcher::RequestType FilesCopyRequest::GetRequestType() const { 258 return net::URLFetcher::POST; 259 } 260 261 GURL FilesCopyRequest::GetURLInternal() const { 262 return url_generator_.GetFilesCopyUrl(file_id_); 263 } 264 265 bool FilesCopyRequest::GetContentData(std::string* upload_content_type, 266 std::string* upload_content) { 267 if (parents_.empty() && title_.empty()) 268 return false; 269 270 *upload_content_type = kContentTypeApplicationJson; 271 272 base::DictionaryValue root; 273 274 if (!modified_date_.is_null()) 275 root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_)); 276 277 if (!parents_.empty()) { 278 base::ListValue* parents_value = new base::ListValue; 279 for (size_t i = 0; i < parents_.size(); ++i) { 280 base::DictionaryValue* parent = new base::DictionaryValue; 281 parent->SetString("id", parents_[i]); 282 parents_value->Append(parent); 283 } 284 root.Set("parents", parents_value); 285 } 286 287 if (!title_.empty()) 288 root.SetString("title", title_); 289 290 base::JSONWriter::Write(&root, upload_content); 291 DVLOG(1) << "FilesCopy data: " << *upload_content_type << ", [" 292 << *upload_content << "]"; 293 return true; 294 } 295 296 //============================= FilesListRequest ============================= 297 298 FilesListRequest::FilesListRequest( 299 RequestSender* sender, 300 const DriveApiUrlGenerator& url_generator, 301 const FileListCallback& callback) 302 : DriveApiDataRequest<FileList>(sender, callback), 303 url_generator_(url_generator), 304 max_results_(100) { 305 DCHECK(!callback.is_null()); 306 } 307 308 FilesListRequest::~FilesListRequest() {} 309 310 GURL FilesListRequest::GetURLInternal() const { 311 return url_generator_.GetFilesListUrl(max_results_, page_token_, q_); 312 } 313 314 //======================== FilesListNextPageRequest ========================= 315 316 FilesListNextPageRequest::FilesListNextPageRequest( 317 RequestSender* sender, 318 const FileListCallback& callback) 319 : DriveApiDataRequest<FileList>(sender, callback) { 320 DCHECK(!callback.is_null()); 321 } 322 323 FilesListNextPageRequest::~FilesListNextPageRequest() { 324 } 325 326 GURL FilesListNextPageRequest::GetURLInternal() const { 327 return next_link_; 328 } 329 330 //============================ FilesDeleteRequest ============================= 331 332 FilesDeleteRequest::FilesDeleteRequest( 333 RequestSender* sender, 334 const DriveApiUrlGenerator& url_generator, 335 const EntryActionCallback& callback) 336 : EntryActionRequest(sender, callback), 337 url_generator_(url_generator) { 338 DCHECK(!callback.is_null()); 339 } 340 341 FilesDeleteRequest::~FilesDeleteRequest() {} 342 343 net::URLFetcher::RequestType FilesDeleteRequest::GetRequestType() const { 344 return net::URLFetcher::DELETE_REQUEST; 345 } 346 347 GURL FilesDeleteRequest::GetURL() const { 348 return url_generator_.GetFilesDeleteUrl(file_id_); 349 } 350 351 std::vector<std::string> FilesDeleteRequest::GetExtraRequestHeaders() const { 352 std::vector<std::string> headers( 353 EntryActionRequest::GetExtraRequestHeaders()); 354 headers.push_back(util::GenerateIfMatchHeader(etag_)); 355 return headers; 356 } 357 358 //============================ FilesTrashRequest ============================= 359 360 FilesTrashRequest::FilesTrashRequest( 361 RequestSender* sender, 362 const DriveApiUrlGenerator& url_generator, 363 const FileResourceCallback& callback) 364 : DriveApiDataRequest<FileResource>(sender, callback), 365 url_generator_(url_generator) { 366 DCHECK(!callback.is_null()); 367 } 368 369 FilesTrashRequest::~FilesTrashRequest() {} 370 371 net::URLFetcher::RequestType FilesTrashRequest::GetRequestType() const { 372 return net::URLFetcher::POST; 373 } 374 375 GURL FilesTrashRequest::GetURLInternal() const { 376 return url_generator_.GetFilesTrashUrl(file_id_); 377 } 378 379 //============================== AboutGetRequest ============================= 380 381 AboutGetRequest::AboutGetRequest( 382 RequestSender* sender, 383 const DriveApiUrlGenerator& url_generator, 384 const AboutResourceCallback& callback) 385 : DriveApiDataRequest<AboutResource>(sender, callback), 386 url_generator_(url_generator) { 387 DCHECK(!callback.is_null()); 388 } 389 390 AboutGetRequest::~AboutGetRequest() {} 391 392 GURL AboutGetRequest::GetURLInternal() const { 393 return url_generator_.GetAboutGetUrl(); 394 } 395 396 //============================ ChangesListRequest =========================== 397 398 ChangesListRequest::ChangesListRequest( 399 RequestSender* sender, 400 const DriveApiUrlGenerator& url_generator, 401 const ChangeListCallback& callback) 402 : DriveApiDataRequest<ChangeList>(sender, callback), 403 url_generator_(url_generator), 404 include_deleted_(true), 405 max_results_(100), 406 start_change_id_(0) { 407 DCHECK(!callback.is_null()); 408 } 409 410 ChangesListRequest::~ChangesListRequest() {} 411 412 GURL ChangesListRequest::GetURLInternal() const { 413 return url_generator_.GetChangesListUrl( 414 include_deleted_, max_results_, page_token_, start_change_id_); 415 } 416 417 //======================== ChangesListNextPageRequest ========================= 418 419 ChangesListNextPageRequest::ChangesListNextPageRequest( 420 RequestSender* sender, 421 const ChangeListCallback& callback) 422 : DriveApiDataRequest<ChangeList>(sender, callback) { 423 DCHECK(!callback.is_null()); 424 } 425 426 ChangesListNextPageRequest::~ChangesListNextPageRequest() { 427 } 428 429 GURL ChangesListNextPageRequest::GetURLInternal() const { 430 return next_link_; 431 } 432 433 //============================== AppsListRequest =========================== 434 435 AppsListRequest::AppsListRequest( 436 RequestSender* sender, 437 const DriveApiUrlGenerator& url_generator, 438 bool use_internal_endpoint, 439 const AppListCallback& callback) 440 : DriveApiDataRequest<AppList>(sender, callback), 441 url_generator_(url_generator), 442 use_internal_endpoint_(use_internal_endpoint) { 443 DCHECK(!callback.is_null()); 444 } 445 446 AppsListRequest::~AppsListRequest() {} 447 448 GURL AppsListRequest::GetURLInternal() const { 449 return url_generator_.GetAppsListUrl(use_internal_endpoint_); 450 } 451 452 //============================== AppsDeleteRequest =========================== 453 454 AppsDeleteRequest::AppsDeleteRequest(RequestSender* sender, 455 const DriveApiUrlGenerator& url_generator, 456 const EntryActionCallback& callback) 457 : EntryActionRequest(sender, callback), 458 url_generator_(url_generator) { 459 DCHECK(!callback.is_null()); 460 } 461 462 AppsDeleteRequest::~AppsDeleteRequest() {} 463 464 net::URLFetcher::RequestType AppsDeleteRequest::GetRequestType() const { 465 return net::URLFetcher::DELETE_REQUEST; 466 } 467 468 GURL AppsDeleteRequest::GetURL() const { 469 return url_generator_.GetAppsDeleteUrl(app_id_); 470 } 471 472 //========================== ChildrenInsertRequest ============================ 473 474 ChildrenInsertRequest::ChildrenInsertRequest( 475 RequestSender* sender, 476 const DriveApiUrlGenerator& url_generator, 477 const EntryActionCallback& callback) 478 : EntryActionRequest(sender, callback), 479 url_generator_(url_generator) { 480 DCHECK(!callback.is_null()); 481 } 482 483 ChildrenInsertRequest::~ChildrenInsertRequest() {} 484 485 net::URLFetcher::RequestType ChildrenInsertRequest::GetRequestType() const { 486 return net::URLFetcher::POST; 487 } 488 489 GURL ChildrenInsertRequest::GetURL() const { 490 return url_generator_.GetChildrenInsertUrl(folder_id_); 491 } 492 493 bool ChildrenInsertRequest::GetContentData(std::string* upload_content_type, 494 std::string* upload_content) { 495 *upload_content_type = kContentTypeApplicationJson; 496 497 base::DictionaryValue root; 498 root.SetString("id", id_); 499 500 base::JSONWriter::Write(&root, upload_content); 501 DVLOG(1) << "InsertResource data: " << *upload_content_type << ", [" 502 << *upload_content << "]"; 503 return true; 504 } 505 506 //========================== ChildrenDeleteRequest ============================ 507 508 ChildrenDeleteRequest::ChildrenDeleteRequest( 509 RequestSender* sender, 510 const DriveApiUrlGenerator& url_generator, 511 const EntryActionCallback& callback) 512 : EntryActionRequest(sender, callback), 513 url_generator_(url_generator) { 514 DCHECK(!callback.is_null()); 515 } 516 517 ChildrenDeleteRequest::~ChildrenDeleteRequest() {} 518 519 net::URLFetcher::RequestType ChildrenDeleteRequest::GetRequestType() const { 520 return net::URLFetcher::DELETE_REQUEST; 521 } 522 523 GURL ChildrenDeleteRequest::GetURL() const { 524 return url_generator_.GetChildrenDeleteUrl(child_id_, folder_id_); 525 } 526 527 //======================= InitiateUploadNewFileRequest ======================= 528 529 InitiateUploadNewFileRequest::InitiateUploadNewFileRequest( 530 RequestSender* sender, 531 const DriveApiUrlGenerator& url_generator, 532 const std::string& content_type, 533 int64 content_length, 534 const std::string& parent_resource_id, 535 const std::string& title, 536 const InitiateUploadCallback& callback) 537 : InitiateUploadRequestBase(sender, 538 callback, 539 content_type, 540 content_length), 541 url_generator_(url_generator), 542 parent_resource_id_(parent_resource_id), 543 title_(title) { 544 } 545 546 InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {} 547 548 GURL InitiateUploadNewFileRequest::GetURL() const { 549 return url_generator_.GetInitiateUploadNewFileUrl(!modified_date_.is_null()); 550 } 551 552 net::URLFetcher::RequestType 553 InitiateUploadNewFileRequest::GetRequestType() const { 554 return net::URLFetcher::POST; 555 } 556 557 bool InitiateUploadNewFileRequest::GetContentData( 558 std::string* upload_content_type, 559 std::string* upload_content) { 560 *upload_content_type = kContentTypeApplicationJson; 561 562 base::DictionaryValue root; 563 root.SetString("title", title_); 564 565 // Fill parent link. 566 scoped_ptr<base::ListValue> parents(new base::ListValue); 567 parents->Append(CreateParentValue(parent_resource_id_).release()); 568 root.Set("parents", parents.release()); 569 570 if (!modified_date_.is_null()) 571 root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_)); 572 573 if (!last_viewed_by_me_date_.is_null()) { 574 root.SetString("lastViewedByMeDate", 575 util::FormatTimeAsString(last_viewed_by_me_date_)); 576 } 577 578 base::JSONWriter::Write(&root, upload_content); 579 580 DVLOG(1) << "InitiateUploadNewFile data: " << *upload_content_type << ", [" 581 << *upload_content << "]"; 582 return true; 583 } 584 585 //===================== InitiateUploadExistingFileRequest ==================== 586 587 InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest( 588 RequestSender* sender, 589 const DriveApiUrlGenerator& url_generator, 590 const std::string& content_type, 591 int64 content_length, 592 const std::string& resource_id, 593 const std::string& etag, 594 const InitiateUploadCallback& callback) 595 : InitiateUploadRequestBase(sender, 596 callback, 597 content_type, 598 content_length), 599 url_generator_(url_generator), 600 resource_id_(resource_id), 601 etag_(etag) { 602 } 603 604 InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {} 605 606 GURL InitiateUploadExistingFileRequest::GetURL() const { 607 return url_generator_.GetInitiateUploadExistingFileUrl( 608 resource_id_, !modified_date_.is_null()); 609 } 610 611 net::URLFetcher::RequestType 612 InitiateUploadExistingFileRequest::GetRequestType() const { 613 return net::URLFetcher::PUT; 614 } 615 616 std::vector<std::string> 617 InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const { 618 std::vector<std::string> headers( 619 InitiateUploadRequestBase::GetExtraRequestHeaders()); 620 headers.push_back(util::GenerateIfMatchHeader(etag_)); 621 return headers; 622 } 623 624 bool InitiateUploadExistingFileRequest::GetContentData( 625 std::string* upload_content_type, 626 std::string* upload_content) { 627 base::DictionaryValue root; 628 if (!parent_resource_id_.empty()) { 629 scoped_ptr<base::ListValue> parents(new base::ListValue); 630 parents->Append(CreateParentValue(parent_resource_id_).release()); 631 root.Set("parents", parents.release()); 632 } 633 634 if (!title_.empty()) 635 root.SetString("title", title_); 636 637 if (!modified_date_.is_null()) 638 root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_)); 639 640 if (!last_viewed_by_me_date_.is_null()) { 641 root.SetString("lastViewedByMeDate", 642 util::FormatTimeAsString(last_viewed_by_me_date_)); 643 } 644 645 if (root.empty()) 646 return false; 647 648 *upload_content_type = kContentTypeApplicationJson; 649 base::JSONWriter::Write(&root, upload_content); 650 DVLOG(1) << "InitiateUploadExistingFile data: " << *upload_content_type 651 << ", [" << *upload_content << "]"; 652 return true; 653 } 654 655 //============================ ResumeUploadRequest =========================== 656 657 ResumeUploadRequest::ResumeUploadRequest( 658 RequestSender* sender, 659 const GURL& upload_location, 660 int64 start_position, 661 int64 end_position, 662 int64 content_length, 663 const std::string& content_type, 664 const base::FilePath& local_file_path, 665 const UploadRangeCallback& callback, 666 const ProgressCallback& progress_callback) 667 : ResumeUploadRequestBase(sender, 668 upload_location, 669 start_position, 670 end_position, 671 content_length, 672 content_type, 673 local_file_path), 674 callback_(callback), 675 progress_callback_(progress_callback) { 676 DCHECK(!callback_.is_null()); 677 } 678 679 ResumeUploadRequest::~ResumeUploadRequest() {} 680 681 void ResumeUploadRequest::OnRangeRequestComplete( 682 const UploadRangeResponse& response, 683 scoped_ptr<base::Value> value) { 684 DCHECK(CalledOnValidThread()); 685 ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass()); 686 } 687 688 void ResumeUploadRequest::OnURLFetchUploadProgress( 689 const net::URLFetcher* source, int64 current, int64 total) { 690 if (!progress_callback_.is_null()) 691 progress_callback_.Run(current, total); 692 } 693 694 //========================== GetUploadStatusRequest ========================== 695 696 GetUploadStatusRequest::GetUploadStatusRequest( 697 RequestSender* sender, 698 const GURL& upload_url, 699 int64 content_length, 700 const UploadRangeCallback& callback) 701 : GetUploadStatusRequestBase(sender, 702 upload_url, 703 content_length), 704 callback_(callback) { 705 DCHECK(!callback.is_null()); 706 } 707 708 GetUploadStatusRequest::~GetUploadStatusRequest() {} 709 710 void GetUploadStatusRequest::OnRangeRequestComplete( 711 const UploadRangeResponse& response, 712 scoped_ptr<base::Value> value) { 713 DCHECK(CalledOnValidThread()); 714 ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass()); 715 } 716 717 //========================== DownloadFileRequest ========================== 718 719 DownloadFileRequest::DownloadFileRequest( 720 RequestSender* sender, 721 const DriveApiUrlGenerator& url_generator, 722 const std::string& resource_id, 723 const base::FilePath& output_file_path, 724 const DownloadActionCallback& download_action_callback, 725 const GetContentCallback& get_content_callback, 726 const ProgressCallback& progress_callback) 727 : DownloadFileRequestBase( 728 sender, 729 download_action_callback, 730 get_content_callback, 731 progress_callback, 732 url_generator.GenerateDownloadFileUrl(resource_id), 733 output_file_path) { 734 } 735 736 DownloadFileRequest::~DownloadFileRequest() { 737 } 738 739 //========================== PermissionsInsertRequest ========================== 740 741 PermissionsInsertRequest::PermissionsInsertRequest( 742 RequestSender* sender, 743 const DriveApiUrlGenerator& url_generator, 744 const EntryActionCallback& callback) 745 : EntryActionRequest(sender, callback), 746 url_generator_(url_generator), 747 type_(PERMISSION_TYPE_USER), 748 role_(PERMISSION_ROLE_READER) { 749 } 750 751 PermissionsInsertRequest::~PermissionsInsertRequest() { 752 } 753 754 GURL PermissionsInsertRequest::GetURL() const { 755 return url_generator_.GetPermissionsInsertUrl(id_); 756 } 757 758 net::URLFetcher::RequestType 759 PermissionsInsertRequest::GetRequestType() const { 760 return net::URLFetcher::POST; 761 } 762 763 bool PermissionsInsertRequest::GetContentData(std::string* upload_content_type, 764 std::string* upload_content) { 765 *upload_content_type = kContentTypeApplicationJson; 766 767 base::DictionaryValue root; 768 switch (type_) { 769 case PERMISSION_TYPE_ANYONE: 770 root.SetString("type", "anyone"); 771 break; 772 case PERMISSION_TYPE_DOMAIN: 773 root.SetString("type", "domain"); 774 break; 775 case PERMISSION_TYPE_GROUP: 776 root.SetString("type", "group"); 777 break; 778 case PERMISSION_TYPE_USER: 779 root.SetString("type", "user"); 780 break; 781 } 782 switch (role_) { 783 case PERMISSION_ROLE_OWNER: 784 root.SetString("role", "owner"); 785 break; 786 case PERMISSION_ROLE_READER: 787 root.SetString("role", "reader"); 788 break; 789 case PERMISSION_ROLE_WRITER: 790 root.SetString("role", "writer"); 791 break; 792 case PERMISSION_ROLE_COMMENTER: 793 root.SetString("role", "reader"); 794 { 795 base::ListValue* list = new base::ListValue; 796 list->AppendString("commenter"); 797 root.Set("additionalRoles", list); 798 } 799 break; 800 } 801 root.SetString("value", value_); 802 base::JSONWriter::Write(&root, upload_content); 803 return true; 804 } 805 806 } // namespace drive 807 } // namespace google_apis 808