buffet: reworked http transport to prepare for unit testing
Changed the way HTTP transport classes are implemented. Now
the Transport class is a very simple factory class that just
creates an appropriate instance of http::Connection object.
http::Connection is a thin layer wrapper around underlying
transport library, such as libcurl.
Also, the Transport class is now stateless and can be used
to initiate multiple HTTP connections.
Majority of HTTP processing is done in http::Request and
http::Response classes which are not dependent on the underlying
transport.
The HTTP utility functions now take the Transport class as
a parameter to facilitate unit tesing.
Also added a stub http_utils_unittest.cc to be populated
with actual tests when the fake HTTP transport is implemented.
BUG=chromium:364733
TEST=Unit tests pass.
Change-Id: If506854d274f725bbc2d6f765f19344d8697a239
Reviewed-on: https://chromium-review.googlesource.com/196153
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/http_transport_curl.h b/buffet/http_transport_curl.h
index 9778b94..f63f815 100644
--- a/buffet/http_transport_curl.h
+++ b/buffet/http_transport_curl.h
@@ -5,155 +5,34 @@
#ifndef BUFFET_HTTP_TRANSPORT_CURL_H_
#define BUFFET_HTTP_TRANSPORT_CURL_H_
-#include <map>
-#include <curl/curl.h>
-
-#include "buffet/http_request.h"
+#include "buffet/http_transport.h"
namespace chromeos {
namespace http {
namespace curl {
///////////////////////////////////////////////////////////////////////////////
-// A particular implementation of TransportInterface that uses libcurl for
-// HTTP communications. This class (as TransportInterface interface)
+// An implementation of http::Transport that uses libcurl for
+// HTTP communications. This class (as http::Transport base)
// is used by http::Request and http::Response classes to provide HTTP
// functionality to the clients.
+// See http_transport.h for more details.
///////////////////////////////////////////////////////////////////////////////
-class Transport : public TransportInterface {
+class Transport : public http::Transport {
public:
- // Standard constructor. |url| is the full request URL with protocol
- // schema, host address, resource path as well as optional query parameters
- // and/or user name/password. |method| is one of HTTP request verbs such as
- // "GET", "POST", etc. If nullptr is specified, "GET" is assumed.
- Transport(const std::string& url, const char* method);
- ~Transport();
+ Transport();
+ virtual ~Transport();
- // Returns the current request/response stage.
- virtual Stage GetStage() const override { return stage_; }
-
- // Implementation of Request::AddRange.
- virtual void AddRange(int64_t bytes) override;
- virtual void AddRange(uint64_t from_byte, uint64_t to_byte) override;
-
- // Implementation of Request::SetAccept/Request::GetAccept.
- virtual void SetAccept(const char* acceptMimeTypes) override {
- accept_ = acceptMimeTypes;
- }
- virtual std::string GetAccept() const override;
-
- // Implementation of Request::GetRequestURL.
- virtual std::string GetRequestURL() const override { return request_url_; }
-
- // Implementation of Request::SetContentType/Request::GetContentType.
- virtual void SetContentType(const char* content_type) override {
- content_type_ = content_type;
- }
- virtual std::string GetContentType() const override { return content_type_; }
-
- // Implementation of Request::AddHeader.
- virtual void AddHeader(const char* header, const char* value) override;
-
- // Implementation of Request::RemoveHeader.
- virtual void RemoveHeader(const char* header) override;
-
- // Implementation of Request::AddRequestBody.
- virtual bool AddRequestBody(const void* data, size_t size) override;
-
- // Implementation of Request::SetMethod/Request::GetMethod.
- virtual void SetMethod(const char* method) override { method_ = method; }
- virtual std::string GetMethod() const override { return method_; }
-
- // Implementation of Request::SetReferer/Request::GetReferer.
- virtual void SetReferer(const char* referer) override { referer_ = referer; }
- virtual std::string GetReferer() const override { return referer_; }
-
- // Implementation of Request::SetUserAgent/Request::GetUserAgent.
- virtual void SetUserAgent(const char* user_agent) override {
- user_agent_ = user_agent;
- }
- virtual std::string GetUserAgent() const override { return user_agent_; }
-
- // Sends the HTTP request to the server. Used by Request::GetResponse().
- virtual bool Perform() override;
-
- // Implementation of Response::GetStatusCode.
- virtual int GetResponseStatusCode() const override;
-
- // Implementation of Response::GetStatusText.
- virtual std::string GetResponseStatusText() const override {
- return status_text_;
- }
-
- // Implementation of Response::GetHeader.
- virtual std::string GetResponseHeader(const char* header_name) const override;
-
- // Implementation of Response::GetData.
- virtual const std::vector<unsigned char>& GetResponseData() const override;
-
- // Implementation of Response::GetErrorMessage.
- virtual std::string GetErrorMessage() const override { return error_; }
-
- // Closes the connection and frees up internal data
- virtual void Close() override;
+ virtual std::unique_ptr<http::Connection> CreateConnection(
+ std::shared_ptr<http::Transport> transport,
+ const std::string& url,
+ const std::string& method,
+ const HeaderList& headers,
+ const std::string& user_agent,
+ const std::string& referer,
+ std::string* error_msg) override;
private:
- HeaderList GetHeaders() const;
-
- // Write data callback. Used by CURL when receiving response data.
- static size_t write_callback(char* ptr, size_t size, size_t num, void* data);
- // Read data callback. Used by CURL when sending request body data.
- static size_t read_callback(char* ptr, size_t size, size_t num, void* data);
- // Write header data callback. Used by CURL when receiving response headers.
- static size_t header_callback(char* ptr, size_t size, size_t num, void* data);
-
- // Full request URL, such as "http://www.host.com/path/to/object"
- std::string request_url_;
- // HTTP request verb, such as "GET", "POST", "PUT", ...
- 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.
- // After request has been sent, contains the received response headers.
- std::map<std::string, std::string> headers_;
- // List of optional data ranges to request partial content from the server.
- // Sent to thr server as "Range: " header.
- std::vector<std::pair<uint64_t, uint64_t>> ranges_;
- // Binary data for request body.
- std::vector<unsigned char> request_data_;
- // Read pointer for request data. Used when streaming data to the server.
- size_t request_data_ptr_ = 0;
-
- // Received response data.
- std::vector<unsigned char> response_data_;
-
- // Current progress stage.
- Stage stage_ = Stage::failed;
- // CURL error message in case request fails completely.
- std::string error_;
- // Reponse status text, such as "OK" for 200, or "Forbidden" for 403
- std::string status_text_;
- // Flag used when parsing response headers to separate the response status
- // from the rest of response headers.
- bool status_text_set_ = false;
-
- // 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.
- static const uint64_t range_value_omitted = (uint64_t)-1;
-
- CURL* curl_handle_ = nullptr;
-
DISALLOW_COPY_AND_ASSIGN(Transport);
};