1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file. 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "cloud_print/gcp20/prototype/privet_http_server.h" 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/command_line.h" 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/json/json_writer.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/stringprintf.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cloud_print/gcp20/prototype/gcp20_switches.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/ip_endpoint.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/net_errors.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/url_util.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/socket/tcp_server_socket.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "url/gurl.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace { 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kDeviceBusyTimeout = 30; // in seconds 202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kPendingUserActionTimeout = 5; // in seconds 212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetInfo[] = "/privet/info"; 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetRegister[] = "/privet/register"; 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetCapabilities[] = "/privet/capabilities"; 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetPrinterCreateJob[] = "/privet/printer/createjob"; 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetPrinterSubmitDoc[] = "/privet/printer/submitdoc"; 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPrivetPrinterJobState[] = "/privet/printer/jobstate"; 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// {"error":|error_type|} 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<base::DictionaryValue> CreateError(const std::string& error_type) { 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue> error(new base::DictionaryValue); 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error->SetString("error", error_type); 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return error.Pass(); 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// {"error":|error_type|, "description":|description|} 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<base::DictionaryValue> CreateErrorWithDescription( 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& error_type, 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& description) { 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue> error(CreateError(error_type)); 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error->SetString("description", description); 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return error.Pass(); 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// {"error":|error_type|, "timeout":|timeout|} 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<base::DictionaryValue> CreateErrorWithTimeout( 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& error_type, 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int timeout) { 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue> error(CreateError(error_type)); 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error->SetInteger("timeout", timeout); 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return error.Pass(); 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Converts state to string. 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string LocalPrintJobStateToString(LocalPrintJob::State state) { 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (state) { 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DRAFT: 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "draft"; 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_ABORTED: 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "done"; 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::STATE_DONE: 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "done"; 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return std::string(); 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Returns |true| if |request| should be GET method. 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool IsGetMethod(const std::string& request) { 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return request == kPrivetInfo || 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request == kPrivetCapabilities || 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request == kPrivetPrinterJobState; 79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 80a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 81a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Returns |true| if |request| should be POST method. 82a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool IsPostMethod(const std::string& request) { 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return request == kPrivetRegister || 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request == kPrivetPrinterCreateJob || 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request == kPrivetPrinterSubmitDoc; 86a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 87a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 90a3f7b4e666c476898878fa745f637129375cd889Ben MurdochPrivetHttpServer::DeviceInfo::DeviceInfo() : uptime(0) { 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochPrivetHttpServer::DeviceInfo::~DeviceInfo() { 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochPrivetHttpServer::PrivetHttpServer(Delegate* delegate) 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : port_(0), 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch delegate_(delegate) { 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochPrivetHttpServer::~PrivetHttpServer() { 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Shutdown(); 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool PrivetHttpServer::Start(uint16 port) { 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (server_) 107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<net::ServerSocket> server_socket( 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::TCPServerSocket(NULL, net::NetLog::Source())); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string listen_address = "::"; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableIpv6)) 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listen_address = "0.0.0.0"; 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci server_socket->ListenWithAddressAndPort(listen_address, port, 1); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci server_.reset(new net::HttpServer(server_socket.Pass(), this)); 116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::IPEndPoint address; 118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (server_->GetLocalAddress(&address) != net::OK) { 119ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch NOTREACHED() << "Cannot start HTTP server"; 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch VLOG(1) << "Address of HTTP server: " << address.ToString(); 124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::Shutdown() { 128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!server_) 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci server_.reset(NULL); 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::OnHttpRequest(int connection_id, 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const net::HttpServerRequestInfo& info) { 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch VLOG(1) << "Processing HTTP request: " << info.path; 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL url("http://host" + info.path); 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 139a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (!ValidateRequestMethod(connection_id, url.path(), info.method)) 140a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return; 141a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableXTocken)) { 143a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch net::HttpServerRequestInfo::HeadersMap::const_iterator iter = 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) info.headers.find("x-privet-token"); 145a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (iter == info.headers.end()) { 146a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch server_->Send(connection_id, net::HTTP_BAD_REQUEST, 147a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "Missing X-Privet-Token header.\n" 148a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "TODO: Message should be in header, not in the body!", 149a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "text/plain"); 150a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return; 151a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 152a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (url.path() != kPrivetInfo && 154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch !delegate_->CheckXPrivetTokenHeader(iter->second)) { 155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) server_->Send(connection_id, net::HTTP_OK, 156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "{\"error\":\"invalid_x_privet_token\"}", 157a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "application/json"); 158a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return; 159a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 160a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 161a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string response; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode status_code = ProcessHttpRequest(url, info, &response); 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 165a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch server_->Send(connection_id, status_code, response, "application/json"); 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::OnWebSocketRequest( 169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int connection_id, 170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const net::HttpServerRequestInfo& info) { 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 173ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::OnWebSocketMessage(int connection_id, 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& data) { 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::OnClose(int connection_id) { 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 180a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid PrivetHttpServer::ReportInvalidMethod(int connection_id) { 181a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch server_->Send(connection_id, net::HTTP_BAD_REQUEST, "Invalid method", 182a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "text/plain"); 183a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 184a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 185a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool PrivetHttpServer::ValidateRequestMethod(int connection_id, 186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& request, 187a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& method) { 188a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DCHECK(!IsGetMethod(request) || !IsPostMethod(request)); 189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (!IsGetMethod(request) && !IsPostMethod(request)) { 191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch server_->Send404(connection_id); 192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 194a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 195a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (CommandLine::ForCurrentProcess()->HasSwitch("disable-method-check")) 196a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 197a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 198a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if ((IsGetMethod(request) && method != "GET") || 199a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch (IsPostMethod(request) && method != "POST")) { 200a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ReportInvalidMethod(connection_id); 201a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 202a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 204a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 205a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 206a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnet::HttpStatusCode PrivetHttpServer::ProcessHttpRequest( 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& url, 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const net::HttpServerRequestInfo& info, 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string* response) { 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::HttpStatusCode status_code = net::HTTP_OK; 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue> json_response; 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (url.path() == kPrivetInfo) { 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch json_response = ProcessInfo(&status_code); 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (url.path() == kPrivetRegister) { 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch json_response = ProcessRegister(url, &status_code); 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (url.path() == kPrivetCapabilities) { 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) json_response = ProcessCapabilities(&status_code); 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (url.path() == kPrivetPrinterCreateJob) { 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) json_response = ProcessCreateJob(url, info.data, &status_code); 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (url.path() == kPrivetPrinterSubmitDoc) { 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) json_response = ProcessSubmitDoc(url, info, &status_code); 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (url.path() == kPrivetPrinterJobState) { 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) json_response = ProcessJobState(url, &status_code); 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 227a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch NOTREACHED(); 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!json_response) { 231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response->clear(); 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status_code; 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::JSONWriter::WriteWithOptions(json_response.get(), 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::JSONWriter::OPTIONS_PRETTY_PRINT, 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response); 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status_code; 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Privet API methods: 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessInfo( 244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::HttpStatusCode* status_code) const { 245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DeviceInfo info; 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch delegate_->CreateInfo(&info); 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue); 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response->SetString("version", info.version); 251a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("name", info.name); 252a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("description", info.description); 253a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("url", info.url); 254a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("id", info.id); 255a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("device_state", info.device_state); 256a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("connection_state", info.connection_state); 257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response->SetString("manufacturer", info.manufacturer); 258a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("model", info.model); 259a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("serial_number", info.serial_number); 260a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("firmware", info.firmware); 261a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetInteger("uptime", info.uptime); 262a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->SetString("x-privet-token", info.x_privet_token); 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::ListValue api; 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (size_t i = 0; i < info.api.size(); ++i) 266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch api.AppendString(info.api[i]); 267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response->Set("api", api.DeepCopy()); 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 269a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch base::ListValue type; 270a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (size_t i = 0; i < info.type.size(); ++i) 271a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch type.AppendString(info.type[i]); 272a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch response->Set("type", type.DeepCopy()); 273a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *status_code = net::HTTP_OK; 275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return response.Pass(); 276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessCapabilities( 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode* status_code) const { 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!delegate_->IsRegistered()) { 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_NOT_FOUND; 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return make_scoped_ptr(delegate_->GetCapabilities().DeepCopy()); 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessCreateJob( 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GURL& url, 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& body, 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode* status_code) const { 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!delegate_->IsRegistered() || !delegate_->IsLocalPrintingAllowed()) { 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_NOT_FOUND; 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string job_id; 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::Time for expiration 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int expires_in = 0; 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::TimeDelta for timeout values 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int error_timeout = -1; 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string error_description; 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::CreateResult result = 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delegate_->CreateJob(body, &job_id, &expires_in, 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &error_timeout, &error_description); 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::DictionaryValue> response; 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_OK; 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (result) { 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_SUCCESS: 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response.reset(new base::DictionaryValue); 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("job_id", job_id); 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetInteger("expires_in", expires_in); 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return response.Pass(); 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_INVALID_TICKET: 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateError("invalid_ticket"); 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_BUSY: 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateErrorWithTimeout("printer_busy", error_timeout); 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::CREATE_PRINTER_ERROR: 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateErrorWithDescription("printer_error", error_description); 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessSubmitDoc( 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GURL& url, 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const net::HttpServerRequestInfo& info, 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode* status_code) const { 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!delegate_->IsRegistered() || !delegate_->IsLocalPrintingAllowed()) { 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_NOT_FOUND; 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) using net::GetValueForKeyInQuery; 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Parse query 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob job; 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string offline; 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string job_id; 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool job_name_present = GetValueForKeyInQuery(url, "job_name", &job.job_name); 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool job_id_present = GetValueForKeyInQuery(url, "job_id", &job_id); 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetValueForKeyInQuery(url, "client_name", &job.client_name); 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetValueForKeyInQuery(url, "user_name", &job.user_name); 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetValueForKeyInQuery(url, "offline", &offline); 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job.offline = (offline == "1"); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job.content_type = info.GetHeaderValue("content-type"); 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) job.content = info.data; 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Call delegate 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(maksymb): Use base::Time for expiration 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int expires_in = 0; 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string error_description; 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int timeout; 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::SaveResult status = job_id_present 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ? delegate_->SubmitDocWithId(job, job_id, &expires_in, 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &error_description, &timeout) 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : delegate_->SubmitDoc(job, &job_id, &expires_in, 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &error_description, &timeout); 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create response 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_OK; 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue); 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (status) { 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_SUCCESS: 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("job_id", job_id); 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetInteger("expires_in", expires_in); 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("job_type", job.content_type); 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString( 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "job_size", 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::StringPrintf("%u", static_cast<uint32>(job.content.size()))); 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (job_name_present) 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("job_name", job.job_name); 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return response.Pass(); 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_INVALID_PRINT_JOB: 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateErrorWithTimeout("invalid_print_job", timeout); 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_INVALID_DOCUMENT_TYPE: 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateError("invalid_document_type"); 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_INVALID_DOCUMENT: 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateError("invalid_document"); 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_DOCUMENT_TOO_LARGE: 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateError("document_too_large"); 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_PRINTER_BUSY: 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateErrorWithTimeout("printer_busy", -2); 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case LocalPrintJob::SAVE_PRINTER_ERROR: 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateErrorWithDescription("printer_error", error_description); 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessJobState( 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GURL& url, 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode* status_code) const { 3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!delegate_->IsRegistered() || !delegate_->IsLocalPrintingAllowed()) { 3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *status_code = net::HTTP_NOT_FOUND; 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string job_id; 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::GetValueForKeyInQuery(url, "job_id", &job_id); 4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LocalPrintJob::Info info; 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!delegate_->GetJobState(job_id, &info)) 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateError("invalid_print_job"); 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue); 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("job_id", job_id); 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetString("state", LocalPrintJobStateToString(info.state)); 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) response->SetInteger("expires_in", info.expires_in); 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return response.Pass(); 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 415ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<base::DictionaryValue> PrivetHttpServer::ProcessRegister( 416ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& url, 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HttpStatusCode* status_code) const { 418a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (delegate_->IsRegistered()) { 419a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch *status_code = net::HTTP_NOT_FOUND; 420a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return scoped_ptr<base::DictionaryValue>(); 421a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string action; 424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string user; 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool params_present = 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::GetValueForKeyInQuery(url, "action", &action) && 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::GetValueForKeyInQuery(url, "user", &user) && 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !user.empty(); 429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) RegistrationErrorStatus status = REG_ERROR_INVALID_PARAMS; 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue); 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (params_present) { 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) response->SetString("action", action); 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) response->SetString("user", user); 436ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (action == "start") 438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status = delegate_->RegistrationStart(user); 439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (action == "getClaimToken") { 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string token; 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string claim_url; 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status = delegate_->RegistrationGetClaimToken(user, &token, &claim_url); 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) response->SetString("token", token); 445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) response->SetString("claim_url", claim_url); 446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (action == "complete") { 449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string device_id; 450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status = delegate_->RegistrationComplete(user, &device_id); 451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) response->SetString("device_id", device_id); 452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (action == "cancel") 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) status = delegate_->RegistrationCancel(user); 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (status != REG_ERROR_OK) 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch response.reset(); 460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProcessRegistrationStatus(status, &response); 462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *status_code = net::HTTP_OK; 463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return response.Pass(); 464ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 465ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 466ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PrivetHttpServer::ProcessRegistrationStatus( 467ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RegistrationErrorStatus status, 468ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::DictionaryValue>* current_response) const { 469ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (status) { 470ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_OK: 471ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(*current_response) << "Response shouldn't be empty."; 472ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 473ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case REG_ERROR_INVALID_PARAMS: 475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *current_response = CreateError("invalid_params"); 476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_DEVICE_BUSY: 4782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch *current_response = CreateErrorWithTimeout("device_busy", 4792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch kDeviceBusyTimeout); 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_PENDING_USER_ACTION: 4822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch *current_response = CreateErrorWithTimeout("pending_user_action", 4832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch kPendingUserActionTimeout); 484ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_USER_CANCEL: 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *current_response = CreateError("user_cancel"); 487ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 488ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_CONFIRMATION_TIMEOUT: 489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *current_response = CreateError("confirmation_timeout"); 490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 491ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_INVALID_ACTION: 492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *current_response = CreateError("invalid_action"); 493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case REG_ERROR_OFFLINE: 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *current_response = CreateError("offline"); 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 498ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case REG_ERROR_SERVER_ERROR: { 499ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string description; 500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch delegate_->GetRegistrationServerError(&description); 501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *current_response = CreateErrorWithDescription("server_error", 502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch description); 503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 506ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch default: 507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch NOTREACHED(); 508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 510