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 | |