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 request_headers 59 Request &request_headers(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. urlcoeurl::Request72 std::string_view url() const { return url_; } 73 //! The response in this request. responsecoeurl::Request74 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. error_codecoeurl::Request78 CURLcode error_code() const { return curl_error; } 79 /// @brief Headers for the response 80 /// @sa request_headers response_headerscoeurl::Request81 Headers response_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 header_cb(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 response_headers_; 99 curl_slist *request_headers_ = 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