diff --git a/include/envoy/http/header_map.h b/include/envoy/http/header_map.h index 668bcd53ff4c6..4776110cb8097 100644 --- a/include/envoy/http/header_map.h +++ b/include/envoy/http/header_map.h @@ -86,6 +86,11 @@ class HeaderString { */ const char* c_str() const { return buffer_.ref_; } + /** + * @return a std::string. + */ + std::string getString() const { return std::string(buffer_.ref_, string_length_); } + /** * Return the string to a default state. Reference strings are not touched. Both inline/dynamic * strings are reset to zero size. diff --git a/source/common/access_log/BUILD b/source/common/access_log/BUILD index cf2b12f8bdc70..49f557ef39e4c 100644 --- a/source/common/access_log/BUILD +++ b/source/common/access_log/BUILD @@ -17,6 +17,7 @@ envoy_cc_library( "//include/envoy/request_info:request_info_interface", "//source/common/common:assert_lib", "//source/common/common:utility_lib", + "//source/common/http:utility_lib", "//source/common/request_info:utility_lib", ], ) @@ -65,6 +66,7 @@ envoy_cc_library( "//include/envoy/thread_local:thread_local_interface", "//include/envoy/upstream:cluster_manager_interface", "//source/common/grpc:async_client_lib", + "//source/common/network:utility_lib", "@envoy_api//envoy/api/v2/filter/accesslog:accesslog_cc", "@envoy_api//envoy/config/accesslog/v2:als_cc", "@envoy_api//envoy/service/accesslog/v2:als_cc", diff --git a/source/common/access_log/access_log_formatter.cc b/source/common/access_log/access_log_formatter.cc index 8f4b09810df12..5b7be5e1226fa 100644 --- a/source/common/access_log/access_log_formatter.cc +++ b/source/common/access_log/access_log_formatter.cc @@ -7,6 +7,7 @@ #include "common/common/assert.h" #include "common/common/fmt.h" #include "common/common/utility.h" +#include "common/http/utility.h" #include "common/request_info/utility.h" namespace Envoy { @@ -25,26 +26,12 @@ FormatterPtr AccessLogFormatUtils::defaultAccessLogFormatter() { return FormatterPtr{new FormatterImpl(DEFAULT_FORMAT)}; } -static const std::string Http10String = "HTTP/1.0"; -static const std::string Http11String = "HTTP/1.1"; -static const std::string Http2String = "HTTP/2"; - const std::string& AccessLogFormatUtils::protocolToString(const Optional& protocol) { if (protocol.valid()) { - switch (protocol.value()) { - case Http::Protocol::Http10: - return Http10String; - case Http::Protocol::Http11: - return Http11String; - case Http::Protocol::Http2: - return Http2String; - } - } else { - return UnspecifiedValueString; + return Http::Utility::getProtocolString(protocol.value()); } - - NOT_REACHED; + return UnspecifiedValueString; } FormatterImpl::FormatterImpl(const std::string& format) { diff --git a/source/common/access_log/grpc_access_log_impl.cc b/source/common/access_log/grpc_access_log_impl.cc index 2487cdaa98a00..dc38f81535b5e 100644 --- a/source/common/access_log/grpc_access_log_impl.cc +++ b/source/common/access_log/grpc_access_log_impl.cc @@ -2,6 +2,7 @@ #include "common/common/assert.h" #include "common/http/header_map_impl.h" +#include "common/network/utility.h" namespace Envoy { namespace AccessLog { @@ -64,18 +65,6 @@ HttpGrpcAccessLog::HttpGrpcAccessLog( : filter_(std::move(filter)), config_(config), grpc_access_log_streamer_(grpc_access_log_streamer) {} -void HttpGrpcAccessLog::addressToAccessLogAddress( - envoy::api::v2::Address& proto_address, const Network::Address::Instance& network_address) { - if (network_address.type() == Network::Address::Type::Pipe) { - proto_address.mutable_pipe()->set_path(network_address.asString()); - } else { - ASSERT(network_address.type() == Network::Address::Type::Ip); - auto* socket_address = proto_address.mutable_socket_address(); - socket_address->set_address(network_address.ip()->addressAsString()); - socket_address->set_port_value(network_address.ip()->port()); - } -} - void HttpGrpcAccessLog::responseFlagsToAccessLogResponseFlags( envoy::api::v2::filter::accesslog::AccessLogCommon& common_access_log, const RequestInfo::RequestInfo& request_info) { @@ -161,10 +150,12 @@ void HttpGrpcAccessLog::log(const Http::HeaderMap* request_headers, // TODO(mattklein123): Populate time_to_first_downstream_tx_byte field. // TODO(mattklein123): Populate metadata field and wire up to filters. auto* common_properties = log_entry->mutable_common_properties(); - addressToAccessLogAddress(*common_properties->mutable_downstream_remote_address(), - *request_info.downstreamRemoteAddress()); - addressToAccessLogAddress(*common_properties->mutable_downstream_local_address(), - *request_info.downstreamLocalAddress()); + Network::Utility::addressToProtobufAddress( + *request_info.downstreamRemoteAddress(), + *common_properties->mutable_downstream_remote_address()); + Network::Utility::addressToProtobufAddress( + *request_info.downstreamLocalAddress(), + *common_properties->mutable_downstream_local_address()); common_properties->mutable_start_time()->MergeFrom( Protobuf::util::TimeUtil::MicrosecondsToTimestamp( std::chrono::duration_cast( @@ -183,13 +174,14 @@ void HttpGrpcAccessLog::log(const Http::HeaderMap* request_headers, common_properties->mutable_time_to_last_downstream_tx_byte()->MergeFrom( Protobuf::util::TimeUtil::MicrosecondsToDuration(request_info.duration().count())); if (request_info.upstreamHost() != nullptr) { - addressToAccessLogAddress(*common_properties->mutable_upstream_remote_address(), - *request_info.upstreamHost()->address()); + Network::Utility::addressToProtobufAddress( + *request_info.upstreamHost()->address(), + *common_properties->mutable_upstream_remote_address()); common_properties->set_upstream_cluster(request_info.upstreamHost()->cluster().name()); } if (request_info.upstreamLocalAddress() != nullptr) { - addressToAccessLogAddress(*common_properties->mutable_upstream_local_address(), - *request_info.upstreamLocalAddress()); + Network::Utility::addressToProtobufAddress( + *request_info.upstreamLocalAddress(), *common_properties->mutable_upstream_local_address()); } responseFlagsToAccessLogResponseFlags(*common_properties, request_info); diff --git a/source/common/access_log/grpc_access_log_impl.h b/source/common/access_log/grpc_access_log_impl.h index 4c79b02d65e69..30d2b0d19bcbb 100644 --- a/source/common/access_log/grpc_access_log_impl.h +++ b/source/common/access_log/grpc_access_log_impl.h @@ -114,8 +114,6 @@ class HttpGrpcAccessLog : public Instance { const envoy::config::accesslog::v2::HttpGrpcAccessLogConfig& config, GrpcAccessLogStreamerSharedPtr grpc_access_log_streamer); - static void addressToAccessLogAddress(envoy::api::v2::Address& proto_address, - const Network::Address::Instance& network_address); static void responseFlagsToAccessLogResponseFlags( envoy::api::v2::filter::accesslog::AccessLogCommon& common_access_log, const RequestInfo::RequestInfo& request_info); diff --git a/source/common/http/headers.h b/source/common/http/headers.h index 67be3e9cfa11b..9e3faecb6324f 100644 --- a/source/common/http/headers.h +++ b/source/common/http/headers.h @@ -177,6 +177,12 @@ class HeaderValues { struct { const std::string True{"true"}; } CORSValues; + + struct { + const std::string Http10String{"HTTP/1.0"}; + const std::string Http11String{"HTTP/1.1"}; + const std::string Http2String{"HTTP/2"}; + } ProtocolStrings; }; typedef ConstSingleton Headers; diff --git a/source/common/http/utility.cc b/source/common/http/utility.cc index c06e7137ee6b8..63a2a6cefdfe9 100644 --- a/source/common/http/utility.cc +++ b/source/common/http/utility.cc @@ -263,5 +263,18 @@ Utility::getLastAddressFromXFF(const Http::HeaderMap& request_headers) { } } +const std::string& Utility::getProtocolString(const Protocol protocol) { + switch (protocol) { + case Protocol::Http10: + return Headers::get().ProtocolStrings.Http10String; + case Protocol::Http11: + return Headers::get().ProtocolStrings.Http11String; + case Protocol::Http2: + return Headers::get().ProtocolStrings.Http2String; + } + + NOT_REACHED; +} + } // namespace Http } // namespace Envoy diff --git a/source/common/http/utility.h b/source/common/http/utility.h index 9b7626d007e1e..3546f373e6b5f 100644 --- a/source/common/http/utility.h +++ b/source/common/http/utility.h @@ -144,6 +144,13 @@ class Utility { * @see GetLastAddressFromXffInfo for more information. */ static GetLastAddressFromXffInfo getLastAddressFromXFF(const Http::HeaderMap& request_headers); + + /** + * Get the string for the given http protocol. + * @param protocol for which to return the string representation. + * @return string representation of the protocol. + */ + static const std::string& getProtocolString(const Protocol p); }; } // namespace Http diff --git a/source/common/network/BUILD b/source/common/network/BUILD index 43fb8507232ac..1c5174a22f86a 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -185,6 +185,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/common:utility_lib", "//source/common/protobuf", + "@envoy_api//envoy/api/v2:address_cc", "@envoy_api//envoy/api/v2:base_cc", ], ) diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index 4875d0826a3ba..ce7fef09e20f1 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -371,5 +371,17 @@ absl::uint128 Utility::flipOrder(const absl::uint128& input) { return result; } +void Utility::addressToProtobufAddress(const Address::Instance& address, + envoy::api::v2::Address& proto_address) { + if (address.type() == Address::Type::Pipe) { + proto_address.mutable_pipe()->set_path(address.asString()); + } else { + ASSERT(address.type() == Address::Type::Ip); + auto* socket_address = proto_address.mutable_socket_address(); + socket_address->set_address(address.ip()->addressAsString()); + socket_address->set_port_value(address.ip()->port()); + } +} + } // namespace Network } // namespace Envoy diff --git a/source/common/network/utility.h b/source/common/network/utility.h index 16c58530617e5..de176d27b5bdc 100644 --- a/source/common/network/utility.h +++ b/source/common/network/utility.h @@ -201,6 +201,14 @@ class Utility { */ static absl::uint128 Ip6htonl(const absl::uint128& address); + /** + * Copies the address instance into the protobuf representation of an address. + * @param address is the address to be copied into the protobuf representation of this address. + * @param proto_address is the protobuf address to which the address instance is copied into. + */ + static void addressToProtobufAddress(const Address::Instance& address, + envoy::api::v2::Address& proto_address); + private: static void throwWithMalformedIp(const std::string& ip_address); diff --git a/test/common/http/header_map_impl_test.cc b/test/common/http/header_map_impl_test.cc index cb55407a2d21f..eaa358e2702e7 100644 --- a/test/common/http/header_map_impl_test.cc +++ b/test/common/http/header_map_impl_test.cc @@ -283,6 +283,19 @@ TEST(HeaderStringTest, All) { EXPECT_FALSE(string.caseInsensitiveContains("keep-alive")); EXPECT_FALSE(string.caseInsensitiveContains("")); } + + // getString + { + std::string static_string("HELLO"); + HeaderString headerString1(static_string); + std::string retString1 = headerString1.getString(); + EXPECT_EQ("HELLO", retString1); + EXPECT_EQ(5U, retString1.size()); + + HeaderString headerString2; + std::string retString2 = headerString2.getString(); + EXPECT_EQ(0U, retString2.size()); + } } TEST(HeaderMapImplTest, InlineInsert) { diff --git a/test/common/network/utility_test.cc b/test/common/network/utility_test.cc index b055fa91f28b8..be1b19517724c 100644 --- a/test/common/network/utility_test.cc +++ b/test/common/network/utility_test.cc @@ -198,6 +198,24 @@ TEST(NetworkUtility, AnyAddress) { } } +TEST(NetworkUtility, AddressToProtobufAddress) { + { + envoy::api::v2::Address proto_address; + Address::Ipv4Instance address("127.0.0.1"); + Utility::addressToProtobufAddress(address, proto_address); + EXPECT_EQ(true, proto_address.has_socket_address()); + EXPECT_EQ("127.0.0.1", proto_address.socket_address().address()); + EXPECT_EQ(0, proto_address.socket_address().port_value()); + } + { + envoy::api::v2::Address proto_address; + Address::PipeInstance address("/hello"); + Utility::addressToProtobufAddress(address, proto_address); + EXPECT_EQ(true, proto_address.has_pipe()); + EXPECT_EQ("/hello", proto_address.pipe().path()); + } +} + TEST(PortRangeListTest, Errors) { { std::string port_range_str = "a1";