Skip to content

Commit

Permalink
HttpResponse return IStream as response body.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jokser committed Jun 8, 2020
1 parent f7d9ce3 commit 2029d3d
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 37 deletions.
4 changes: 3 additions & 1 deletion aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,14 @@ namespace Aws
/**
* Gets the response body of the response.
*/
virtual Aws::IOStream& GetResponseBody() const = 0;
virtual Aws::IStream& GetResponseBody() const = 0;
/**
* Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's
* responsibility to clean up this object.
*/
virtual Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() = 0;

virtual Utils::Stream::ResponseStream & GetResponseStream() = 0;
/**
* Adds a header to the http response object.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ namespace Aws
/**
* Gets the response body of the response.
*/
inline Aws::IOStream& GetResponseBody() const { return bodyStream.GetUnderlyingStream(); }
inline Aws::IStream& GetResponseBody() const { return bodyStream.GetUnderlyingStream(); }
/**
* Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's
* responsibility to clean up this object.
*/
inline Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() { return std::move(bodyStream); }

inline Utils::Stream::ResponseStream& GetResponseStream() { return bodyStream; }
/**
* Adds a header to the http response object.
*/
Expand Down
13 changes: 9 additions & 4 deletions aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <aws/core/utils/memory/AWSMemory.h>
#include <aws/core/utils/memory/stl/AWSStreamFwd.h>

#include <utility>

namespace Aws
{
namespace Utils
Expand Down Expand Up @@ -47,6 +49,7 @@ namespace Aws
* Takes ownership of an underlying stream.
*/
ResponseStream(IOStream* underlyingStreamToManage);
ResponseStream(IStream* underlyingStreamToManage);
ResponseStream(const ResponseStream&) = delete;
~ResponseStream();

Expand All @@ -59,12 +62,14 @@ namespace Aws
/**
* Gives access to underlying stream, but keep in mind that this changes state of the stream
*/
inline Aws::IOStream& GetUnderlyingStream() const { return *m_underlyingStream; }
inline Aws::IStream & GetUnderlyingStream() const { return *m_underlyingStream; }

/**
* Set underlying stream
*/
void SetUnderlyingStream(std::shared_ptr<Aws::IStream> stream) { m_underlyingStream = std::move(stream); }
private:
void ReleaseStream();

Aws::IOStream* m_underlyingStream;
std::shared_ptr<Aws::IStream> m_underlyingStream;
};

class AWS_CORE_API DefaultUnderlyingStream : public Aws::IOStream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ namespace Aws
/**
* Parses the stream into an XMLDocument
*/
static XmlDocument CreateFromXmlStream(Aws::IOStream&);
static XmlDocument CreateFromXmlStream(Aws::IStream&);
/**
* Parses the string into an XMLDocument
*/
Expand Down
16 changes: 8 additions & 8 deletions aws-cpp-sdk-core/source/client/AWSClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
return JsonOutcome(httpOutcome.GetError());
}

if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
if (httpOutcome.GetResult()->GetResponseBody().peek() != EOF)
//this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(httpOutcome.GetResult()->GetResponseBody()),
httpOutcome.GetResult()->GetHeaders(),
Expand All @@ -717,7 +717,7 @@ JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
return JsonOutcome(httpOutcome.GetError());
}

if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
if (httpOutcome.GetResult()->GetResponseBody().peek() != EOF)
{
JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
if (!jsonValue.WasParseSuccessful())
Expand Down Expand Up @@ -750,7 +750,7 @@ JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::Htt

HttpResponseOutcome httpOutcome(httpResponse);

if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
if (httpOutcome.GetResult()->GetResponseBody().peek() != EOF)
{
JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
if (!jsonValue.WasParseSuccessful())
Expand All @@ -776,7 +776,7 @@ AWSError<CoreErrors> AWSJsonClient::BuildAWSError(
bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
}
else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().eof())
{
auto responseCode = httpResponse->GetResponseCode();
auto errorCode = GuessBodylessErrorType(responseCode);
Expand Down Expand Up @@ -830,7 +830,7 @@ XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
return XmlOutcome(httpOutcome.GetError());
}

if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
if (httpOutcome.GetResult()->GetResponseBody().peek() != EOF)
{
XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody());

Expand Down Expand Up @@ -859,7 +859,7 @@ XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
return XmlOutcome(httpOutcome.GetError());
}

if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
if (httpOutcome.GetResult()->GetResponseBody().peek() != EOF)
{
return XmlOutcome(AmazonWebServiceResult<XmlDocument>(
XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()),
Expand All @@ -877,7 +877,7 @@ AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::Htt
bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
}
else if (httpResponse->GetResponseBody().tellp() < 1)
else if (httpResponse->GetResponseBody().eof())
{
auto responseCode = httpResponse->GetResponseCode();
auto errorCode = GuessBodylessErrorType(responseCode);
Expand All @@ -892,7 +892,7 @@ AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::Htt

// When trying to build an AWS Error from a response which is an FStream, we need to rewind the
// file pointer back to the beginning in order to correctly read the input using the XML string iterator
if ((httpResponse->GetResponseBody().tellp() > 0)
if ((httpResponse->GetResponseBody())
&& (httpResponse->GetResponseBody().tellg() > 0))
{
httpResponse->GetResponseBody().seekg(0);
Expand Down
7 changes: 4 additions & 3 deletions aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata)
context->m_rateLimiter->ApplyAndPayForCost(static_cast<int64_t>(sizeToWrite));
}

response->GetResponseBody().write(ptr, static_cast<std::streamsize>(sizeToWrite));
auto stream = std::make_shared<Aws::Utils::Stream::DefaultUnderlyingStream>();
stream->write(ptr, static_cast<std::streamsize>(sizeToWrite));
stream->flush();
response->GetResponseStream().SetUnderlyingStream(stream);
auto& receivedHandler = context->m_request->GetDataReceivedEventHandler();
if (receivedHandler)
{
Expand Down Expand Up @@ -703,8 +706,6 @@ void CurlHttpClient::MakeRequestInternal(HttpRequest& request,
{
m_curlHandleContainer.ReleaseCurlHandle(connectionHandle);
}
//go ahead and flush the response body stream
response->GetResponseBody().flush();
request.AddRequestMetric(GetHttpClientMetricNameByType(HttpClientMetricsType::RequestLatency), (DateTime::Now() - startTransmissionTime).count());
}

Expand Down
2 changes: 1 addition & 1 deletion aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ AmazonWebServiceResult<Aws::String> AWSHttpResourceClient::GetResourceWithAWSWeb
}

const Aws::Client::AWSError<Aws::Client::CoreErrors> error = [this, &response]() {
if (response->HasClientError() || response->GetResponseBody().tellp() < 1)
if (response->HasClientError() || response->GetResponseBody().eof())
{
AWS_LOGSTREAM_ERROR(m_logtag.c_str(), "Http request to retrieve credentials failed");
return AWSError<CoreErrors>(CoreErrors::NETWORK_CONNECTION, true); // Retryable
Expand Down
18 changes: 5 additions & 13 deletions aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ ResponseStream::ResponseStream(Aws::IOStream* underlyingStreamToManage) :
{
}

ResponseStream::ResponseStream(Aws::IStream* underlyingStreamToManage) :
m_underlyingStream(underlyingStreamToManage)
{
}

ResponseStream::ResponseStream(const Aws::IOStreamFactory& factory) :
m_underlyingStream(factory())
{
Expand All @@ -52,7 +57,6 @@ ResponseStream& ResponseStream::operator=(ResponseStream&& toMove)
return *this;
}

ReleaseStream();
m_underlyingStream = toMove.m_underlyingStream;
toMove.m_underlyingStream = nullptr;

Expand All @@ -61,18 +65,6 @@ ResponseStream& ResponseStream::operator=(ResponseStream&& toMove)

ResponseStream::~ResponseStream()
{
ReleaseStream();
}

void ResponseStream::ReleaseStream()
{
if (m_underlyingStream)
{
m_underlyingStream->flush();
Aws::Delete(m_underlyingStream);
}

m_underlyingStream = nullptr;
}

static const char *DEFAULT_STREAM_TAG = "DefaultUnderlyingStream";
Expand Down
2 changes: 1 addition & 1 deletion aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ Aws::String XmlDocument::ConvertToString() const
return printer.CStr();
}

XmlDocument XmlDocument::CreateFromXmlStream(Aws::IOStream& xmlStream)
XmlDocument XmlDocument::CreateFromXmlStream(Aws::IStream& xmlStream)
{
Aws::String xmlString((Aws::IStreamBufIterator(xmlStream)), Aws::IStreamBufIterator());
return CreateFromXmlString(xmlString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace Model
/**
* <p>The bucket policy as a JSON document.</p>
*/
inline Aws::IOStream& GetPolicy() { return m_policy.GetUnderlyingStream(); }
inline Aws::IStream& GetPolicy() { return m_policy.GetUnderlyingStream(); }

/**
* <p>The bucket policy as a JSON document.</p>
Expand Down
2 changes: 1 addition & 1 deletion aws-cpp-sdk-s3/include/aws/s3/model/GetObjectResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace Model
/**
* <p>Object data.</p>
*/
inline Aws::IOStream& GetBody() { return m_body.GetUnderlyingStream(); }
inline Aws::IStream& GetBody() { return m_body.GetUnderlyingStream(); }

/**
* <p>Object data.</p>
Expand Down
4 changes: 2 additions & 2 deletions aws-cpp-sdk-s3/include/aws/s3/model/GetObjectTorrentResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ namespace Model
/**
* <p>A Bencoded dictionary as defined by the BitTorrent specification</p>
*/
inline Aws::IOStream& GetBody() { return m_body.GetUnderlyingStream(); }
inline Aws::IStream& GetBody() { return m_body.GetUnderlyingStream(); }

/**
* <p>A Bencoded dictionary as defined by the BitTorrent specification</p>
*/
inline void ReplaceBody(Aws::IOStream* body) { m_body = Aws::Utils::Stream::ResponseStream(body); }
inline void ReplaceBody(Aws::IStream* body) { m_body = Aws::Utils::Stream::ResponseStream(body); }



Expand Down

0 comments on commit 2029d3d

Please sign in to comment.