std::string request(http::client &client, http::method method, const std::string &userPath) { CURLcode code; char buf[http::MAX_URL_LEN + 1] = {0}; struct curl_slist *headers = NULL; CURL *curl = NULL; std::string path = userPath; net::uri uri = client.uri(); std::string content = client.content(); std::string response; curl = curl_easy_init(); if (curl == NULL) { throw socket_exception("unable to initialize curl request"); } // check if a path was specified if (path.empty()) { path = uri.full_path(); } if (path.empty()) { snprintf(buf, http::MAX_URL_LEN, "%s://%s", uri.scheme().c_str(), uri.host_with_port().c_str()); } else if (path[0] == '/') { snprintf(buf, http::MAX_URL_LEN, "%s://%s%s", uri.scheme().c_str(), uri.host_with_port().c_str(), path.c_str()); } else { snprintf(buf, http::MAX_URL_LEN, "%s://%s/%s", uri.scheme().c_str(), uri.host_with_port().c_str(), path.c_str()); } helper::curl_set_opt(curl, CURLOPT_URL, buf); helper::curl_set_opt_fun(curl, CURLOPT_WRITEFUNCTION, helper::curl_append_response_callback); helper::curl_set_opt_num(curl, CURLOPT_HEADER, 1L); #ifdef DEBUG helper::curl_set_opt_num(curl, CURLOPT_VERBOSE, 1L); #endif switch (method) { case http::GET: helper::curl_set_opt_num(curl, CURLOPT_HTTPGET, 1L); break; case http::POST: helper::curl_set_opt_num(curl, CURLOPT_POST, 1L); if (!content.empty()) { helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str()); helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size()); } break; case http::PUT: helper::curl_set_opt_num(curl, CURLOPT_PUT, 1L); if (!content.empty()) { helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str()); helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size()); } break; default: helper::curl_set_opt(curl, CURLOPT_CUSTOMREQUEST, http::method_names[method]); break; } for (auto &h : client.headers()) { snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str()); headers = curl_slist_append(headers, buf); } helper::curl_set_opt(curl, CURLOPT_HTTPHEADER, headers); helper::curl_set_opt_num(curl, CURLOPT_TIMEOUT, client.timeout()); helper::curl_set_opt(curl, CURLOPT_WRITEDATA, &response); CURLcode res = curl_easy_perform(curl); curl_slist_free_all(headers); if (res != CURLE_OK && res != CURLE_PARTIAL_FILE) { curl_easy_cleanup(curl); throw socket_exception(curl_easy_strerror(res)); } curl_easy_cleanup(curl); return response; }