aboutsummaryrefslogtreecommitdiffstats
path: root/brillo/http/http_transport_curl.h
diff options
context:
space:
mode:
Diffstat (limited to 'brillo/http/http_transport_curl.h')
-rw-r--r--brillo/http/http_transport_curl.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/brillo/http/http_transport_curl.h b/brillo/http/http_transport_curl.h
new file mode 100644
index 0000000..e07f56f
--- /dev/null
+++ b/brillo/http/http_transport_curl.h
@@ -0,0 +1,140 @@
+// 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_TRANSPORT_CURL_H_
+#define LIBCHROMEOS_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_
+
+#include <map>
+#include <string>
+#include <utility>
+
+#include <base/memory/weak_ptr.h>
+#include <brillo/brillo_export.h>
+#include <brillo/http/curl_api.h>
+#include <brillo/http/http_transport.h>
+
+namespace brillo {
+namespace http {
+namespace curl {
+
+class Connection;
+
+///////////////////////////////////////////////////////////////////////////////
+// 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 BRILLO_EXPORT Transport : public http::Transport {
+ public:
+ // Constructs the transport using the current message loop for async
+ // operations.
+ explicit Transport(const std::shared_ptr<CurlInterface>& curl_interface);
+ // Creates a transport object using a proxy.
+ // |proxy| is of the form [protocol://][user:password@]host[:port].
+ // If not defined, protocol is assumed to be http://.
+ Transport(const std::shared_ptr<CurlInterface>& curl_interface,
+ const std::string& proxy);
+ ~Transport() override;
+
+ // Overrides from http::Transport.
+ std::shared_ptr<http::Connection> CreateConnection(
+ const std::string& url,
+ const std::string& method,
+ const HeaderList& headers,
+ const std::string& user_agent,
+ const std::string& referer,
+ brillo::ErrorPtr* error) override;
+
+ void RunCallbackAsync(const tracked_objects::Location& from_here,
+ const base::Closure& callback) override;
+
+ RequestID StartAsyncTransfer(http::Connection* connection,
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) override;
+
+ bool CancelRequest(RequestID request_id) override;
+
+ void SetDefaultTimeout(base::TimeDelta timeout) override;
+
+ // Helper methods to convert CURL error codes (CURLcode and CURLMcode)
+ // into brillo::Error object.
+ static void AddEasyCurlError(brillo::ErrorPtr* error,
+ const tracked_objects::Location& location,
+ CURLcode code,
+ CurlInterface* curl_interface);
+
+ static void AddMultiCurlError(brillo::ErrorPtr* error,
+ const tracked_objects::Location& location,
+ CURLMcode code,
+ CurlInterface* curl_interface);
+
+ private:
+ // Forward-declaration of internal implementation structures.
+ struct AsyncRequestData;
+ class SocketPollData;
+
+ // Initializes CURL for async operation.
+ bool SetupAsyncCurl(brillo::ErrorPtr* error);
+
+ // Stops CURL's async operations.
+ void ShutDownAsyncCurl();
+
+ // Handles all pending async messages from CURL.
+ void ProcessAsyncCurlMessages();
+
+ // Processes the transfer completion message (success or failure).
+ void OnTransferComplete(http::curl::Connection* connection,
+ CURLcode code);
+
+ // Cleans up internal data for a completed/canceled asynchronous operation
+ // on a connection.
+ void CleanAsyncConnection(http::curl::Connection* connection);
+
+ // Called after a timeout delay requested by CURL has elapsed.
+ void OnTimer();
+
+ // Callback for CURL to handle curl_socket_callback() notifications.
+ // The parameters correspond to those of curl_socket_callback().
+ static int MultiSocketCallback(CURL* easy,
+ curl_socket_t s,
+ int what,
+ void* userp,
+ void* socketp);
+
+ // Callback for CURL to handle curl_multi_timer_callback() notifications.
+ // The parameters correspond to those of curl_multi_timer_callback().
+ // CURL actually uses "long" types in callback signatures, so we must comply.
+ static int MultiTimerCallback(CURLM* multi,
+ long timeout_ms, // NOLINT(runtime/int)
+ void* userp);
+
+ std::shared_ptr<CurlInterface> curl_interface_;
+ std::string proxy_;
+ // CURL "multi"-handle for processing requests on multiple connections.
+ CURLM* curl_multi_handle_{nullptr};
+ // A map to find a corresponding Connection* using a request ID.
+ std::map<RequestID, Connection*> request_id_map_;
+ // Stores the connection-specific asynchronous data (such as the success
+ // and error callbacks that need to be called at the end of the async
+ // operation).
+ std::map<Connection*, std::unique_ptr<AsyncRequestData>> async_requests_;
+ // Internal data associated with in-progress asynchronous operations.
+ std::map<std::pair<CURL*, curl_socket_t>, SocketPollData*> poll_data_map_;
+ // The last request ID used for asynchronous operations.
+ RequestID last_request_id_{0};
+ // The connection timeout for the requests made.
+ base::TimeDelta connection_timeout_;
+
+ base::WeakPtrFactory<Transport> weak_ptr_factory_for_timer_{this};
+ base::WeakPtrFactory<Transport> weak_ptr_factory_{this};
+ DISALLOW_COPY_AND_ASSIGN(Transport);
+};
+
+} // namespace curl
+} // namespace http
+} // namespace brillo
+
+#endif // LIBCHROMEOS_BRILLO_HTTP_HTTP_TRANSPORT_CURL_H_