Home | History | Annotate | Download | only in prototype
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CLOUD_PRINT_GCP20_PROTOTYPE_PRIVET_HTTP_SERVER_H_
      6 #define CLOUD_PRINT_GCP20_PROTOTYPE_PRIVET_HTTP_SERVER_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/values.h"
     13 #include "cloud_print/gcp20/prototype/local_print_job.h"
     14 #include "net/server/http_server.h"
     15 #include "net/server/http_server_request_info.h"
     16 
     17 class GURL;
     18 
     19 // HTTP server for receiving .
     20 class PrivetHttpServer: public net::HttpServer::Delegate {
     21  public:
     22   // TODO(maksymb): Move this enum to some namespace instead of this class.
     23   enum RegistrationErrorStatus {
     24     REG_ERROR_OK,
     25 
     26     REG_ERROR_INVALID_PARAMS,
     27     REG_ERROR_DEVICE_BUSY,
     28     REG_ERROR_PENDING_USER_ACTION,
     29     REG_ERROR_USER_CANCEL,
     30     REG_ERROR_CONFIRMATION_TIMEOUT,
     31     REG_ERROR_INVALID_ACTION,
     32     REG_ERROR_OFFLINE,
     33     REG_ERROR_SERVER_ERROR
     34   };
     35 
     36   // TODO(maksymb): Move this struct to some namespace instead of this class.
     37   struct DeviceInfo {
     38     DeviceInfo();
     39     ~DeviceInfo();
     40 
     41     std::string version;
     42     std::string name;
     43     std::string description;
     44     std::string url;
     45     std::string id;
     46     std::string device_state;
     47     std::string connection_state;
     48     std::string manufacturer;
     49     std::string model;
     50     std::string serial_number;
     51     std::string firmware;
     52     int uptime;
     53     std::string x_privet_token;
     54 
     55     std::vector<std::string> api;
     56     std::vector<std::string> type;
     57   };
     58 
     59   class Delegate {
     60    public:
     61     virtual ~Delegate() {}
     62 
     63     // Invoked when registration is starting.
     64     virtual RegistrationErrorStatus RegistrationStart(
     65         const std::string& user) = 0;
     66 
     67     // Invoked when claimtoken is needed.
     68     virtual RegistrationErrorStatus RegistrationGetClaimToken(
     69         const std::string& user,
     70         std::string* token,
     71         std::string* claim_url) = 0;
     72 
     73     // Invoked when registration is going to be completed.
     74     virtual RegistrationErrorStatus RegistrationComplete(
     75         const std::string& user,
     76         std::string* device_id) = 0;
     77 
     78     // Invoked when client asked for cancelling the registration.
     79     virtual RegistrationErrorStatus RegistrationCancel(
     80         const std::string& user) = 0;
     81 
     82     // Invoked for receiving server error details.
     83     virtual void GetRegistrationServerError(std::string* description) = 0;
     84 
     85     // Invoked when /privet/info is called.
     86     virtual void CreateInfo(DeviceInfo* info) = 0;
     87 
     88     // Invoked for checking wether /privet/register should be exposed.
     89     virtual bool IsRegistered() const = 0;
     90 
     91     // Invoked for checking wether /privet/printer/* should be exposed.
     92     virtual bool IsLocalPrintingAllowed() const = 0;
     93 
     94     // Invoked when XPrivetToken has to be checked.
     95     virtual bool CheckXPrivetTokenHeader(const std::string& token) const = 0;
     96 
     97     // Invoked for getting capabilities.
     98     virtual const base::DictionaryValue& GetCapabilities() = 0;
     99 
    100     // Invoked for creating a job.
    101     virtual LocalPrintJob::CreateResult CreateJob(
    102         const std::string& ticket,
    103         std::string* job_id,
    104         int* expires_in,
    105         // TODO(maksymb): Use base::TimeDelta for timeouts
    106         int* error_timeout,
    107         std::string* error_description) = 0;
    108 
    109     // Invoked for simple local printing.
    110     virtual LocalPrintJob::SaveResult SubmitDoc(
    111         const LocalPrintJob& job,
    112         std::string* job_id,
    113         int* expires_in,
    114         std::string* error_description,
    115         int* timeout) = 0;
    116 
    117     // Invoked for advanced local printing.
    118     virtual LocalPrintJob::SaveResult SubmitDocWithId(
    119         const LocalPrintJob& job,
    120         const std::string& job_id,
    121         int* expires_in,
    122         std::string* error_description,
    123         int* timeout) = 0;
    124 
    125     // Invoked for getting job status.
    126     virtual bool GetJobState(const std::string& job_id,
    127                              LocalPrintJob::Info* info) = 0;
    128   };
    129 
    130   // Constructor doesn't start server.
    131   explicit PrivetHttpServer(Delegate* delegate);
    132 
    133   // Destroys the object.
    134   virtual ~PrivetHttpServer();
    135 
    136   // Starts HTTP server: start listening port |port| for HTTP requests.
    137   bool Start(uint16 port);
    138 
    139   // Stops HTTP server.
    140   void Shutdown();
    141 
    142  private:
    143   // net::HttpServer::Delegate methods:
    144   virtual void OnHttpRequest(
    145       int connection_id,
    146       const net::HttpServerRequestInfo& info) OVERRIDE;
    147   virtual void OnWebSocketRequest(
    148       int connection_id,
    149       const net::HttpServerRequestInfo& info) OVERRIDE;
    150   virtual void OnWebSocketMessage(int connection_id,
    151                                   const std::string& data) OVERRIDE;
    152   virtual void OnClose(int connection_id) OVERRIDE;
    153 
    154   // Sends error as response. Invoked when request method is invalid.
    155   void ReportInvalidMethod(int connection_id);
    156 
    157   // Returns |true| if |request| should be done with correct |method|.
    158   // Otherwise sends |Invalid method| error.
    159   // Also checks support of |request| by this server.
    160   bool ValidateRequestMethod(int connection_id,
    161                              const std::string& request,
    162                              const std::string& method);
    163 
    164   // Processes http request after all preparations (XPrivetHeader check,
    165   // data handling etc.)
    166   net::HttpStatusCode ProcessHttpRequest(
    167       const GURL& url,
    168       const net::HttpServerRequestInfo& info,
    169       std::string* response);
    170 
    171   // Pivet API methods. Return reference to NULL if output should be empty.
    172   scoped_ptr<base::DictionaryValue> ProcessInfo(
    173       net::HttpStatusCode* status_code) const;
    174 
    175   scoped_ptr<base::DictionaryValue> ProcessCapabilities(
    176       net::HttpStatusCode* status_code) const;
    177 
    178   scoped_ptr<base::DictionaryValue> ProcessCreateJob(
    179       const GURL& url,
    180       const std::string& body,
    181       net::HttpStatusCode* status_code) const;
    182 
    183   scoped_ptr<base::DictionaryValue> ProcessSubmitDoc(
    184       const GURL& url,
    185       const net::HttpServerRequestInfo& info,
    186       net::HttpStatusCode* status_code) const;
    187 
    188   scoped_ptr<base::DictionaryValue> ProcessJobState(
    189       const GURL& url,
    190       net::HttpStatusCode* status_code) const;
    191 
    192   scoped_ptr<base::DictionaryValue> ProcessRegister(
    193       const GURL& url,
    194       net::HttpStatusCode* status_code) const;
    195 
    196   // Processes current status and depending on it replaces (or not)
    197   // |current_response| with error or empty response.
    198   void ProcessRegistrationStatus(
    199       RegistrationErrorStatus status,
    200       scoped_ptr<base::DictionaryValue>* current_response) const;
    201 
    202   // Port for listening.
    203 
    204   uint16 port_;
    205 
    206   // Contains encapsulated object for listening for requests.
    207   scoped_refptr<net::HttpServer> server_;
    208 
    209   Delegate* delegate_;
    210 
    211   DISALLOW_COPY_AND_ASSIGN(PrivetHttpServer);
    212 };
    213 
    214 #endif  // CLOUD_PRINT_GCP20_PROTOTYPE_PRIVET_HTTP_SERVER_H_
    215 
    216