diff options
author | Alex Vakulenko <avakulenko@google.com> | 2015-10-12 15:21:28 -0700 |
---|---|---|
committer | Alex Vakulenko <avakulenko@google.com> | 2015-10-13 16:10:03 -0700 |
commit | 9ed0cab99f18acb3570a35e9408f24355f6b8324 (patch) | |
tree | 60e3b4c2822b812b3218489a9a6d835df1e8ca6e /brillo/http/http_request.h | |
parent | eabfe23a51c91a103042793ac2d5c28170994e1f (diff) | |
download | platform_external_libbrillo-9ed0cab99f18acb3570a35e9408f24355f6b8324.tar.gz platform_external_libbrillo-9ed0cab99f18acb3570a35e9408f24355f6b8324.tar.bz2 platform_external_libbrillo-9ed0cab99f18acb3570a35e9408f24355f6b8324.zip |
Move chromeos symbols into brillo namespace
And move the include files into "brillo" directory instead of "chromeos"
BUG: 24872993
TEST=built aosp and brillo and unit tests pass on dragonoboard
Change-Id: Ieb979d1ebd3152921d36cd15acbd6247f02aae69
Diffstat (limited to 'brillo/http/http_request.h')
-rw-r--r-- | brillo/http/http_request.h | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/brillo/http/http_request.h b/brillo/http/http_request.h new file mode 100644 index 0000000..b47a50c --- /dev/null +++ b/brillo/http/http_request.h @@ -0,0 +1,381 @@ +// Copyright 2014 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef LIBCHROMEOS_BRILLO_HTTP_HTTP_REQUEST_H_ +#define LIBCHROMEOS_BRILLO_HTTP_HTTP_REQUEST_H_ + +#include <limits> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include <base/macros.h> +#include <brillo/brillo_export.h> +#include <brillo/errors/error.h> +#include <brillo/http/http_connection.h> +#include <brillo/http/http_transport.h> + +namespace brillo { +namespace http { + +// HTTP request verbs +namespace request_type { +BRILLO_EXPORT extern const char kOptions[]; +BRILLO_EXPORT extern const char kGet[]; +BRILLO_EXPORT extern const char kHead[]; +BRILLO_EXPORT extern const char kPost[]; +BRILLO_EXPORT extern const char kPut[]; +BRILLO_EXPORT extern const char kPatch[]; // Non-standard HTTP/1.1 verb +BRILLO_EXPORT extern const char kDelete[]; +BRILLO_EXPORT extern const char kTrace[]; +BRILLO_EXPORT extern const char kConnect[]; +BRILLO_EXPORT extern const char kCopy[]; // Non-standard HTTP/1.1 verb +BRILLO_EXPORT extern const char kMove[]; // Non-standard HTTP/1.1 verb +} // namespace request_type + +// HTTP request header names +namespace request_header { +BRILLO_EXPORT extern const char kAccept[]; +BRILLO_EXPORT extern const char kAcceptCharset[]; +BRILLO_EXPORT extern const char kAcceptEncoding[]; +BRILLO_EXPORT extern const char kAcceptLanguage[]; +BRILLO_EXPORT extern const char kAllow[]; +BRILLO_EXPORT extern const char kAuthorization[]; +BRILLO_EXPORT extern const char kCacheControl[]; +BRILLO_EXPORT extern const char kConnection[]; +BRILLO_EXPORT extern const char kContentEncoding[]; +BRILLO_EXPORT extern const char kContentLanguage[]; +BRILLO_EXPORT extern const char kContentLength[]; +BRILLO_EXPORT extern const char kContentLocation[]; +BRILLO_EXPORT extern const char kContentMd5[]; +BRILLO_EXPORT extern const char kContentRange[]; +BRILLO_EXPORT extern const char kContentType[]; +BRILLO_EXPORT extern const char kCookie[]; +BRILLO_EXPORT extern const char kDate[]; +BRILLO_EXPORT extern const char kExpect[]; +BRILLO_EXPORT extern const char kExpires[]; +BRILLO_EXPORT extern const char kFrom[]; +BRILLO_EXPORT extern const char kHost[]; +BRILLO_EXPORT extern const char kIfMatch[]; +BRILLO_EXPORT extern const char kIfModifiedSince[]; +BRILLO_EXPORT extern const char kIfNoneMatch[]; +BRILLO_EXPORT extern const char kIfRange[]; +BRILLO_EXPORT extern const char kIfUnmodifiedSince[]; +BRILLO_EXPORT extern const char kLastModified[]; +BRILLO_EXPORT extern const char kMaxForwards[]; +BRILLO_EXPORT extern const char kPragma[]; +BRILLO_EXPORT extern const char kProxyAuthorization[]; +BRILLO_EXPORT extern const char kRange[]; +BRILLO_EXPORT extern const char kReferer[]; +BRILLO_EXPORT extern const char kTE[]; +BRILLO_EXPORT extern const char kTrailer[]; +BRILLO_EXPORT extern const char kTransferEncoding[]; +BRILLO_EXPORT extern const char kUpgrade[]; +BRILLO_EXPORT extern const char kUserAgent[]; +BRILLO_EXPORT extern const char kVia[]; +BRILLO_EXPORT extern const char kWarning[]; +} // namespace request_header + +// HTTP response header names +namespace response_header { +BRILLO_EXPORT extern const char kAcceptRanges[]; +BRILLO_EXPORT extern const char kAge[]; +BRILLO_EXPORT extern const char kAllow[]; +BRILLO_EXPORT extern const char kCacheControl[]; +BRILLO_EXPORT extern const char kConnection[]; +BRILLO_EXPORT extern const char kContentEncoding[]; +BRILLO_EXPORT extern const char kContentLanguage[]; +BRILLO_EXPORT extern const char kContentLength[]; +BRILLO_EXPORT extern const char kContentLocation[]; +BRILLO_EXPORT extern const char kContentMd5[]; +BRILLO_EXPORT extern const char kContentRange[]; +BRILLO_EXPORT extern const char kContentType[]; +BRILLO_EXPORT extern const char kDate[]; +BRILLO_EXPORT extern const char kETag[]; +BRILLO_EXPORT extern const char kExpires[]; +BRILLO_EXPORT extern const char kLastModified[]; +BRILLO_EXPORT extern const char kLocation[]; +BRILLO_EXPORT extern const char kPragma[]; +BRILLO_EXPORT extern const char kProxyAuthenticate[]; +BRILLO_EXPORT extern const char kRetryAfter[]; +BRILLO_EXPORT extern const char kServer[]; +BRILLO_EXPORT extern const char kSetCookie[]; +BRILLO_EXPORT extern const char kTrailer[]; +BRILLO_EXPORT extern const char kTransferEncoding[]; +BRILLO_EXPORT extern const char kUpgrade[]; +BRILLO_EXPORT extern const char kVary[]; +BRILLO_EXPORT extern const char kVia[]; +BRILLO_EXPORT extern const char kWarning[]; +BRILLO_EXPORT extern const char kWwwAuthenticate[]; +} // namespace response_header + +// HTTP request status (error) codes +namespace status_code { +// OK to continue with request +static const int Continue = 100; +// Server has switched protocols in upgrade header +static const int SwitchProtocols = 101; + +// Request completed +static const int Ok = 200; +// Object created, reason = new URI +static const int Created = 201; +// Async completion (TBS) +static const int Accepted = 202; +// Partial completion +static const int Partial = 203; +// No info to return +static const int NoContent = 204; +// Request completed, but clear form +static const int ResetContent = 205; +// Partial GET fulfilled +static const int PartialContent = 206; + +// Server couldn't decide what to return +static const int Ambiguous = 300; +// Object permanently moved +static const int Moved = 301; +// Object temporarily moved +static const int Redirect = 302; +// Redirection w/ new access method +static const int RedirectMethod = 303; +// If-Modified-Since was not modified +static const int NotModified = 304; +// Redirection to proxy, location header specifies proxy to use +static const int UseProxy = 305; +// HTTP/1.1: keep same verb +static const int RedirectKeepVerb = 307; + +// Invalid syntax +static const int BadRequest = 400; +// Access denied +static const int Denied = 401; +// Payment required +static const int PaymentRequired = 402; +// Request forbidden +static const int Forbidden = 403; +// Object not found +static const int NotFound = 404; +// Method is not allowed +static const int BadMethod = 405; +// No response acceptable to client found +static const int NoneAcceptable = 406; +// Proxy authentication required +static const int ProxyAuthRequired = 407; +// Server timed out waiting for request +static const int RequestTimeout = 408; +// User should resubmit with more info +static const int Conflict = 409; +// The resource is no longer available +static const int Gone = 410; +// The server refused to accept request w/o a length +static const int LengthRequired = 411; +// Precondition given in request failed +static const int PrecondionFailed = 412; +// Request entity was too large +static const int RequestTooLarge = 413; +// Request URI too long +static const int UriTooLong = 414; +// Unsupported media type +static const int UnsupportedMedia = 415; +// Retry after doing the appropriate action. +static const int RetryWith = 449; + +// Internal server error +static const int InternalServerError = 500; +// Request not supported +static const int NotSupported = 501; +// Error response received from gateway +static const int BadGateway = 502; +// Temporarily overloaded +static const int ServiceUnavailable = 503; +// Timed out waiting for gateway +static const int GatewayTimeout = 504; +// HTTP version not supported +static const int VersionNotSupported = 505; +} // namespace status_code + +class Response; // Just a forward declaration. +class FormData; + +/////////////////////////////////////////////////////////////////////////////// +// Request class is the main object used to set up and initiate an HTTP +// communication session. It is used to specify the HTTP request method, +// request URL and many optional parameters (such as HTTP headers, user agent, +// referer URL and so on. +// +// Once everything is setup, GetResponse() method is used to send the request +// and obtain the server response. The returned Response object can be +// used to inspect the response code, HTTP headers and/or response body. +/////////////////////////////////////////////////////////////////////////////// +class BRILLO_EXPORT Request final { + public: + // The main constructor. |url| specifies the remote host address/path + // to send the request to. |method| is the HTTP request verb and + // |transport| is the HTTP transport implementation for server communications. + Request(const std::string& url, + const std::string& method, + std::shared_ptr<Transport> transport); + ~Request(); + + // Gets/Sets "Accept:" header value. The default value is "*/*" if not set. + void SetAccept(const std::string& accept_mime_types); + const std::string& GetAccept() const; + + // Gets/Sets "Content-Type:" header value + void SetContentType(const std::string& content_type); + const std::string& GetContentType() const; + + // Adds additional HTTP request header + void AddHeader(const std::string& header, const std::string& value); + void AddHeaders(const HeaderList& headers); + + // Removes HTTP request header + void RemoveHeader(const std::string& header); + + // Adds a request body. This is not to be used with GET method + bool AddRequestBody(const void* data, size_t size, brillo::ErrorPtr* error); + bool AddRequestBody(StreamPtr stream, brillo::ErrorPtr* error); + + // Adds a request body. This is not to be used with GET method. + // This method also sets the correct content-type of the request, including + // the multipart data boundary. + bool AddRequestBodyAsFormData(std::unique_ptr<FormData> form_data, + brillo::ErrorPtr* error); + + // Adds a stream for the response. Otherwise a MemoryStream will be used. + bool AddResponseStream(StreamPtr stream, brillo::ErrorPtr* error); + + // Makes a request for a subrange of data. Specifies a partial range with + // either from beginning of the data to the specified offset (if |bytes| is + // negative) or from the specified offset to the end of data (if |bytes| is + // positive). + // All individual ranges will be sent as part of "Range:" HTTP request header. + void AddRange(int64_t bytes); + + // Makes a request for a subrange of data. Specifies a full range with + // start and end bytes from the beginning of the requested data. + // All individual ranges will be sent as part of "Range:" HTTP request header. + void AddRange(uint64_t from_byte, uint64_t to_byte); + + // Returns the request URL + const std::string& GetRequestURL() const; + + // Returns the request verb. + const std::string& GetRequestMethod() const; + + // Gets/Sets a request referer URL (sent as "Referer:" request header). + void SetReferer(const std::string& referer); + const std::string& GetReferer() const; + + // Gets/Sets a user agent string (sent as "User-Agent:" request header). + void SetUserAgent(const std::string& user_agent); + const std::string& GetUserAgent() const; + + // Sends the request to the server and blocks until the response is received, + // which is returned as the response object. + // In case the server couldn't be reached for whatever reason, returns + // empty unique_ptr (null). In such a case, the additional error information + // can be returned through the optional supplied |error| parameter. + std::unique_ptr<Response> GetResponseAndBlock(brillo::ErrorPtr* error); + + // Sends out the request and invokes the |success_callback| when the response + // is received. In case of an error, the |error_callback| is invoked. + // Returns the ID of the asynchronous request created. + RequestID GetResponse(const SuccessCallback& success_callback, + const ErrorCallback& error_callback); + + private: + friend class HttpRequestTest; + + // Helper function to create an http::Connection and send off request headers. + BRILLO_PRIVATE bool SendRequestIfNeeded(brillo::ErrorPtr* error); + + // Implementation that provides particular HTTP transport. + std::shared_ptr<Transport> transport_; + + // An established connection for adding request body. This connection + // is maintained by the request object after the headers have been + // sent and before the response is requested. + std::shared_ptr<Connection> connection_; + + // Full request URL, such as "http://www.host.com/path/to/object" + const std::string request_url_; + // HTTP request verb, such as "GET", "POST", "PUT", ... + const std::string method_; + + // Referrer URL, if any. Sent to the server via "Referer: " header. + std::string referer_; + // User agent string, if any. Sent to the server via "User-Agent: " header. + std::string user_agent_; + // Content type of the request body data. + // Sent to the server via "Content-Type: " header. + std::string content_type_; + // List of acceptable response data types. + // Sent to the server via "Accept: " header. + std::string accept_ = "*/*"; + + // List of optional request headers provided by the caller. + std::multimap<std::string, std::string> headers_; + // List of optional data ranges to request partial content from the server. + // Sent to the server as "Range: " header. + std::vector<std::pair<uint64_t, uint64_t>> ranges_; + + // range_value_omitted is used in |ranges_| list to indicate omitted value. + // E.g. range (10,range_value_omitted) represents bytes from 10 to the end + // of the data stream. + const uint64_t range_value_omitted = std::numeric_limits<uint64_t>::max(); + + DISALLOW_COPY_AND_ASSIGN(Request); +}; + +/////////////////////////////////////////////////////////////////////////////// +// Response class is returned from Request::GetResponse() and is a way +// to get to response status, error codes, response HTTP headers and response +// data (body) if available. +/////////////////////////////////////////////////////////////////////////////// +class BRILLO_EXPORT Response final { + public: + explicit Response(const std::shared_ptr<Connection>& connection); + ~Response(); + + // Returns true if server returned a success code (status code below 400). + bool IsSuccessful() const; + + // Returns the HTTP status code (e.g. 200 for success) + int GetStatusCode() const; + + // Returns the status text (e.g. for error 403 it could be "NOT AUTHORIZED"). + std::string GetStatusText() const; + + // Returns the content type of the response data. + std::string GetContentType() const; + + // Returns response data stream by transferring ownership of the data stream + // from Response class to the caller. + StreamPtr ExtractDataStream(ErrorPtr* error); + + // Extracts the data from the underlying response data stream as a byte array. + std::vector<uint8_t> ExtractData(); + + // Extracts the data from the underlying response data stream as a string. + std::string ExtractDataAsString(); + + // Returns a value of a given response HTTP header. + std::string GetHeader(const std::string& header_name) const; + + private: + friend class HttpRequestTest; + + std::shared_ptr<Connection> connection_; + + DISALLOW_COPY_AND_ASSIGN(Response); +}; + +} // namespace http +} // namespace brillo + +#endif // LIBCHROMEOS_BRILLO_HTTP_HTTP_REQUEST_H_ |