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 |