| 1 | #pragma once |
| 2 | |
| 3 | /// @file |
| 4 | /// @brief Include for the @ref coeurl::Request |
| 5 | |
| 6 | #include <functional> |
| 7 | #include <string> |
| 8 | |
| 9 | #include <curl/curl.h> |
| 10 | |
| 11 | #include "headers.hpp" |
| 12 | |
| 13 | namespace coeurl { |
| 14 | struct Client; |
| 15 | |
| 16 | /// @brief A HTTP request. |
| 17 | /// |
| 18 | /// Can be sent using a @ref Client |
| 19 | /// You can listen to various events here and access the response, after it |
| 20 | /// finished. |
| 21 | struct Request { |
| 22 | //! The different HTTP methods. |
| 23 | enum class Method { |
| 24 | Delete, //!< HTTP DELETE |
| 25 | Get, //!< HTTP GET |
| 26 | Head, //!< HTTP HEAD |
| 27 | Options, //!< HTTP OPTIONS |
| 28 | Patch, //!< HTTP PATCH |
| 29 | Post, //!< HTTP POST |
| 30 | Put, //!< HTTP PUT |
| 31 | }; |
| 32 | |
| 33 | /// @brief construct a new request to @a url. |
| 34 | /// @param url The URL to request. |
| 35 | /// @param client The client to use. |
| 36 | /// @param method The http method for this request. Usually GET. |
| 37 | Request(Client *client, Method method, std::string url); |
| 38 | //! Cleans up a request. |
| 39 | ~Request(); |
| 40 | //! Uncopyable |
| 41 | Request(Request const &) = delete; |
| 42 | //! Uncopyable |
| 43 | void operator=(Request const &) = delete; |
| 44 | //! Unmoveable |
| 45 | Request(Request &&) = delete; |
| 46 | //! Unmoveable |
| 47 | void operator=(Request &&) = delete; |
| 48 | |
| 49 | //! The maximum number of redirects. Defaults to 0. |
| 50 | Request &max_redirects(long amount); |
| 51 | //! Whether to verify the certificate of the peer. Defaults to whatever is |
| 52 | //! set on the client (usually true). |
| 53 | Request &verify_peer(bool verify); |
| 54 | //! The actual request body. \a contenttype defaults to |
| 55 | //! "application/octet-stream". |
| 56 | Request &request(std::string r, std::string contenttype = "application/octet-stream" ); |
| 57 | /// @brief Headers for this request. |
| 58 | /// @sa response_headers() const |
| 59 | Request &(const Headers &h); |
| 60 | //! Timeout connection after the specified amount of seconds, if the server |
| 61 | //! stops sending acks. |
| 62 | Request &connection_timeout(long t); |
| 63 | |
| 64 | //! Optional completion handler. |
| 65 | Request &on_complete(const std::function<void(const Request &)> handler); |
| 66 | //! Optional upload progress handler. |
| 67 | Request &on_upload_progress(std::function<void(size_t progress, size_t total)> handler); |
| 68 | //! Optional download progress handler. |
| 69 | Request &on_download_progess(std::function<void(size_t progress, size_t total)> handler); |
| 70 | |
| 71 | //! The url for this request. |
| 72 | std::string_view url() const { return url_; } |
| 73 | //! The response in this request. |
| 74 | std::string_view response() const { return response_; } |
| 75 | //! The HTTP response code. 200 for success. |
| 76 | int response_code() const; |
| 77 | //! The curl error code. CURLE_OK (0) on success. |
| 78 | CURLcode error_code() const { return curl_error; } |
| 79 | /// @brief Headers for the response |
| 80 | /// @sa request_headers(const Headers &) |
| 81 | Headers () const { return response_headers_; } |
| 82 | |
| 83 | private: |
| 84 | /* CURLOPT_WRITEFUNCTION */ |
| 85 | static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data); |
| 86 | /* CURLOPT_READFUNCTION */ |
| 87 | static size_t read_cb(char *buffer, size_t size, size_t nitems, void *data); |
| 88 | /* CURLOPT_HEADERFUNCTION */ |
| 89 | static size_t (char *buffer, size_t size, size_t nitems, void *data); |
| 90 | /* CURLOPT_PROGRESSFUNCTION */ |
| 91 | static int prog_cb(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ult, curl_off_t uln); |
| 92 | |
| 93 | CURL *easy; |
| 94 | std::string request_; |
| 95 | std::string request_contenttype_; |
| 96 | std::string response_; |
| 97 | std::string url_; |
| 98 | Headers ; |
| 99 | curl_slist * = nullptr; |
| 100 | |
| 101 | Client *global; |
| 102 | size_t readoffset = 0; |
| 103 | char error[CURL_ERROR_SIZE]; |
| 104 | |
| 105 | enum class Status { |
| 106 | Running, |
| 107 | Canceled, |
| 108 | Done, |
| 109 | } status = Status::Running; |
| 110 | CURLcode curl_error = CURLcode::CURLE_OK; |
| 111 | Method method = Method::Get; |
| 112 | |
| 113 | long connection_timeout_ = 0; |
| 114 | |
| 115 | std::function<void(const Request &)> on_complete_; |
| 116 | std::function<void(size_t progress, size_t total)> on_upload_progress_, on_download_progess_; |
| 117 | |
| 118 | friend Client; |
| 119 | }; |
| 120 | } // namespace coeurl |
| 121 | |