1f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved.
2f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be
3f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// found in the LICENSE file.
4f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_HTTP_HTTP_CONNECTION_CURL_H_
6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_HTTP_HTTP_CONNECTION_CURL_H_
7f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
8f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <map>
9f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <string>
10f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <vector>
11f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
12f2418e562d358917b02b53290d5f4b3690d6f5d3Alex Vakulenko#include <base/macros.h>
139ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/brillo_export.h>
149ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_connection.h>
159ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_transport_curl.h>
16f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <curl/curl.h>
17f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
189ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo {
19f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace http {
20f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace curl {
21f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
22f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// This is a libcurl-based implementation of http::Connection.
239ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkoclass BRILLO_EXPORT Connection : public http::Connection {
24f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko public:
25f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  Connection(CURL* curl_handle,
26f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko             const std::string& method,
27f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko             const std::shared_ptr<CurlInterface>& curl_interface,
28f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko             const std::shared_ptr<http::Transport>& transport);
29f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  ~Connection() override;
30f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
31f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Overrides from http::Connection.
32f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // See http_connection.h for description of these methods.
339ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool SendHeaders(const HeaderList& headers, brillo::ErrorPtr* error) override;
349ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool SetRequestData(StreamPtr stream, brillo::ErrorPtr* error) override;
352eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock  void SetResponseData(StreamPtr stream) override;
369ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool FinishRequest(brillo::ErrorPtr* error) override;
378757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko  RequestID FinishRequestAsync(
388757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko      const SuccessCallback& success_callback,
398757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko      const ErrorCallback& error_callback) override;
40f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
41f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  int GetResponseStatusCode() const override;
42f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string GetResponseStatusText() const override;
43f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string GetProtocolVersion() const override;
44f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string GetResponseHeader(const std::string& header_name) const override;
459ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  StreamPtr ExtractDataStream(brillo::ErrorPtr* error) override;
46f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
47f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko protected:
48f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Write data callback. Used by CURL when receiving response data.
499ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  BRILLO_PRIVATE static size_t write_callback(char* ptr,
509ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                              size_t size,
519ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                              size_t num,
529ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                              void* data);
53f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Read data callback. Used by CURL when sending request body data.
549ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  BRILLO_PRIVATE static size_t read_callback(char* ptr,
559ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                             size_t size,
569ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                             size_t num,
579ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                             void* data);
589ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  // Write header data callback. Used by CURL when receiving response headers.
599ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  BRILLO_PRIVATE static size_t header_callback(char* ptr,
6005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                               size_t size,
6105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                               size_t num,
6205d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko                                               void* data);
63f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
64f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // Helper method to set up the |curl_handle_| with all the parameters
65f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // pertaining to the current connection.
669ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  BRILLO_PRIVATE void PrepareRequest();
67f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko
68f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // HTTP request verb, such as "GET", "POST", "PUT", ...
69f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string method_;
70f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
71f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Binary data for request body.
7280663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko  StreamPtr request_data_stream_;
73f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
74f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Received response data.
752eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock  StreamPtr response_data_stream_;
76f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
77f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // List of optional request headers provided by the caller.
78f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // After request has been sent, contains the received response headers.
79f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  std::multimap<std::string, std::string> headers_;
80f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
81f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // HTTP protocol version, such as HTTP/1.1
82f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string protocol_version_;
83f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Response status text, such as "OK" for 200, or "Forbidden" for 403
84f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string status_text_;
85f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Flag used when parsing response headers to separate the response status
86f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // from the rest of response headers.
87f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  bool status_text_set_{false};
88f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
89f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  CURL* curl_handle_{nullptr};
90f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  curl_slist* header_list_{nullptr};
91f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
92f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  std::shared_ptr<CurlInterface> curl_interface_;
93f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko
94f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko private:
95f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  friend class http::curl::Transport;
96f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(Connection);
97f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko};
98f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
99f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace curl
100f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace http
1019ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko}  // namespace brillo
102f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
103fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif  // LIBBRILLO_BRILLO_HTTP_HTTP_CONNECTION_CURL_H_
104