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 // Common type declarations for http_transport layer. 00022 // These are really here to get around cross-include dependencies where 00023 // the header guard would prevent getting at definitions. 00024 00025 #ifndef APISERVING_CLIENTS_CPP_TRANSPORT_HTTP_TYPES_H_ 00026 #define APISERVING_CLIENTS_CPP_TRANSPORT_HTTP_TYPES_H_ 00027 00028 #include <map> 00029 using std::map; 00030 #include <string> 00031 using std::string; 00032 #include "googleapis/base/callback.h" 00033 #include "googleapis/base/macros.h" 00034 #include "googleapis/base/mutex.h" 00035 #include "googleapis/base/thread_annotations.h" 00036 #include "googleapis/strings/case.h" 00037 #include "googleapis/util/status.h" 00038 namespace googleapis { 00039 00040 namespace client { 00041 00042 class HttpRequest; 00043 class HttpResponse; 00044 00045 /* 00046 * Comparator for using headers in standard template library collections. 00047 * 00048 * Puts certain headers before others and case-insensitive compares the rest. 00049 */ 00050 struct RequestHeaderLess { 00051 /* 00052 * Constructor is overloaded to perform some global initialization. 00053 */ 00054 RequestHeaderLess(); 00055 00056 /* 00057 * Compares headers for sort-order. 00058 * 00059 * @param[in] a Name of first header. 00060 * @param[in] b Name of second header. 00061 * @return true if a should be sorted before b, false otherwise. 00062 */ 00063 bool operator()(const string& a, const string& b) const; 00064 }; 00065 00066 /* 00067 * Collection of HTTP headers (without repeated headers). 00068 * @ingroup TransportLayerCore 00069 * 00070 * The map is keyed by case-insensitive header naem. 00071 * The values are the header values. 00072 */ 00073 typedef std::map<string, string, RequestHeaderLess> HttpHeaderMap; 00074 00075 /* 00076 * Collection of HTTP headers (allows repeated header values). 00077 * @ingroup TransportLayerCore 00078 * 00079 * The map is keyed by case-insensitive header naem. 00080 * The values are the header values. 00081 */ 00082 typedef std::multimap<string, string, StringCaseLess> HttpHeaderMultiMap; 00083 00084 /* 00085 * Denotes a callback function that takes an HttpRequest* parameter. 00086 * @ingroup TransportLayerCore 00087 * 00088 * Request callbacks are used for notification on asynchronous requests. 00089 * Typically the owner maintains ownership of the request. 00090 * If this is called by the ExecuteAsync flow then you can call 00091 * DestroyWhenDone before executing the request and the request will 00092 * be destroyed after the callback is called. 00093 */ 00094 typedef Callback1<HttpRequest*> HttpRequestCallback; 00095 00096 /* 00097 * Specifies per-request options that control its behavior. 00098 * @ingroup TransportLayerCore 00099 */ 00100 class HttpRequestOptions { 00101 public: 00102 /* 00103 * Default constructor. 00104 */ 00105 HttpRequestOptions(); 00106 00107 /* 00108 * Clears the timeout value so requests can be indefnite. 00109 */ 00110 void clear_timeout() { timeout_ms_ = 0; } 00111 00112 /* 00113 * Determine if request can timeout. 00114 * @return false if request will never timeout. 00115 */ 00116 bool has_timeout() const { return timeout_ms_ != 0; } 00117 00118 /* 00119 * Specify timeout, in milliseconds. 00120 * 00121 * The precision of the timeout is left to the actual transport used. 00122 * 00123 * @param[in] ms 0 indicates request will never timeout. 00124 */ 00125 void set_timeout_ms(int64 ms) { timeout_ms_ = ms; } 00126 00127 /* 00128 * Get specified timeout, in milliseconds. 00129 * @return 0 if there is no timeout. 00130 */ 00131 int64 timeout_ms() const { return timeout_ms_; } 00132 00133 /* 00134 * Set maximum permissable retries. 00135 * 00136 * This is only applicable for situations in which the application 00137 * chooses to attempt to retry sending a request. These do not include 00138 * redirects. 00139 * 00140 * @param[in] n 0 will not attempt any retries. 00141 * 00142 * @see HttpRequest 00143 * @see max_redirects 00144 */ 00145 void set_max_retries(int n) { max_retries_ = n; } 00146 00147 /* 00148 * Get specified max permissable retries. 00149 */ 00150 int max_reries() const { return max_retries_; } 00151 00152 /* 00153 * Get specified maximum permissable redirects. 00154 */ 00155 int max_redirects() const { return max_redirects_; } 00156 00157 /* 00158 * Set maximum permissable redirects. 00159 * 00160 * @param[in] n 0 will not follow any redirets. 00161 * Maximum number of redirects to follow when sending requests. 00162 */ 00163 void set_max_redirects(int n) { max_redirects_ = n; } 00164 00165 /* 00166 * Determine if request will self-destruct when done. 00167 * 00168 * @return false Will not self destruct. 00169 */ 00170 bool destroy_when_done() const { return destroy_when_done_; } 00171 00172 /* 00173 * Specify whether to self-destruct when done. 00174 * @param[in] destroy false (default) requires explicit destruction. 00175 */ 00176 void set_destroy_when_done(bool destroy) { destroy_when_done_ = destroy; } 00177 00178 private: 00179 int64 timeout_ms_; 00180 int max_retries_; 00181 int max_redirects_; 00182 bool destroy_when_done_; //< Default is false. 00183 }; 00184 00185 /* 00186 * Denotes the current state of an HttpRequest's lifecycel. 00187 * @ingroup TransportLayerCore 00188 * 00189 * The state includes the StateCode in its state machine progress as 00190 * well as status and response data. Normally the state is created as 00191 * an attribute to an HttpRequest or HttpResponse -- you do not typically 00192 * instantiate these directly yourself. 00193 * 00194 * The state is shared between an HttpRequest and its HttpResponse such 00195 * that it is accessible by either. It will remain valid until both the 00196 * request and response have been destroyed. 00197 * 00198 * This class is thread-safe. 00199 */ 00200 class HttpRequestState { 00201 public: 00202 /* 00203 * Denotes a state in the HttpRequest lifecycle. 00204 * 00205 * <table> 00206 * <tr><th>State Code <th>Done<th>Ok 00207 * <th>Description 00208 * <th>Possible Transitions 00209 * <tr><td>UNSENT <td>- <td>Y 00210 * <td>The request has not yet been sent. 00211 * <TD>QUEUED, PENDING, COULD_NOT_SEND, CANCELLED 00212 * <tr><td>QUEUED <td>- <td>Y 00213 * <td>The request has been queued to send (async) 00214 * but has not yet been sent. 00215 * <td>PENDING, COULD_NOT_SEND, CANCELLED, 00216 * <tr><td>PENDING <td>- <td>Y 00217 * <td>The request has been sent (either in part or whole) but a 00218 * response has not yet been received. 00219 * <td>COMPLETED, COULD_NOT_SEND, TIMED_OUT, ABORTED 00220 * <tr><td>COMPLETED <td>Y <td>Y 00221 * <td>A response was received from the server. The response might 00222 * have been an HTTP error, but was a valid HTTP response. 00223 * <td>- 00224 * <tr><td>COULD_NOT_SEND <td>Y <td>- 00225 * <td>An error prevented the request from being sent or response 00226 * from being received. 00227 * <td>- 00228 * <tr><td>TIMED_OUT <td>Y <td>- 00229 * <td>Request was sent but timed out before response arrived. 00230 * <td>- 00231 * <tr><td>CANCELLED <td>Y <td>- 00232 * <td>Indicates that the request was cancelled before it was sent. 00233 * <td>- 00234 * <tr><td>ABORTED <td>Y <td>- 00235 * <td>Used to signal callback it will never be called. 00236 * <td>- 00237 * <tr><td>_NUM_STATES_ <td>- <td>- 00238 * <td>An internal marker used to count the nuber of states. 00239 * <td>- 00240 * </table> 00241 */ 00242 enum StateCode { 00243 UNSENT, 00244 QUEUED, 00245 PENDING, 00246 COMPLETED, 00247 COULD_NOT_SEND, 00248 TIMED_OUT, 00249 CANCELLED, 00250 ABORTED, 00251 _NUM_STATES_ 00252 }; 00253 00254 /* 00255 * Standard constructor. 00256 */ 00257 HttpRequestState(); 00258 00259 /* 00260 * Destroys this instance. 00261 */ 00262 virtual ~HttpRequestState(); 00263 00264 /* 00265 * Destroys this instance when it is finished waiting. 00266 * 00267 * Will destory immediately if it isnt waiting. 00268 */ 00269 void DestroyWhenDone(); 00270 00271 /* 00272 * Gets lifecycle state code. 00273 * @note Only HttpTransports should set the state attribute. 00274 */ 00275 StateCode state_code() const LOCKS_EXCLUDED(mutex_); 00276 00277 /* 00278 * Transition to a new lifecycle state. 00279 * 00280 * @param[in] code Specifies the new state_code(). 00281 * 00282 * If this transitions into a done() state for the first time then it will 00283 * call the callback, if one has been bound, then signal any threads waiting 00284 * on this state. This method does not cause the instance to be destroyed 00285 * if it was configured to self-destruct; that is up to the caller. 00286 */ 00287 void TransitionAndNotifyIfDone(StateCode code) LOCKS_EXCLUDED(mutex_); 00288 00289 /* 00290 * Transitions the state as applicable based on the transport_status() or 00291 * http_code(). 00292 * 00293 * This function deteremins what the state_code should be based on the 00294 * transport_status() and http_code() values. 00295 * 00296 * An http_code indicating that the HTTP request is no longer outstanding 00297 * will transition into StateCode::COMPLETED (even if the http code is an 00298 * error). Only (specialized) HttpRequest classes should set the http_code 00299 * attribute. 00300 * 00301 * @return The overall request status after the transition. A failure status 00302 * indicates that the HttpRequest failed, not a failure to transition. 00303 */ 00304 util::Status AutoTransitionAndNotifyIfDone() LOCKS_EXCLUDED(mutex_); 00305 00306 /* 00307 * Sets the transport-level status for the request. 00308 * 00309 * The transport-level status can be used to determine whether the 00310 * communication between this client and the service was ok or not 00311 * independent of whether the service was able to actually perform the 00312 * request. HTTP errors are application-level failures, but transport-level 00313 * success because the complete HTTP messaging was able to take place. 00314 * 00315 * @param[in] status The transport-level status. 00316 */ 00317 void set_transport_status(const util::Status& status) 00318 LOCKS_EXCLUDED(mutex_); 00319 00320 /* 00321 * Returns the transport-level status. 00322 * 00323 * @return failure status only if a transport error was encountered. 00324 * The status will be ok in an UNSENT state. 00325 */ 00326 util::Status transport_status() const LOCKS_EXCLUDED(mutex_); 00327 00328 /* 00329 * Returns the overall status for this request. 00330 * 00331 * If the transport_status is a failure, then this status will reflect that. 00332 * If the transport_status is ok then this status will be determined by the 00333 * http_code. Often for HTTP level errors, HttpResponse::body_reader() 00334 * contains additional error information that wont be contained in the 00335 * status. 00336 */ 00337 util::Status status() const LOCKS_EXCLUDED(mutex_); 00338 00339 /* 00340 * Returns the HTTP status code returned in the response. 00341 * 00342 * @pre request_state() == COMPLETED 00343 * @returns 0 if the request_state has not completed, 00344 * including transport errors. 00345 */ 00346 int http_code() const { return http_code_; } 00347 00348 /* 00349 * Sets the HTTP status code returned by the HTTP server 00350 */ 00351 void set_http_code(int http_code) { http_code_ = http_code; } 00352 00353 /* 00354 * Returns whether or not the request has completely finished executing. 00355 * 00356 * @return true if the state denotes done, false otherwise 00357 * @see StateCode 00358 */ 00359 bool done() const LOCKS_EXCLUDED(mutex_); 00360 00361 /* 00362 * Returns whether or not an error has been encountered. 00363 * 00364 * @return true if the state code denotes ok, false otherwise 00365 * @see StateCode 00366 */ 00367 bool ok() const LOCKS_EXCLUDED(mutex_); 00368 00369 /* 00370 * Blocks the callers thread until the state is done (the request completes) 00371 * or the timeout has elapsed. 00372 * 00373 * @param[in] timeout_ms (optional, forever if not specified) 00374 * @return true if the request is done, false if the timeout expired. If 00375 * the request times out then true is returned (because the 00376 * request is done). 00377 * 00378 * If the request had the destroy_when_done option set then it will no 00379 * longer be available, nor will this state instance. Even if false is 00380 * returned, indicating that the request is not done, you should not assume 00381 * that the request or state instance is still valid because it could have 00382 * just completed since this method returned. 00383 */ 00384 bool WaitUntilDone(int64 timeout_ms = kint64max) LOCKS_EXCLUDED(mutex_); 00385 00386 /* 00387 * Gets the respose objecta associated with the request. 00388 */ 00389 HttpResponse* response() const LOCKS_EXCLUDED(mutex_); 00390 00391 private: 00392 friend class HttpRequest; 00393 00394 void Reset(); 00395 00396 bool has_notify_callback() LOCKS_EXCLUDED(mutex_) { 00397 MutexLock l(&mutex_); 00398 return callback_ != NULL; 00399 } 00400 00401 void set_notify_callback( 00402 HttpRequest* request, HttpRequestCallback* callback) 00403 LOCKS_EXCLUDED(mutex_); 00404 00405 private: 00406 mutable Mutex mutex_; 00407 mutable CondVar condvar_; 00408 util::Status transport_status_ GUARDED_BY(mutex_); 00409 StateCode state_code_ GUARDED_BY(mutex_); 00410 int http_code_; 00411 int waiting_ GUARDED_BY(mutex_); 00412 bool destroy_when_done_ GUARDED_BY(mutex_); 00413 00414 // Paired with callback_. 00415 // Null when callback_ is NULL. 00416 HttpRequest* request_ GUARDED_BY(mutex_); 00417 00418 // Can be NULL. Single-use is permissible. Not owned. Only used 00419 // for async invocation. 00420 HttpRequestCallback* callback_ GUARDED_BY(mutex_); 00421 00422 bool UnsafeWaitUntilDone(int64 timeout_ms) EXCLUSIVE_LOCKS_REQUIRED(mutex_); 00423 00424 DISALLOW_COPY_AND_ASSIGN(HttpRequestState); 00425 }; 00426 00427 /* 00428 * This is a helper class for interpreting standard HTTP status codes. 00429 * @ingroup TransportLayerCore 00430 * 00431 * It is not meant to be instantiated. 00432 */ 00433 class HttpStatusCode { 00434 public: 00435 /* 00436 * Symbolic names for some common HTTP Stauts Codes of interest. 00437 * 00438 * The list here is not a complete enumeration of http_code values. It 00439 * only enumerates the standard codes that are of particular itnerest within 00440 * this library or might be commonly checked by consumers. 00441 * 00442 * See <a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html'> 00443 * Section 10 of RFC 2616</a> for a complete list of standard status codes. 00444 */ 00445 enum HttpStatus { 00446 OK = 200, 00447 NO_CONTENT = 204, 00448 MULTIPLE_CHOICES = 300, 00449 MOVED_PERMANENTLY = 301, 00450 FOUND = 302, 00451 SEE_OTHER = 303, 00452 NOT_MODIFIED = 304, 00453 TEMPORARY_REDIRECT = 307, 00454 BAD_REQUEST = 400, 00455 UNAUTHORIZED = 401, 00456 FORBIDDEN = 403, 00457 NOT_FOUND = 404, 00458 NOT_ALLOWED = 405, 00459 NOT_ACCEPTABLE = 406, 00460 REQUEST_TIMEOUT = 408, 00461 SERVER_ERROR = 500, 00462 SERVICE_UNAVAILABLE = 503, 00463 }; 00464 00465 /* 00466 * Returns true if the given HTTP status code indicates an HTTP Redirect. 00467 * 00468 * @param[in] http_code Denotes an HTTP status code 00469 * @return true if the code indicates a standard type of redirect 00470 * (300..303, 305..307). 00471 */ 00472 static bool IsRedirect(int http_code) { 00473 // HTTP 1.1 only defines 300-307 00474 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 00475 return http_code >= 300 && http_code <= 307 && http_code != 304; 00476 } 00477 00478 /* 00479 * Returns true if the given HTTP status code indicates a successful request. 00480 * 00481 * @param[in] http_code Denotes an HTTP status code. 00482 * @return true if the code is a 2xx series response code (200..299) 00483 */ 00484 static bool IsOk(int http_code) { 00485 return http_code >= 200 && http_code < 300; 00486 } 00487 00488 /* 00489 * Returns true if the given HTTP status code indicates an informational 00490 * response. 00491 * 00492 * @param[in] http_code Denotes an HTTP status code. 00493 * @return true if the code is a 1xx series response code (100..199) 00494 */ 00495 static bool IsInformational(int http_code) { 00496 return http_code >= 100 && http_code < 200; 00497 } 00498 00499 private: 00500 HttpStatusCode(); 00501 ~HttpStatusCode(); 00502 }; 00503 00504 } // namespace client 00505 00506 } // namespace googleapis 00507 #endif // APISERVING_CLIENTS_CPP_TRANSPORT_HTTP_TYPES_H_