Google APIs Client Library for C++
http_types.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines