Chromium Code Reviews| Index: cloud_print/gcp20/prototype/cloud_print_requester.cc |
| diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.cc b/cloud_print/gcp20/prototype/cloud_print_requester.cc |
| index b0c61695019f0a55d1b13afeb919465c3b8641a2..efeb144be2e145a4c7b5b187b9049f9fbda6274d 100644 |
| --- a/cloud_print/gcp20/prototype/cloud_print_requester.cc |
| +++ b/cloud_print/gcp20/prototype/cloud_print_requester.cc |
| @@ -4,18 +4,18 @@ |
| #include "cloud_print/gcp20/prototype/cloud_print_requester.h" |
| +#include "base/bind.h" |
| #include "base/md5.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/rand_util.h" |
| #include "base/strings/stringprintf.h" |
| -#include "cloud_print/gcp20/prototype/cloud_print_response_parser.h" |
| #include "google_apis/google_api_keys.h" |
| -#include "net/base/load_flags.h" |
| #include "net/base/mime_util.h" |
| #include "net/base/url_util.h" |
| #include "net/proxy/proxy_config_service_fixed.h" |
| #include "net/url_request/url_request_context.h" |
| #include "net/url_request/url_request_context_builder.h" |
| +#include "net/url_request/url_request_context_getter.h" |
| #include "url/gurl.h" |
| const char kCloudPrintUrl[] = "https://www.google.com/cloudprint"; |
| @@ -34,8 +34,23 @@ GURL CreateRegisterUrl() { |
| return GURL(std::string(kCloudPrintUrl) + "/register"); |
| } |
| +GURL CreateFetchUrl(const std::string& device_id) { |
| + GURL url(std::string(kCloudPrintUrl) + "/fetch"); |
| + url = net::AppendQueryParameter(url, "printerid", device_id); |
| + return url; |
| +} |
| + |
| +GURL CreateControlUrl(const std::string& job_id, const std::string& status) { |
| + GURL url(std::string(kCloudPrintUrl) + "/control"); |
| + url = net::AppendQueryParameter(url, "jobid", job_id); |
| + url = net::AppendQueryParameter(url, "status", status); |
| + return url; |
| +} |
| + |
| } // namespace |
| +using cloud_print_response_parser::Job; |
| + |
| // Used to return a dummy context, which lives on the message loop |
| // given in the constructor. |
| class CloudPrintURLRequestContextGetter : public net::URLRequestContextGetter { |
| @@ -89,7 +104,11 @@ CloudPrintRequester::CloudPrintRequester( |
| CloudPrintRequester::~CloudPrintRequester() { |
| } |
| -bool CloudPrintRequester::StartRegistration(const std::string& proxy_id, |
| +bool CloudPrintRequester::IsBusy() const { |
| + return request_ || gaia_; |
| +} |
| + |
| +void CloudPrintRequester::StartRegistration(const std::string& proxy_id, |
| const std::string& device_name, |
| const std::string& user, |
| const std::string& cdd) { |
| @@ -99,66 +118,113 @@ bool CloudPrintRequester::StartRegistration(const std::string& proxy_id, |
| base::SStringPrintf(&mime_boundary, |
| "---------------------------%08X%08X", r1, r2); |
| - std::string data; |
| - net::AddMultipartValueForUpload(kProxyIdValue, proxy_id, |
| - mime_boundary, std::string(), &data); |
| - net::AddMultipartValueForUpload(kPrinterNameValue, device_name, |
| - mime_boundary, std::string(), &data); |
| - net::AddMultipartValueForUpload("use_cdd", "true", |
| - mime_boundary, std::string(), &data); |
| - net::AddMultipartValueForUpload(kPrinterNameValue, device_name, |
| - mime_boundary, std::string(), &data); |
| - net::AddMultipartValueForUpload(kPrinterCapsValue, cdd, |
| - mime_boundary, "application/json", &data); |
| + CloudPrintRequest::DataForUpload data; |
| + data.content_type = "multipart/form-data; boundary=" + mime_boundary; |
| + |
| + net::AddMultipartValueForUpload(kProxyIdValue, proxy_id, mime_boundary, |
| + std::string(), &data.content); |
| + net::AddMultipartValueForUpload(kPrinterNameValue, device_name, mime_boundary, |
| + std::string(), &data.content); |
| + net::AddMultipartValueForUpload("use_cdd", "true", mime_boundary, |
| + std::string(), &data.content); |
| + net::AddMultipartValueForUpload(kPrinterNameValue, device_name, mime_boundary, |
| + std::string(), &data.content); |
| + net::AddMultipartValueForUpload(kPrinterCapsValue, cdd, mime_boundary, |
| + "application/json", &data.content); |
| net::AddMultipartValueForUpload(kPrinterCapsHashValue, base::MD5String(cdd), |
| - mime_boundary, std::string(), &data); |
| + mime_boundary, std::string(), &data.content); |
| net::AddMultipartValueForUpload(kPrinterUserValue, user, |
| - mime_boundary, std::string(), &data); |
| - net::AddMultipartFinalDelimiterForUpload(mime_boundary, &data); |
| + mime_boundary, std::string(), &data.content); |
| + net::AddMultipartFinalDelimiterForUpload(mime_boundary, &data.content); |
| - std::string mime_type("multipart/form-data; boundary=" + mime_boundary); |
| + request_ = CreatePost(CreateRegisterUrl(), data); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParseRegisterStart, AsWeakPtr())); |
| +} |
| + |
| +void CloudPrintRequester::CompleteRegistration() { |
| + request_ = CreateGet(GURL(polling_url_ + oauth_client_info_.client_id)); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParseRegisterComplete, AsWeakPtr())); |
| +} |
| - if (!CreateRequest( |
| - CreateRegisterUrl(), net::URLFetcher::POST, |
| - base::Bind(&CloudPrintRequester::ParseRegisterStartResponse, |
| - AsWeakPtr()))) { |
| - return false; |
| +void CloudPrintRequester::FetchPrintJobs(const std::string& refresh_token, |
| + const std::string& device_id) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + if (IsBusy()) |
| + return; |
| + |
| + if (access_token_.empty()) { |
| + UpdateAccesstoken(refresh_token); |
| + return; |
| } |
| - fetcher_->SetUploadData(mime_type, data); |
| - fetcher_->Start(); |
| - return true; |
| + VLOG(3) << "Function: " << __FUNCTION__ << |
| + ": request created"; |
| + request_ = CreateGet(CreateFetchUrl(device_id)); |
| + request_->Run(base::Bind(&CloudPrintRequester::ParseFetch, AsWeakPtr())); |
| } |
| -bool CloudPrintRequester::CompleteRegistration() { |
| - if (!CreateRequest( |
| - GURL(polling_url_ + oauth_client_info_.client_id), |
| - net::URLFetcher::GET, |
| - base::Bind(&CloudPrintRequester::ParseRegisterCompleteResponse, |
| - AsWeakPtr()))) { |
| - return false; |
| - } |
| - fetcher_->Start(); |
| +void CloudPrintRequester::UpdateAccesstoken(const std::string& refresh_token) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + DCHECK(!IsBusy()); |
| + gaia_.reset(new gaia::GaiaOAuthClient(context_getter_.get())); |
| + gaia_->RefreshToken(oauth_client_info_, refresh_token, |
| + std::vector<std::string>(), kGaiaMaxRetries, this); |
| + delegate_->OnServerError("Access token requested."); |
| +} |
| - return true; |
| +void CloudPrintRequester::RequestPrintJob(const Job& job) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + current_print_job_.reset(new Job(job)); |
| + request_ = CreateGet( |
| + CreateControlUrl(current_print_job_->job_id, "IN_PROGRESS")); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParsePrintJobInProgress, AsWeakPtr())); |
| } |
| -void CloudPrintRequester::OnURLFetchComplete(const net::URLFetcher* source) { |
| - std::string response; |
| - source->GetResponseAsString(&response); |
| - fetcher_.reset(); |
| - VLOG(1) << response; |
| +void CloudPrintRequester::SendPrintJobDone(const std::string& job_id) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + request_ = CreateGet(CreateControlUrl(job_id, "DONE")); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParsePrintJobDone, AsWeakPtr())); |
| +} |
| - // TODO(maksymb): Add |server_http_code| and |server_api| info for errors. |
| - if (!parse_response_callback_.is_null()) { |
| - parse_response_callback_.Run(response); |
| - parse_response_callback_.Reset(); |
| - } |
| +void CloudPrintRequester::OnFetchComplete() { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + request_.reset(); |
| +} |
| + |
| +void CloudPrintRequester::OnFetchError(const std::string& server_api, |
| + int server_code, |
| + int server_http_code) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + request_.reset(); |
| + delegate_->OnServerError("Fetch error"); |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void CloudPrintRequester::OnFetchTimeoutReached() { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + request_.reset(); |
| + current_print_job_.reset(); |
| + delegate_->OnNetworkError(); |
| +} |
| + |
| +std::string CloudPrintRequester::access_token() { |
| + return access_token_; |
| +} |
| + |
| +scoped_refptr<net::URLRequestContextGetter> |
| + CloudPrintRequester::context_getter() { |
| + return context_getter_; |
| } |
| void CloudPrintRequester::OnGetTokensResponse(const std::string& refresh_token, |
| const std::string& access_token, |
| int expires_in_seconds) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + gaia_.reset(); |
| access_token_ = access_token; |
| delegate_->OnGetAuthCodeResponseParsed(refresh_token); |
| } |
| @@ -166,42 +232,37 @@ void CloudPrintRequester::OnGetTokensResponse(const std::string& refresh_token, |
| void CloudPrintRequester::OnRefreshTokenResponse( |
| const std::string& access_token, |
| int expires_in_seconds) { |
| - NOTIMPLEMENTED(); |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + gaia_.reset(); |
| + access_token_ = access_token; |
| + LOG(INFO) << "New accesstoken: " << access_token; |
| } |
| void CloudPrintRequester::OnOAuthError() { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + gaia_.reset(); |
| NOTIMPLEMENTED(); |
| } |
| void CloudPrintRequester::OnNetworkError(int response_code) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + gaia_.reset(); |
| NOTIMPLEMENTED(); |
| } |
| -bool CloudPrintRequester::CreateRequest(const GURL& url, |
| - net::URLFetcher::RequestType method, |
| - const ParserCallback& callback) { |
| - if (fetcher_) |
| - return false; // Only one query is supported. |
| - |
| - fetcher_.reset(net::URLFetcher::Create(url, method, this)); |
| - fetcher_->SetRequestContext(context_getter_); |
| - |
| - int load_flags = fetcher_->GetLoadFlags(); |
| - load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; |
| - load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; |
| - fetcher_->SetLoadFlags(load_flags); |
| - |
| - fetcher_->AddExtraRequestHeader("X-CloudPrint-Proxy: \"\""); |
| - if (!access_token_.empty()) |
| - fetcher_->AddExtraRequestHeader("Authorization: Bearer " + access_token_); |
| - |
| - parse_response_callback_ = callback; |
| +scoped_ptr<CloudPrintRequest> CloudPrintRequester::CreateGet(const GURL& url) { |
| + DCHECK(!IsBusy()); |
| + return CloudPrintRequest::CreateGet(url, this); |
| +} |
| - return true; |
| +scoped_ptr<CloudPrintRequest> CloudPrintRequester::CreatePost( |
| + const GURL& url, |
| + const CloudPrintRequest::DataForUpload& data) { |
| + DCHECK(!IsBusy()); |
| + return CloudPrintRequest::CreatePost(url, data, this); |
| } |
| -void CloudPrintRequester::ParseRegisterStartResponse( |
| - const std::string& response) { |
| +void CloudPrintRequester::ParseRegisterStart(const std::string& response) { |
| std::string polling_url; |
| std::string registration_token; |
| std::string complete_invite_url; |
| @@ -224,8 +285,7 @@ void CloudPrintRequester::ParseRegisterStartResponse( |
| complete_invite_url, device_id); |
| } |
| -void CloudPrintRequester::ParseRegisterCompleteResponse( |
| - const std::string& response) { |
| +void CloudPrintRequester::ParseRegisterComplete(const std::string& response) { |
| std::string authorization_code; |
| bool success = cloud_print_response_parser::ParseRegisterCompleteResponse( |
| @@ -242,3 +302,50 @@ void CloudPrintRequester::ParseRegisterCompleteResponse( |
| kGaiaMaxRetries, this); |
| } |
| +void CloudPrintRequester::ParseFetch(const std::string& response) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + std::vector<Job> list; |
| + bool success = cloud_print_response_parser::ParseFetchResponse( |
|
gene
2013/07/23 09:36:23
This part is a bit confusing. Reading the code, it
maksymb
2013/07/23 19:02:37
Done.
|
| + response, |
| + base::Bind(&CloudPrintRequester::Delegate::OnServerError, |
| + base::Unretained(delegate_)), |
| + &list); |
| + |
| + if (!success) |
| + return; |
| + |
| + delegate_->OnPrintJobsAvailable(list); |
| +} |
| + |
| +void CloudPrintRequester::ParseGetPrintJobTicket(const std::string& response) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + current_print_job_->ticket = response; |
| + |
| + DCHECK(current_print_job_); |
| + request_ = CreateGet(GURL(current_print_job_->file_url)); |
| + request_->AddHeader("Accept: \"application/pdf\""); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParseGetPrintJobData, AsWeakPtr())); |
| +} |
| + |
| +void CloudPrintRequester::ParseGetPrintJobData(const std::string& response) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + current_print_job_->file = response; |
| + DCHECK(current_print_job_); |
| + delegate_->OnPrintJobDownloaded(*current_print_job_); |
| +} |
| + |
| +void CloudPrintRequester::ParsePrintJobDone(const std::string& response) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + current_print_job_.reset(); |
| + delegate_->OnPrintJobDone(); |
| +} |
| + |
| +void CloudPrintRequester::ParsePrintJobInProgress(const std::string& response) { |
| + VLOG(3) << "Function: " << __FUNCTION__; |
| + DCHECK(current_print_job_); |
| + request_ = CreateGet(GURL(current_print_job_->ticket_url)); |
| + request_->Run( |
| + base::Bind(&CloudPrintRequester::ParseGetPrintJobTicket, AsWeakPtr())); |
| +} |
| + |