Mercurial > hg > orthanc
diff Core/HttpClient.cpp @ 2040:6ea2e264ca50
retrieval of HTTP headers in answers within HttpClient
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 21 Jun 2016 16:34:30 +0200 |
parents | e7e1858d9504 |
children | 9f61ca1e3eb3 |
line wrap: on
line diff
--- a/Core/HttpClient.cpp Tue Jun 21 15:17:49 2016 +0200 +++ b/Core/HttpClient.cpp Tue Jun 21 16:34:30 2016 +0200 @@ -36,6 +36,7 @@ #include "Toolbox.h" #include "OrthancException.h" #include "Logging.h" +#include "ChunkedBuffer.h" #include <string.h> #include <curl/curl.h> @@ -218,18 +219,51 @@ static size_t CurlBodyCallback(void *buffer, size_t size, size_t nmemb, void *payload) { - std::string& target = *(static_cast<std::string*>(payload)); + ChunkedBuffer& target = *(static_cast<ChunkedBuffer*>(payload)); + + size_t length = size * nmemb; + if (length == 0) + { + return 0; + } + else + { + target.AddChunk(buffer, length); + return length; + } + } + + + static size_t CurlHeaderCallback(void *buffer, size_t size, size_t nmemb, void *payload) + { + HttpClient::HttpHeaders& headers = *(static_cast<HttpClient::HttpHeaders*>(payload)); size_t length = size * nmemb; if (length == 0) + { return 0; - - size_t pos = target.size(); + } + else + { + std::string s(reinterpret_cast<const char*>(buffer), length); + std::size_t colon = s.find(':'); + std::size_t eol = s.find("\r\n"); + if (colon != std::string::npos && + eol != std::string::npos) + { + std::string tmp; + Toolbox::ToLowerCase(tmp, s.substr(0, colon)); + std::string key = Toolbox::StripSpaces(tmp); - target.resize(pos + length); - memcpy(&target.at(pos), buffer, length); + if (!key.empty()) + { + std::string value = Toolbox::StripSpaces(s.substr(colon + 1, eol)); + headers[key] = value; + } + } - return length; + return length; + } } @@ -354,11 +388,22 @@ } - bool HttpClient::ApplyInternal(std::string& answer) + bool HttpClient::ApplyInternal(std::string& answer, + HttpHeaders* headers) { answer.clear(); CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str())); - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &answer)); + + if (headers == NULL) + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, NULL)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, NULL)); + } + else + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, &CurlHeaderCallback)); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, headers)); + } #if ORTHANC_SSL_ENABLED == 1 // Setup HTTPS-related options @@ -520,6 +565,9 @@ CURLcode code; long status = 0; + ChunkedBuffer buffer; + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &buffer)); + if (boost::starts_with(url_, "https://")) { code = OrthancHttpClientPerformSSL(pimpl_->curl_, &status); @@ -543,8 +591,13 @@ bool success = (status >= 200 && status < 300); - if (!success) + if (success) { + buffer.Flatten(answer); + } + else + { + answer.clear(); LOG(INFO) << "Error in HTTP request, received HTTP status " << status << " (" << EnumerationToString(lastStatus_) << ")"; } @@ -553,16 +606,11 @@ } - bool HttpClient::Apply(std::string& answer) - { - return ApplyInternal(answer); - } - - - bool HttpClient::Apply(Json::Value& answer) + bool HttpClient::ApplyInternal(Json::Value& answer, + HttpClient::HttpHeaders* answerHeaders) { std::string s; - if (Apply(s)) + if (ApplyInternal(s, answerHeaders)) { Json::Reader reader; return reader.parse(s, answer);