|
5 | 5 | #include <stdexcept> |
6 | 6 | #include <string> |
7 | 7 |
|
8 | | -HttpResponse HttpRequest::execute() { return client_.execute(*this); } |
| 8 | +// Route to its HttpMethod |
| 9 | +HttpResponse HttpRequest::execute() { |
| 10 | + switch (this->http_method_) { |
| 11 | + case HttpMethod::Get: |
| 12 | + return client_.execute_get(*this); |
| 13 | + case HttpMethod::Head: |
| 14 | + return client_.execute_head(*this); |
| 15 | + default: |
| 16 | + throw std::runtime_error(std::format("No matching enum Http Method")); |
| 17 | + } |
| 18 | +} |
9 | 19 |
|
10 | | -HttpResponse HttpClient::execute(HttpRequest &request) { |
| 20 | +HttpResponse HttpClient::execute_get(HttpRequest &request) { |
11 | 21 | if (!curl_handle) { |
12 | 22 | throw std::runtime_error( |
13 | 23 | // this can happen both when cURL handle is not initialized or when it |
@@ -53,6 +63,50 @@ HttpResponse HttpClient::execute(HttpRequest &request) { |
53 | 63 | return HttpResponse(static_cast<int>(response_code), std::move(buffer)); |
54 | 64 | } |
55 | 65 |
|
| 66 | +HttpResponse HttpClient::execute_head(HttpRequest &request) { |
| 67 | + if (!curl_handle) { |
| 68 | + throw std::runtime_error( |
| 69 | + // this can happen both when cURL handle is not initialized or when it |
| 70 | + // is invalidated in the HTTPClient copy constructor |
| 71 | + "cURL handle is invalid"); |
| 72 | + } |
| 73 | + std::string error_buf; |
| 74 | + |
| 75 | + // TODO(cristian): from libcurl docs, they state that each curl handle has |
| 76 | + // "sticky" params, this is why we are resetting at each get request |
| 77 | + // However, I think we should only do this when moving a new handle the only |
| 78 | + // thing that will change is the URL from now |
| 79 | + // |
| 80 | + // curl_easy_reset(curl_handle); |
| 81 | + |
| 82 | + curl_easy_setopt(curl_handle, CURLOPT_URL, request.getURL().c_str()); |
| 83 | + curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1L); |
| 84 | + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, request.getTimeout()); |
| 85 | + |
| 86 | + // merge client and request headers |
| 87 | + // https://stackoverflow.com/questions/34321719 |
| 88 | + auto headers = request.getHeaders(); |
| 89 | + headers.insert(this->getHeaders().begin(), this->getHeaders().end()); |
| 90 | + struct curl_slist *list = NULL; |
| 91 | + for (const auto &[k, v] : headers) { |
| 92 | + list = curl_slist_append(list, std::format("{}: {}", k, v).c_str()); |
| 93 | + } |
| 94 | + curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, list); |
| 95 | + |
| 96 | + CURLcode code = curl_easy_perform(curl_handle); |
| 97 | + curl_slist_free_all(list); |
| 98 | + if (code != CURLE_OK) { |
| 99 | + throw std::runtime_error( |
| 100 | + std::format("libcurl error for request: {}", curl_easy_strerror(code))); |
| 101 | + } |
| 102 | + |
| 103 | + // HTTP code |
| 104 | + long response_code = 0; |
| 105 | + curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE, &response_code); |
| 106 | + |
| 107 | + return HttpResponse(static_cast<int>(response_code)); |
| 108 | +} |
| 109 | + |
56 | 110 | size_t HttpClient::write_callback(char *ptr, size_t size, size_t nmemb, |
57 | 111 | void *userdata) { |
58 | 112 | std::string *buffer = static_cast<std::string *>(userdata); |
|
0 commit comments