-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// @brief Pointer to the @c HttpHeader class.
typedef boost::shared_ptr<HttpHeader> HttpHeaderPtr;
+/// @brief Represents HTTP Host header.
+class HostHttpHeader : public HttpHeader {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param header_value Host header value. The default is empty
+ /// string.
+ explicit HostHttpHeader(const std::string& header_value = "")
+ : HttpHeader("Host", header_value) {
+ }
+};
+
+/// @brief Pointer to the HTTP host header.
+typedef boost::shared_ptr<HostHttpHeader> HostHttpHeaderPtr;
+
} // end of namespace isc::http
} // end of namespace isc
-// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
context_(new HttpRequestContext()) {
}
-HttpRequest::HttpRequest(const Method& method, const std::string& uri,
- const HttpVersion& version)
+HttpRequest::HttpRequest(const Method& method,
+ const std::string& uri,
+ const HttpVersion& version,
+ const HostHttpHeader& host_header)
: HttpMessage(OUTBOUND), required_methods_(),
method_(Method::HTTP_METHOD_UNKNOWN),
context_(new HttpRequestContext()) {
context()->uri_ = uri;
context()->http_version_major_ = version.major_;
context()->http_version_minor_ = version.minor_;
+ // The Host header is mandatory in HTTP/1.1 and should be placed before
+ // any other headers. We also include it for HTTP/1.0 as it doesn't
+ // harm to include it.
+ context()->headers_.push_back(HttpHeaderContext(host_header.getName(),
+ host_header.getValue()));
}
void
-// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// @brief Constructor for outbound HTTP request.
///
+ /// The constructor always includes Host header in the request, regardless
+ /// of the HTTP version used.
+ ///
/// @param method HTTP method, e.g. POST.
/// @param uri URI.
/// @param version HTTP version.
- HttpRequest(const Method& method, const std::string& uri, const HttpVersion& version);
+ /// @param host_header Host header to be included in the request. The default
+ /// is the empty Host header.
+ HttpRequest(const Method& method, const std::string& uri, const HttpVersion& version,
+ const HostHttpHeader& host_header = HostHttpHeader());
/// @brief Returns pointer to the @ref HttpRequestContext.
///
-// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
HttpMessageNonExistingHeader);
}
+// This test verifies that empty Host header is included in the
+// request if it is not explicitly specified.
+TEST_F(HttpRequestTest, hostHeaderDefault) {
+ HttpRequestPtr request;
+ ASSERT_NO_THROW(request.reset(new HttpRequest(HttpRequest::Method::HTTP_GET,
+ "/isc/org",
+ HttpVersion(1, 0))));
+
+ ASSERT_NO_THROW(request->finalize());
+
+ EXPECT_EQ(HttpRequest::Method::HTTP_GET, request->getMethod());
+ EXPECT_EQ("/isc/org", request->getUri());
+ EXPECT_EQ(1, request->getHttpVersion().major_);
+ EXPECT_EQ(0, request->getHttpVersion().minor_);
+
+ std::string host_hdr;
+ ASSERT_NO_THROW(host_hdr = request->getHeaderValue("Host"));
+ EXPECT_TRUE(host_hdr.empty());
+}
+
+// This test verifies that it is possible to explicitly specify a
+// Host header value while creating a request.
+TEST_F(HttpRequestTest, hostHeaderCustom) {
+ HttpRequestPtr request;
+ ASSERT_NO_THROW(request.reset(new HttpRequest(HttpRequest::Method::HTTP_GET,
+ "/isc/org",
+ HttpVersion(1, 1),
+ HostHttpHeader("www.example.org"))));
+
+ ASSERT_NO_THROW(request->finalize());
+
+ EXPECT_EQ(HttpRequest::Method::HTTP_GET, request->getMethod());
+ EXPECT_EQ("/isc/org", request->getUri());
+ EXPECT_EQ(1, request->getHttpVersion().major_);
+ EXPECT_EQ(1, request->getHttpVersion().minor_);
+
+ std::string host_hdr;
+ ASSERT_NO_THROW(host_hdr = request->getHeaderValue("Host"));
+ EXPECT_EQ("www.example.org", host_hdr);
+}
+
TEST_F(HttpRequestTest, includeHeaders) {
setContextBasics("POST", "/isc/org", HttpVersion(1, 0));
addHeaderToContext("Content-Length", "1024");