Google APIs Client Library for C++
|
00001 /* 00002 * \copyright Copyright 2013 Google Inc. All Rights Reserved. 00003 * \license @{ 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 * @} 00018 */ 00019 00020 00021 /* 00022 * @defgroup PlatformLayerWebServer Platform Layer - Embedded Web Server 00023 * 00024 * The embedded webserver module is provided by the Plaform Layer rather 00025 * than the Trnasport Layer were you might otherwise expect it. This is 00026 * because we are not really embracing it as a core product feature. It is 00027 * only here to support providing interfaces to iteractt with embedded 00028 * HTTP servers and for writing tests. 00029 * 00030 * The request/response abstraction in this module is distinctly different 00031 * (and not compatible with) the HttpRequest interface core to the 00032 * Transport Layer. The transport layer is designed around the needs of 00033 * clients. The embedded web server is for servers. Because the focal point 00034 * of the SDK is strictly for clients, we are keeping the focus and viewpoints 00035 * more stictly separated. 00036 */ 00037 00038 #ifndef APISERVING_CLIENTS_CPP_UTIL_ABSTRACT_WEBSERVER_H_ 00039 #define APISERVING_CLIENTS_CPP_UTIL_ABSTRACT_WEBSERVER_H_ 00040 00041 #include <string> 00042 using std::string; 00043 #include <utility> 00044 using std::make_pair; 00045 using std::pair; 00046 #include <vector> 00047 using std::vector; 00048 #include "googleapis/client/util/uri_utils.h" 00049 #include "googleapis/base/callback.h" 00050 #include "googleapis/base/macros.h" 00051 #include "googleapis/base/scoped_ptr.h" 00052 #include "googleapis/strings/stringpiece.h" 00053 #include "googleapis/util/status.h" 00054 namespace googleapis { 00055 00056 namespace client { 00057 00058 /* 00059 * Abstract class for responses to WebServerRequests into the 00060 * AbstractWebServer 00061 * @ingroup PlatformLayerWebServer 00062 * 00063 * This is different from the HttpResponse class in the transport layer 00064 * which are client-side responses. These are server side responses. 00065 * 00066 * Responses are owned and created by WebServerRequest. 00067 */ 00068 class WebServerResponse { 00069 public: 00070 WebServerResponse() {} 00071 virtual ~WebServerResponse() {} 00072 00073 /* 00074 * Respond with a text/html content type and body. 00075 * 00076 * @param[in] http_code The HTTP status code to send. 00077 * @param[in] body The payload can be empty. 00078 * 00079 * @return ok or reason for failure. 00080 */ 00081 util::Status SendHtml(int http_code, const StringPiece& body) { 00082 return SendReply("text/html", http_code, body); 00083 } 00084 00085 /* 00086 * Respond with a text/plain content type and body. 00087 * 00088 * @param[in] http_code The HTTP status code to send. 00089 * @param[in] body The payload can be empty. 00090 * 00091 * @return ok or reason for failure. 00092 */ 00093 util::Status SendText(int http_code, const StringPiece& body) { 00094 return SendReply("text/plain", http_code, body); 00095 } 00096 00097 /* 00098 * Respond with a redirect to another url. 00099 * 00100 * @param[in] http_code The HTTP status code to send (e.g. 307). 00101 * @param[in] url The url to redirect to. 00102 * 00103 * @return ok or reason for failure. 00104 */ 00105 virtual util::Status SendRedirect( 00106 int http_code, const StringPiece& url); 00107 00108 /* 00109 * Respond with an specified content type and body. 00110 * 00111 * @param[in] content_type The MIME content type of the body. 00112 * @param[in] http_code The HTTP status code to send. 00113 * @param[in] body The payload can be empty. 00114 * 00115 * @return ok or reason for failure. 00116 */ 00117 virtual util::Status SendReply( 00118 const StringPiece& content_type, 00119 int http_code, 00120 const StringPiece& body) = 0; 00121 00122 /* 00123 * Adds a custom header to the repsonse. 00124 * 00125 * Content-Type, Content-Length and Location headers are automatically added. 00126 * This will not check the header names or values. 00127 * 00128 * @param[in] name The name of header to add. 00129 * @param[in] value The value of the header. 00130 */ 00131 virtual util::Status AddHeader( 00132 const StringPiece& name, const StringPiece& value) = 0; 00133 00134 /* 00135 * Adds a custom cookie to the repsonse. 00136 * 00137 * This will not check the cookie names or values. 00138 * 00139 * @param[in] name The name of header to add. 00140 * @param[in] value The value of the header. 00141 */ 00142 virtual util::Status AddCookie( 00143 const StringPiece& name, const StringPiece& value) = 0; 00144 00145 private: 00146 DISALLOW_COPY_AND_ASSIGN(WebServerResponse); 00147 }; 00148 00149 /* 00150 * Abstract class for invocations into the AbstractWebServer 00151 * @ingroup PlatformLayerWebServer 00152 * 00153 * This is different from the HttpRequest class in the transport layer 00154 * which are client-side requests. These are server side requests. 00155 * 00156 * Requests are created by the AbstractWebServer when it receives an 00157 * invocation. 00158 */ 00159 class WebServerRequest { 00160 public: 00161 /* 00162 * Standard constructor. 00163 * 00164 * @param[in] method The HTTP method called (e.g. GET). 00165 * @param[in] url The url that was invoked. 00166 * @param[in] response_storage The repsonse object to bind to the request. 00167 */ 00168 WebServerRequest( 00169 const StringPiece& method, 00170 const StringPiece& url, 00171 WebServerResponse* response_storage); 00172 00173 /* 00174 * Standard destructor. 00175 */ 00176 virtual ~WebServerRequest(); 00177 00178 const string& method() const { return method_; } 00179 const ParsedUrl& parsed_url() const { return parsed_url_; } 00180 WebServerResponse* response() const { return response_.get(); } 00181 00182 virtual bool GetCookieValue(const char* key, string* value) const = 0; 00183 virtual bool GetHeaderValue(const char* key, string* value) const = 0; 00184 00185 private: 00186 string method_; 00187 ParsedUrl parsed_url_; 00188 scoped_ptr<WebServerResponse> response_; 00189 }; 00190 00191 /* 00192 * A minimal abstract interface for embedded webservers. 00193 * @ingroup PlatformLayerWebServer 00194 * 00195 * This is only an abstract interface. You must supply 00196 * your own implementation and use this class to adapt it. The interface 00197 * is only intended to provide some library code and sample code that integrate 00198 * with an embedded web server without explicitly depending on any particular 00199 * implementation. 00200 * 00201 * Note that this interface does not accomodate POST requests at this time, 00202 * but the library does not need it as a client -- this abstractionis not 00203 * intended to be used for implementing cloud services. 00204 */ 00205 class AbstractWebServer { 00206 public: 00207 /* 00208 * Used to register a callback on particular URIs or trees. 00209 * 00210 * @param[in] request for the request being processed. 00211 * @return ok or reason for failure. 00212 */ 00213 typedef ResultCallback1< util::Status, WebServerRequest*> PathHandler; 00214 00215 /* 00216 * Constructs an http server on the given port 00217 * 00218 * @param[in] port Should be non-0. 00219 */ 00220 explicit AbstractWebServer(int port); 00221 00222 /* 00223 * Standard destructor. 00224 */ 00225 virtual ~AbstractWebServer(); 00226 00227 /* 00228 * Returns the port bound in the constructor. 00229 */ 00230 int port() const { return port_; } 00231 00232 /* 00233 * Starts the server. 00234 * 00235 * @return ok or reason for error. 00236 */ 00237 util::Status Startup(); 00238 00239 /* 00240 * Stops the server. 00241 * 00242 * @return ok or reason for error. 00243 */ 00244 void Shutdown(); 00245 00246 /* 00247 * Returns URL into this server for the given path. 00248 * 00249 * @param[in] use_localhost If true use 'localhost' rather than the hostname. 00250 * @param[in] path The path part of the url to build. 00251 */ 00252 string MakeEndpointUrl(bool use_localhost, const StringPiece& path) const; 00253 00254 /* 00255 * Inject handler for path. 00256 * 00257 * @param[in] path The path to intercept with this handler. 00258 * @param[in] handler A repeatable callback. Ownership is passed. 00259 * 00260 * This is called by the default DoHandleUrl method. 00261 */ 00262 void AddPathHandler(const string& path, PathHandler* handler); 00263 00264 /* 00265 * Looks up added PathHandler that matches path. 00266 * 00267 * Searches in the order they were added. 00268 * 00269 * @param[in] request The request to lookup. 00270 * @return path handler or NULL if one could not be found. 00271 */ 00272 PathHandler* FindPathHandler(WebServerRequest* request) const; 00273 00274 /* 00275 * Returns the protocol part of the url used by this webserver (e.g. 'https') 00276 */ 00277 virtual string url_protocol() const; 00278 00279 protected: 00280 virtual util::Status DoStartup() = 0; 00281 virtual void DoShutdown() = 0; 00282 00283 /* 00284 * Handles inbound request. 00285 * 00286 * The base class method looks up a registered path handler that matches 00287 * the url path prefix. It returns a 404 if one isnt found. 00288 * 00289 * @param[in] request The request from the web server. 00290 */ 00291 virtual util::Status DoHandleRequest(WebServerRequest* request); 00292 00293 private: 00294 int port_; 00295 00296 typedef pair<string, PathHandler*> Hook; 00297 vector<Hook> hooks_; 00298 00299 DISALLOW_COPY_AND_ASSIGN(AbstractWebServer); 00300 }; 00301 00302 } // namespace client 00303 00304 } // namespace googleapis 00305 #endif // APISERVING_CLIENTS_CPP_UTIL_ABSTRACT_WEBSERVER_H_