Support for requests with no body (#202)

* avoid fail if no body in request

* request with no body

* fix for win86

* Update sdk/samples/http_client/curl/src/azure_core_with_curl_bodyBuffer.cpp

Co-authored-by: Rick Winter <rick.winter@microsoft.com>

Co-authored-by: Rick Winter <rick.winter@microsoft.com>
This commit is contained in:
Victor Vazquez 2020-06-22 18:38:35 -07:00 committed by GitHub
parent 90345e090c
commit e1e88b3984
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 10 deletions

View File

@ -204,13 +204,15 @@ CURLcode CurlSession::HttpRawSend()
uint64_t rawRequestLen = rawRequest.size();
CURLcode sendResult = SendBuffer((uint8_t*)rawRequest.data(), (size_t)rawRequestLen);
if (this->m_request.GetMethod() == HttpMethod::Get)
auto streamBody = this->m_request.GetBodyStream();
if (streamBody == nullptr)
{
// Finish request with no body
uint8_t endOfRequest[] = "0";
return SendBuffer(endOfRequest, 1); // need one more byte to end request
}
auto streamBody = this->m_request.GetBodyStream();
// Send body 64k at a time (libcurl default)
// NOTE: if stream is on top a contiguous memory, we can avoid allocating this copying buffer
std::unique_ptr<uint8_t[]> unique_buffer(new uint8_t[UploadSstreamPageSize]);
@ -245,6 +247,14 @@ CURLcode CurlSession::ReadStatusLineAndHeadersFromRawResponse()
}
this->m_response = parser.GetResponse();
// For Head request, set the length of body response to 0.
if (this->m_request.GetMethod() == HttpMethod::Head)
{
this->m_response->SetBodyStream(new CurlBodyStream(0, this));
return CURLE_OK;
}
// TODO: tolower ContentLength
auto headers = this->m_response->GetHeaders();
auto bodySize = atoi(headers.at("Content-Length").data());

View File

@ -57,8 +57,13 @@ std::unique_ptr<std::vector<uint8_t>> Response::ConstructBodyBufferFromStream(
return nullptr;
}
uint8_t const bodySize = (uint8_t)stream->Length();
std::unique_ptr<std::vector<uint8_t>> unique_buffer(new std::vector<uint8_t>(bodySize));
auto const bodySize = stream->Length();
if (bodySize <= 0)
{
// no body to get
return nullptr;
}
std::unique_ptr<std::vector<uint8_t>> unique_buffer(new std::vector<uint8_t>((size_t)bodySize));
auto buffer = unique_buffer.get()->data();
stream->Read(buffer, bodySize);

View File

@ -22,6 +22,9 @@ constexpr auto BufferSize = 50;
std::vector<uint8_t> buffer(BufferSize);
Http::Request createGetRequest();
Http::Request createPutRequest();
Http::Request createHeadRequest();
Http::Request createDeleteRequest();
Http::Request createPatchRequest();
void printRespose(std::unique_ptr<Http::Response> response);
int main()
@ -31,6 +34,9 @@ int main()
// Both requests uses a body buffer to be uploaded that would produce responses with bodyBuffer
auto getRequest = createGetRequest();
auto putRequest = createPutRequest();
auto headRequest = createHeadRequest();
auto deleteRequest = createDeleteRequest();
auto patchRequest = createPatchRequest();
// Create the Transport
std::shared_ptr<HttpTransport> transport = std::make_unique<CurlTransport>();
@ -43,11 +49,26 @@ int main()
auto httpPipeline = Http::HttpPipeline(policies);
auto context = Context();
std::unique_ptr<Http::Response> getResponse = httpPipeline.Send(context, getRequest);
std::unique_ptr<Http::Response> putResponse = httpPipeline.Send(context, putRequest);
cout << endl << "GET:";
std::unique_ptr<Http::Response> getResponse = httpPipeline.Send(context, getRequest);
printRespose(std::move(getResponse));
cout << endl << "PUT:";
std::unique_ptr<Http::Response> putResponse = httpPipeline.Send(context, putRequest);
printRespose(std::move(putResponse));
cout << endl << "HEAD:";
std::unique_ptr<Http::Response> headResponse = httpPipeline.Send(context, headRequest);
printRespose(std::move(headResponse));
cout << endl << "DELETE:";
std::unique_ptr<Http::Response> deleteResponse = httpPipeline.Send(context, deleteRequest);
printRespose(std::move(deleteResponse));
cout << endl << "PATCH:";
std::unique_ptr<Http::Response> patchResponse = httpPipeline.Send(context, patchRequest);
printRespose(std::move(patchResponse));
}
catch (Http::CouldNotResolveHostException& e)
{
@ -110,8 +131,9 @@ void printRespose(std::unique_ptr<Http::Response> response)
throw;
}
cout << static_cast<typename std::underlying_type<Http::HttpStatusCode>::type>(
response->GetStatusCode())
cout << endl
<< static_cast<typename std::underlying_type<Http::HttpStatusCode>::type>(
response->GetStatusCode())
<< endl;
cout << response->GetReasonPhrase() << endl;
cout << "headers:" << endl;
@ -120,8 +142,48 @@ void printRespose(std::unique_ptr<Http::Response> response)
cout << header.first << " : " << header.second << endl;
}
cout << "Body (buffer):" << endl;
auto bodyVector = *Http::Response::ConstructBodyBufferFromStream(response->GetBodyStream()).get();
cout << std::string(bodyVector.begin(), bodyVector.end());
auto responseBodyVector
= Http::Response::ConstructBodyBufferFromStream(response->GetBodyStream());
if (responseBodyVector != nullptr)
{
// print body only if response has a body. Head Response won't have body
auto bodyVector = *responseBodyVector.get();
cout << std::string(bodyVector.begin(), bodyVector.end()) << endl;
}
std::cin.ignore();
return;
}
Http::Request createPatchRequest()
{
string host("https://httpbin.org/patch");
cout << "Creating an PATCH request to" << endl << "Host: " << host << endl;
auto request = Http::Request(Http::HttpMethod::Patch, host);
request.AddHeader("Host", "httpbin.org");
return request;
}
Http::Request createDeleteRequest()
{
string host("https://httpbin.org/delete");
cout << "Creating an DELETE request to" << endl << "Host: " << host << endl;
auto request = Http::Request(Http::HttpMethod::Delete, host);
request.AddHeader("Host", "httpbin.org");
return request;
}
Http::Request createHeadRequest()
{
string host("https://httpbin.org/get");
cout << "Creating an HEAD request to" << endl << "Host: " << host << endl;
auto request = Http::Request(Http::HttpMethod::Head, host);
request.AddHeader("Host", "httpbin.org");
return request;
}