Skip to content

Commit 6e3a30c

Browse files
authored
Wrap aws_http_request (aws#44)
* Wrap aws_http_request
1 parent 60ad32d commit 6e3a30c

File tree

4 files changed

+269
-0
lines changed

4 files changed

+269
-0
lines changed

include/aws/crt/http/HttpRequest.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#pragma once
2+
/*
3+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License").
6+
* You may not use this file except in compliance with the License.
7+
* A copy of the License is located at
8+
*
9+
* http://aws.amazon.com/apache2.0
10+
*
11+
* or in the "license" file accompanying this file. This file is distributed
12+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+
* express or implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
#include <aws/crt/Exports.h>
18+
#include <aws/crt/Types.h>
19+
20+
struct aws_http_header;
21+
struct aws_http_request;
22+
23+
namespace Aws
24+
{
25+
namespace Crt
26+
{
27+
namespace Http
28+
{
29+
using HttpHeader = aws_http_header;
30+
31+
/*
32+
* Class representing a mutable http request.
33+
*/
34+
class AWS_CRT_CPP_API HttpRequest
35+
{
36+
public:
37+
HttpRequest(Allocator *allocator = DefaultAllocator()) noexcept;
38+
~HttpRequest();
39+
40+
HttpRequest(const HttpRequest &) = delete;
41+
HttpRequest(HttpRequest &&) = delete;
42+
HttpRequest &operator=(const HttpRequest &) = delete;
43+
HttpRequest &operator=(HttpRequest &&) = delete;
44+
45+
Optional<ByteCursor> GetMethod() const noexcept;
46+
bool SetMethod(ByteCursor method) noexcept;
47+
48+
Optional<ByteCursor> GetPath() const noexcept;
49+
bool SetPath(ByteCursor path) noexcept;
50+
51+
std::shared_ptr<Aws::Crt::Io::IStream> GetBody() const noexcept;
52+
bool SetBody(const std::shared_ptr<Aws::Crt::Io::IStream> &body) noexcept;
53+
54+
size_t GetHeaderCount() const noexcept;
55+
Optional<HttpHeader> GetHeader(size_t index) const noexcept;
56+
bool SetHeader(size_t index, const HttpHeader &header) noexcept;
57+
bool AddHeader(const HttpHeader &header) noexcept;
58+
bool EraseHeader(size_t index) noexcept;
59+
60+
operator bool() const noexcept { return m_request != nullptr; }
61+
62+
private:
63+
Allocator *m_allocator;
64+
65+
struct aws_http_request *m_request;
66+
std::shared_ptr<Aws::Crt::Io::IStream> m_bodyStream;
67+
};
68+
} // namespace Http
69+
} // namespace Crt
70+
} // namespace Aws

source/http/HttpRequest.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include <aws/crt/http/HttpRequest.h>
17+
18+
#include <aws/crt/io/Stream.h>
19+
#include <aws/http/request_response.h>
20+
#include <aws/io/stream.h>
21+
22+
namespace Aws
23+
{
24+
namespace Crt
25+
{
26+
namespace Http
27+
{
28+
29+
HttpRequest::HttpRequest(Allocator *allocator) noexcept
30+
: m_allocator(allocator), m_request(aws_http_request_new(allocator)), m_bodyStream(nullptr)
31+
{
32+
}
33+
34+
HttpRequest::~HttpRequest()
35+
{
36+
if (m_request != nullptr)
37+
{
38+
aws_input_stream *old_stream = aws_http_request_get_body_stream(m_request);
39+
if (old_stream != nullptr)
40+
{
41+
aws_input_stream_destroy(old_stream);
42+
}
43+
44+
aws_http_request_destroy(m_request);
45+
m_request = nullptr;
46+
}
47+
}
48+
49+
Optional<ByteCursor> HttpRequest::GetMethod() const noexcept
50+
{
51+
ByteCursor method;
52+
if (aws_http_request_get_method(m_request, &method) != AWS_OP_SUCCESS)
53+
{
54+
return Optional<ByteCursor>();
55+
}
56+
57+
return Optional<ByteCursor>(method);
58+
}
59+
60+
bool HttpRequest::SetMethod(ByteCursor method) noexcept
61+
{
62+
return aws_http_request_set_method(m_request, method) == AWS_OP_SUCCESS;
63+
}
64+
65+
Optional<ByteCursor> HttpRequest::GetPath() const noexcept
66+
{
67+
ByteCursor path;
68+
if (aws_http_request_get_path(m_request, &path) != AWS_OP_SUCCESS)
69+
{
70+
return Optional<ByteCursor>();
71+
}
72+
73+
return Optional<ByteCursor>(path);
74+
}
75+
76+
bool HttpRequest::SetPath(ByteCursor path) noexcept
77+
{
78+
return aws_http_request_set_path(m_request, path) == AWS_OP_SUCCESS;
79+
}
80+
81+
std::shared_ptr<Aws::Crt::Io::IStream> HttpRequest::GetBody() const noexcept { return m_bodyStream; }
82+
83+
bool HttpRequest::SetBody(const std::shared_ptr<Aws::Crt::Io::IStream> &body) noexcept
84+
{
85+
aws_input_stream *stream = nullptr;
86+
if (body != nullptr)
87+
{
88+
stream = Aws::Crt::Io::AwsInputStreamNewCpp(body, m_allocator);
89+
if (stream == nullptr)
90+
{
91+
return false;
92+
}
93+
}
94+
95+
/*
96+
* clean up the old stream before setting the new
97+
*/
98+
aws_input_stream *old_stream = aws_http_request_get_body_stream(m_request);
99+
if (old_stream != nullptr)
100+
{
101+
// aws_input_stream_destroy(old_stream);
102+
}
103+
104+
aws_http_request_set_body_stream(m_request, stream);
105+
106+
m_bodyStream = (stream) ? body : nullptr;
107+
108+
return true;
109+
}
110+
111+
size_t HttpRequest::GetHeaderCount() const noexcept { return aws_http_request_get_header_count(m_request); }
112+
113+
Optional<HttpHeader> HttpRequest::GetHeader(size_t index) const noexcept
114+
{
115+
HttpHeader header;
116+
if (aws_http_request_get_header(m_request, &header, index) != AWS_OP_SUCCESS)
117+
{
118+
return Optional<HttpHeader>();
119+
}
120+
121+
return Optional<HttpHeader>(header);
122+
}
123+
124+
bool HttpRequest::SetHeader(size_t index, const HttpHeader &header) noexcept
125+
{
126+
return aws_http_request_set_header(m_request, header, index) == AWS_OP_SUCCESS;
127+
}
128+
129+
bool HttpRequest::AddHeader(const HttpHeader &header) noexcept
130+
{
131+
return aws_http_request_add_header(m_request, header) == AWS_OP_SUCCESS;
132+
}
133+
134+
bool HttpRequest::EraseHeader(size_t index) noexcept
135+
{
136+
return aws_http_request_erase_header(m_request, index) == AWS_OP_SUCCESS;
137+
}
138+
} // namespace Http
139+
} // namespace Crt
140+
} // namespace Aws

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ add_test_case(TestProviderEnvironmentGet)
4040
add_test_case(TestProviderProfileGet)
4141
add_test_case(TestProviderImdsGet)
4242
add_test_case(TestProviderDefaultChainGet)
43+
add_test_case(HttpRequestTestCreateDestroy)
4344

4445
generate_cpp_test_driver(${TEST_BINARY_NAME})
4546

tests/HttpRequestTest.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
#include <aws/crt/Api.h>
16+
17+
#include <aws/crt/http/HttpRequest.h>
18+
19+
#include <aws/http/request_response.h>
20+
21+
#include <aws/testing/aws_test_harness.h>
22+
23+
#include <sstream>
24+
25+
using namespace Aws::Crt::Http;
26+
27+
static int s_HttpRequestTestCreateDestroy(struct aws_allocator *allocator, void *ctx)
28+
{
29+
(void)ctx;
30+
Aws::Crt::ApiHandle apiHandle(allocator);
31+
32+
{
33+
Aws::Crt::Http::HttpRequest request;
34+
request.SetMethod(aws_byte_cursor_from_c_str("GET"));
35+
request.SetPath(aws_byte_cursor_from_c_str("/index"));
36+
37+
std::shared_ptr<Aws::Crt::Io::IStream> stream = std::make_shared<std::stringstream>("TestContent");
38+
request.SetBody(stream);
39+
40+
std::shared_ptr<Aws::Crt::Io::IStream> stream2 = std::make_shared<std::stringstream>("SomeOtherContent");
41+
request.SetBody(stream2);
42+
43+
HttpHeader header1 = {aws_byte_cursor_from_c_str("Host"), aws_byte_cursor_from_c_str("www.test.com")};
44+
request.AddHeader(header1);
45+
46+
HttpHeader header2 = {aws_byte_cursor_from_c_str("Authorization"), aws_byte_cursor_from_c_str("sadf")};
47+
request.AddHeader(header2);
48+
49+
HttpHeader header3 = {aws_byte_cursor_from_c_str("UserAgent"), aws_byte_cursor_from_c_str("unit-tests-1.0")};
50+
request.AddHeader(header3);
51+
52+
request.EraseHeader(2);
53+
}
54+
55+
return AWS_OP_SUCCESS;
56+
}
57+
58+
AWS_TEST_CASE(HttpRequestTestCreateDestroy, s_HttpRequestTestCreateDestroy)

0 commit comments

Comments
 (0)