| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/privet_http_impl.h" | 5 #include "chrome/browser/local_discovery/privet_http_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "chrome/browser/local_discovery/privet_constants.h" | 10 #include "chrome/browser/local_discovery/privet_constants.h" |
| 11 #include "net/base/url_util.h" | 11 #include "net/base/url_util.h" |
| 12 #include "url/gurl.h" | 12 #include "url/gurl.h" |
| 13 | 13 |
| 14 namespace local_discovery { | 14 namespace local_discovery { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 const char kUrlPlaceHolder[] = "http://host/"; | 17 const char kUrlPlaceHolder[] = "http://host/"; |
| 18 const char kPrivetRegisterActionArgName[] = "action"; | 18 const char kPrivetRegisterActionArgName[] = "action"; |
| 19 const char kPrivetRegisterUserArgName[] = "user"; | 19 const char kPrivetRegisterUserArgName[] = "user"; |
| 20 | 20 |
| 21 const char kPrivetURLKeyUser[] = "user"; | 21 const char kPrivetURLKeyUser[] = "user"; |
| 22 const char kPrivetURLKeyJobname[] = "jobname"; | 22 const char kPrivetURLKeyJobname[] = "jobname"; |
| 23 const char kPrivetURLKeyOffline[] = "offline"; | 23 const char kPrivetURLKeyOffline[] = "offline"; |
| 24 const char kPrivetURLValueOffline[] = "1"; | 24 const char kPrivetURLValueOffline[] = "1"; |
| 25 | 25 |
| 26 const char kPrivetContentTypePDF[] = "application/pdf"; | 26 const char kPrivetContentTypePDF[] = "application/pdf"; |
| 27 const char kPrivetContentTypePWGRaster[] = "image/pwg-raster"; | 27 const char kPrivetContentTypePWGRaster[] = "image/pwg-raster"; |
| 28 const char kPrivetContentTypeCJT[] = "application/json"; |
| 28 | 29 |
| 29 const char kPrivetCDDKeySupportedContentTypes[] = | 30 const char kPrivetCDDKeySupportedContentTypes[] = |
| 30 "printer.supported_content_type"; | 31 "printer.supported_content_type"; |
| 31 | 32 |
| 32 const char kPrivetCDDKeyContentType[] = "content_type"; | 33 const char kPrivetCDDKeyContentType[] = "content_type"; |
| 33 | 34 |
| 35 const char kPrivetKeyJobID[] = "job_id"; |
| 36 |
| 34 const int kPrivetCancelationTimeoutSeconds = 3; | 37 const int kPrivetCancelationTimeoutSeconds = 3; |
| 35 | 38 |
| 36 GURL CreatePrivetURL(const std::string& path) { | 39 GURL CreatePrivetURL(const std::string& path) { |
| 37 GURL url(kUrlPlaceHolder); | 40 GURL url(kUrlPlaceHolder); |
| 38 GURL::Replacements replacements; | 41 GURL::Replacements replacements; |
| 39 replacements.SetPathStr(path); | 42 replacements.SetPathStr(path); |
| 40 return url.ReplaceComponents(replacements); | 43 return url.ReplaceComponents(replacements); |
| 41 } | 44 } |
| 42 | 45 |
| 43 GURL CreatePrivetRegisterURL(const std::string& action, | 46 GURL CreatePrivetRegisterURL(const std::string& action, |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 use_pdf_(false), has_capabilities_(false), has_extended_workflow_(false), | 361 use_pdf_(false), has_capabilities_(false), has_extended_workflow_(false), |
| 359 started_(false), offline_(false) { | 362 started_(false), offline_(false) { |
| 360 } | 363 } |
| 361 | 364 |
| 362 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { | 365 PrivetLocalPrintOperationImpl::~PrivetLocalPrintOperationImpl() { |
| 363 } | 366 } |
| 364 | 367 |
| 365 void PrivetLocalPrintOperationImpl::Start() { | 368 void PrivetLocalPrintOperationImpl::Start() { |
| 366 DCHECK(!started_); | 369 DCHECK(!started_); |
| 367 | 370 |
| 368 current_request_ = | |
| 369 base::Bind(&PrivetLocalPrintOperationImpl::StartInitialRequest, | |
| 370 base::Unretained(this)); | |
| 371 | |
| 372 // We need to get the /info response so we can know which APIs are available. | 371 // We need to get the /info response so we can know which APIs are available. |
| 373 // TODO(noamsml): Use cached info when available. | 372 // TODO(noamsml): Use cached info when available. |
| 374 info_operation_ = privet_client_->CreateInfoOperation(this); | 373 info_operation_ = privet_client_->CreateInfoOperation(this); |
| 375 info_operation_->Start(); | 374 info_operation_->Start(); |
| 376 | 375 |
| 377 started_ = true; | 376 started_ = true; |
| 378 } | 377 } |
| 379 | 378 |
| 380 void PrivetLocalPrintOperationImpl::StartCurrentRequest() { | |
| 381 DCHECK(!current_request_.is_null()); | |
| 382 current_request_.Run(); | |
| 383 } | |
| 384 | |
| 385 void PrivetLocalPrintOperationImpl::OnPrivetInfoDone( | 379 void PrivetLocalPrintOperationImpl::OnPrivetInfoDone( |
| 386 PrivetInfoOperation* operation, | 380 PrivetInfoOperation* operation, |
| 387 int http_code, | 381 int http_code, |
| 388 const base::DictionaryValue* value) { | 382 const base::DictionaryValue* value) { |
| 389 if (value && !value->HasKey(kPrivetKeyError)) { | 383 if (value && !value->HasKey(kPrivetKeyError)) { |
| 390 has_capabilities_ = false; | 384 has_capabilities_ = false; |
| 391 has_extended_workflow_ = false; | 385 has_extended_workflow_ = false; |
| 392 bool has_printing = false; | 386 bool has_printing = false; |
| 393 | 387 |
| 394 const base::ListValue* api_list; | 388 const base::ListValue* api_list; |
| 395 if (value->GetList(kPrivetInfoKeyAPIList, &api_list)) { | 389 if (value->GetList(kPrivetInfoKeyAPIList, &api_list)) { |
| 396 for (size_t i = 0; i < api_list->GetSize(); i++) { | 390 for (size_t i = 0; i < api_list->GetSize(); i++) { |
| 397 std::string api; | 391 std::string api; |
| 398 api_list->GetString(i, &api); | 392 api_list->GetString(i, &api); |
| 399 if (api == kPrivetCapabilitiesPath) { | 393 if (api == kPrivetCapabilitiesPath) { |
| 400 has_capabilities_ = true; | 394 has_capabilities_ = true; |
| 401 } else if (api == kPrivetSubmitdocPath) { | 395 } else if (api == kPrivetSubmitdocPath) { |
| 402 has_printing = true; | 396 has_printing = true; |
| 403 } else if (api == kPrivetCreatejobPath) { | 397 } else if (api == kPrivetCreatejobPath) { |
| 404 has_extended_workflow_ = true; | 398 has_extended_workflow_ = true; |
| 405 } | 399 } |
| 406 } | 400 } |
| 407 } | 401 } |
| 408 | 402 |
| 409 if (!has_printing) { | 403 if (!has_printing) { |
| 410 delegate_->OnPrivetPrintingError(this, -1); | 404 delegate_->OnPrivetPrintingError(this, -1); |
| 411 return; | 405 return; |
| 412 } | 406 } |
| 413 | 407 |
| 414 StartCurrentRequest(); | 408 StartInitialRequest(); |
| 415 } else { | 409 } else { |
| 416 delegate_->OnPrivetPrintingError(this, http_code); | 410 delegate_->OnPrivetPrintingError(this, http_code); |
| 417 } | 411 } |
| 418 } | 412 } |
| 419 | 413 |
| 420 void PrivetLocalPrintOperationImpl::StartInitialRequest() { | 414 void PrivetLocalPrintOperationImpl::StartInitialRequest() { |
| 421 if (has_capabilities_) { | 415 if (has_capabilities_) { |
| 422 GetCapabilities(); | 416 GetCapabilities(); |
| 423 } else { | 417 } else { |
| 424 // Since we have no capabiltties, the only reasonable format we can | 418 // Since we have no capabiltties, the only reasonable format we can |
| 425 // request is PWG Raster. | 419 // request is PWG Raster. |
| 426 use_pdf_ = false; | 420 use_pdf_ = false; |
| 427 delegate_->OnPrivetPrintingRequestPWGRaster(this); | 421 delegate_->OnPrivetPrintingRequestPWGRaster(this); |
| 428 } | 422 } |
| 429 } | 423 } |
| 430 | 424 |
| 431 void PrivetLocalPrintOperationImpl::GetCapabilities() { | 425 void PrivetLocalPrintOperationImpl::GetCapabilities() { |
| 432 current_response_ = base::Bind( | 426 current_response_ = base::Bind( |
| 433 &PrivetLocalPrintOperationImpl::OnCapabilities, | 427 &PrivetLocalPrintOperationImpl::OnCapabilitiesResponse, |
| 434 base::Unretained(this)); | 428 base::Unretained(this)); |
| 435 | 429 |
| 436 url_fetcher_= privet_client_->CreateURLFetcher( | 430 url_fetcher_= privet_client_->CreateURLFetcher( |
| 437 CreatePrivetURL(kPrivetCapabilitiesPath), net::URLFetcher::GET, this); | 431 CreatePrivetURL(kPrivetCapabilitiesPath), net::URLFetcher::GET, this); |
| 438 url_fetcher_->DoNotRetryOnTransientError(); | 432 url_fetcher_->DoNotRetryOnTransientError(); |
| 439 | 433 |
| 440 url_fetcher_->Start(); | 434 url_fetcher_->Start(); |
| 441 } | 435 } |
| 442 | 436 |
| 437 void PrivetLocalPrintOperationImpl::DoCreatejob() { |
| 438 current_response_ = base::Bind( |
| 439 &PrivetLocalPrintOperationImpl::OnCreatejobResponse, |
| 440 base::Unretained(this)); |
| 441 |
| 442 url_fetcher_= privet_client_->CreateURLFetcher( |
| 443 CreatePrivetURL(kPrivetCreatejobPath), net::URLFetcher::POST, this); |
| 444 url_fetcher_->SetUploadData(kPrivetContentTypeCJT, ticket_); |
| 445 |
| 446 url_fetcher_->Start(); |
| 447 } |
| 448 |
| 443 void PrivetLocalPrintOperationImpl::DoSubmitdoc() { | 449 void PrivetLocalPrintOperationImpl::DoSubmitdoc() { |
| 444 current_response_ = base::Bind( | 450 current_response_ = base::Bind( |
| 445 &PrivetLocalPrintOperationImpl::OnSubmitdocResponse, | 451 &PrivetLocalPrintOperationImpl::OnSubmitdocResponse, |
| 446 base::Unretained(this)); | 452 base::Unretained(this)); |
| 447 | 453 |
| 448 GURL url = CreatePrivetURL(kPrivetSubmitdocPath); | 454 GURL url = CreatePrivetURL(kPrivetSubmitdocPath); |
| 449 | 455 |
| 450 if (!user_.empty()) { | 456 if (!user_.empty()) { |
| 451 url = net::AppendQueryParameter(url, | 457 url = net::AppendQueryParameter(url, |
| 452 kPrivetURLKeyUser, | 458 kPrivetURLKeyUser, |
| 453 user_); | 459 user_); |
| 454 } | 460 } |
| 455 | 461 |
| 456 if (!jobname_.empty()) { | 462 if (!jobname_.empty()) { |
| 457 url = net::AppendQueryParameter(url, | 463 url = net::AppendQueryParameter(url, |
| 458 kPrivetURLKeyJobname, | 464 kPrivetURLKeyJobname, |
| 459 jobname_); | 465 jobname_); |
| 460 } | 466 } |
| 461 | 467 |
| 468 if (!jobid_.empty()) { |
| 469 url = net::AppendQueryParameter(url, |
| 470 kPrivetKeyJobID, |
| 471 jobid_); |
| 472 } |
| 473 |
| 462 if (offline_) { | 474 if (offline_) { |
| 463 url = net::AppendQueryParameter(url, | 475 url = net::AppendQueryParameter(url, |
| 464 kPrivetURLKeyOffline, | 476 kPrivetURLKeyOffline, |
| 465 kPrivetURLValueOffline); | 477 kPrivetURLValueOffline); |
| 466 } | 478 } |
| 467 | 479 |
| 468 url_fetcher_= privet_client_->CreateURLFetcher( | 480 url_fetcher_= privet_client_->CreateURLFetcher( |
| 469 url, net::URLFetcher::POST, this); | 481 url, net::URLFetcher::POST, this); |
| 470 | 482 |
| 471 DCHECK(!data_.empty()); | 483 DCHECK(!data_.empty()); |
| 472 url_fetcher_->SetUploadData( | 484 url_fetcher_->SetUploadData( |
| 473 use_pdf_ ? kPrivetContentTypePDF : kPrivetContentTypePWGRaster, | 485 use_pdf_ ? kPrivetContentTypePDF : kPrivetContentTypePWGRaster, |
| 474 data_); | 486 data_); |
| 475 | 487 |
| 476 url_fetcher_->Start(); | 488 url_fetcher_->Start(); |
| 477 } | 489 } |
| 478 | 490 |
| 479 void PrivetLocalPrintOperationImpl::OnCapabilities( | 491 void PrivetLocalPrintOperationImpl::OnCapabilitiesResponse( |
| 480 const base::DictionaryValue* value) { | 492 const base::DictionaryValue* value) { |
| 481 const base::ListValue* supported_content_types; | 493 const base::ListValue* supported_content_types; |
| 482 use_pdf_ = false; | 494 use_pdf_ = false; |
| 483 | 495 |
| 484 if (value->GetList(kPrivetCDDKeySupportedContentTypes, | 496 if (value->GetList(kPrivetCDDKeySupportedContentTypes, |
| 485 &supported_content_types)) { | 497 &supported_content_types)) { |
| 486 for (size_t i = 0; i < supported_content_types->GetSize(); | 498 for (size_t i = 0; i < supported_content_types->GetSize(); |
| 487 i++) { | 499 i++) { |
| 488 const base::DictionaryValue* content_type_value; | 500 const base::DictionaryValue* content_type_value; |
| 489 std::string content_type; | 501 std::string content_type; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 504 } | 516 } |
| 505 | 517 |
| 506 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( | 518 void PrivetLocalPrintOperationImpl::OnSubmitdocResponse( |
| 507 const base::DictionaryValue* value) { | 519 const base::DictionaryValue* value) { |
| 508 // If we've gotten this far, there are no errors, so we've effectively | 520 // If we've gotten this far, there are no errors, so we've effectively |
| 509 // succeeded. | 521 // succeeded. |
| 510 | 522 |
| 511 delegate_->OnPrivetPrintingDone(this); | 523 delegate_->OnPrivetPrintingDone(this); |
| 512 } | 524 } |
| 513 | 525 |
| 526 void PrivetLocalPrintOperationImpl::OnCreatejobResponse( |
| 527 const base::DictionaryValue* value) { |
| 528 // Try to get job ID from value. If not, jobid_ will be empty and we will use |
| 529 // simple printing. |
| 530 value->GetString(kPrivetKeyJobID, &jobid_); |
| 531 |
| 532 DoSubmitdoc(); |
| 533 } |
| 534 |
| 514 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { | 535 PrivetHTTPClient* PrivetLocalPrintOperationImpl::GetHTTPClient() { |
| 515 return privet_client_; | 536 return privet_client_; |
| 516 } | 537 } |
| 517 | 538 |
| 518 void PrivetLocalPrintOperationImpl::OnError( | 539 void PrivetLocalPrintOperationImpl::OnError( |
| 519 PrivetURLFetcher* fetcher, | 540 PrivetURLFetcher* fetcher, |
| 520 PrivetURLFetcher::ErrorType error) { | 541 PrivetURLFetcher::ErrorType error) { |
| 521 delegate_->OnPrivetPrintingError(this, -1); | 542 delegate_->OnPrivetPrintingError(this, -1); |
| 522 } | 543 } |
| 523 | 544 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 536 | 557 |
| 537 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( | 558 void PrivetLocalPrintOperationImpl::OnNeedPrivetToken( |
| 538 PrivetURLFetcher* fetcher, | 559 PrivetURLFetcher* fetcher, |
| 539 const PrivetURLFetcher::TokenCallback& callback) { | 560 const PrivetURLFetcher::TokenCallback& callback) { |
| 540 privet_client_->RefreshPrivetToken(callback); | 561 privet_client_->RefreshPrivetToken(callback); |
| 541 } | 562 } |
| 542 | 563 |
| 543 void PrivetLocalPrintOperationImpl::SendData(const std::string& data) { | 564 void PrivetLocalPrintOperationImpl::SendData(const std::string& data) { |
| 544 DCHECK(started_); | 565 DCHECK(started_); |
| 545 data_ = data; | 566 data_ = data; |
| 546 current_request_ = base::Bind( | |
| 547 &PrivetLocalPrintOperationImpl::DoSubmitdoc, | |
| 548 base::Unretained(this)); | |
| 549 | 567 |
| 550 StartCurrentRequest(); | 568 if (has_extended_workflow_ && !ticket_.empty()) { |
| 569 DoCreatejob(); |
| 570 } else { |
| 571 DoSubmitdoc(); |
| 572 } |
| 551 } | 573 } |
| 552 | 574 |
| 553 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { | 575 void PrivetLocalPrintOperationImpl::SetTicket(const std::string& ticket) { |
| 554 DCHECK(!started_); | 576 DCHECK(!started_); |
| 555 ticket_ = ticket; | 577 ticket_ = ticket; |
| 556 } | 578 } |
| 557 | 579 |
| 558 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { | 580 void PrivetLocalPrintOperationImpl::SetUsername(const std::string& user) { |
| 559 DCHECK(!started_); | 581 DCHECK(!started_); |
| 560 user_= user; | 582 user_= user; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 TokenCallbackVector token_callbacks; | 690 TokenCallbackVector token_callbacks; |
| 669 token_callbacks_.swap(token_callbacks); | 691 token_callbacks_.swap(token_callbacks); |
| 670 | 692 |
| 671 for (TokenCallbackVector::iterator i = token_callbacks.begin(); | 693 for (TokenCallbackVector::iterator i = token_callbacks.begin(); |
| 672 i != token_callbacks.end(); i++) { | 694 i != token_callbacks.end(); i++) { |
| 673 i->Run(token); | 695 i->Run(token); |
| 674 } | 696 } |
| 675 } | 697 } |
| 676 | 698 |
| 677 } // namespace local_discovery | 699 } // namespace local_discovery |
| OLD | NEW |