Skip to content

Commit

Permalink
Send headers as string map. (envoyproxy#129)
Browse files Browse the repository at this point in the history
* Send headers as string map.

* Remove origin.ip and origin.host.

* Fix format
  • Loading branch information
qiwzhang authored Feb 25, 2017
1 parent 7fe10df commit fdfb73f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 62 deletions.
120 changes: 59 additions & 61 deletions src/envoy/mixer/http_control.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,17 @@ namespace Http {
namespace Mixer {
namespace {

// Define lower case string for X-Forwarded-Host.
const LowerCaseString kHeaderNameXFH("x-forwarded-host", false);

const std::string kRequestHeaderPrefix = "request.headers.";
const std::string kResponseHeaderPrefix = "response.headers.";

// Define attribute names
const std::string kAttrNameRequestPath = "request.path";
const std::string kAttrNameRequestSize = "request.size";
const std::string kAttrNameResponseSize = "response.size";
const std::string kAttrNameResponseTime = "response.time";
const std::string kAttrNameOriginIp = "origin.ip";
const std::string kAttrNameOriginHost = "origin.host";
const std::string kRequestPath = "request.path";
const std::string kRequestHost = "request.host";
const std::string kRequestSize = "request.size";
const std::string kRequestTime = "request.time";
const std::string kRequestHeaders = "request.headers";

const std::string kResponseHeaders = "response.headers";
const std::string kResponseSize = "response.size";
const std::string kResponseTime = "response.time";
const std::string kResponseLatency = "response.latency";
const std::string kResponseHttpCode = "response.http.code";

Attributes::Value StringValue(const std::string& str) {
Expand All @@ -52,86 +50,85 @@ Attributes::Value StringValue(const std::string& str) {
return v;
}

Attributes::Value StringMapValue(
std::map<std::string, std::string>&& string_map) {
Attributes::Value v;
v.type = Attributes::Value::STRING_MAP;
v.string_map_v.swap(string_map);
return v;
}

Attributes::Value Int64Value(int64_t value) {
Attributes::Value v;
v.type = Attributes::Value::INT64;
v.value.int64_v = value;
return v;
}

void SetStringAttribute(const std::string& name, const std::string& value,
Attributes* attr) {
if (!value.empty()) {
attr->attributes[name] = StringValue(value);
}
Attributes::Value TimeValue(
std::chrono::time_point<std::chrono::system_clock> value) {
Attributes::Value v;
v.type = Attributes::Value::TIME;
v.time_v = value;
return v;
}

std::string GetFirstForwardedFor(const HeaderMap& header_map) {
if (!header_map.ForwardedFor()) {
return "";
}
std::vector<std::string> xff_address_list =
StringUtil::split(header_map.ForwardedFor()->value().c_str(), ',');
if (xff_address_list.empty()) {
return "";
}
return xff_address_list.front();
Attributes::Value DurationValue(std::chrono::nanoseconds value) {
Attributes::Value v;
v.type = Attributes::Value::DURATION;
v.duration_nanos_v = value;
return v;
}

std::string GetLastForwardedHost(const HeaderMap& header_map) {
const HeaderEntry* entry = header_map.get(kHeaderNameXFH);
if (entry == nullptr) {
return "";
}
std::vector<std::string> xff_list =
StringUtil::split(entry->value().c_str(), ',');
if (xff_list.empty()) {
return "";
void SetStringAttribute(const std::string& name, const std::string& value,
Attributes* attr) {
if (!value.empty()) {
attr->attributes[name] = StringValue(value);
}
return xff_list.back();
}

void FillRequestHeaderAttributes(const HeaderMap& header_map,
Attributes* attr) {
// Pass in all headers
std::map<std::string, std::string> ExtractHeaders(const HeaderMap& header_map) {
std::map<std::string, std::string> headers;
header_map.iterate(
[](const HeaderEntry& header, void* context) {
Attributes* attr = static_cast<Attributes*>(context);
attr->attributes[kRequestHeaderPrefix + header.key().c_str()] =
StringValue(header.value().c_str());
std::map<std::string, std::string>* header_map =
static_cast<std::map<std::string, std::string>*>(context);
(*header_map)[header.key().c_str()] = header.value().c_str();
},
attr);
&headers);
return headers;
}

SetStringAttribute(kAttrNameRequestPath, header_map.Path()->value().c_str(),
attr);
SetStringAttribute(kAttrNameOriginIp, GetFirstForwardedFor(header_map), attr);
SetStringAttribute(kAttrNameOriginHost, GetLastForwardedHost(header_map),
attr);
void FillRequestHeaderAttributes(const HeaderMap& header_map,
Attributes* attr) {
SetStringAttribute(kRequestPath, header_map.Path()->value().c_str(), attr);
SetStringAttribute(kRequestHost, header_map.Host()->value().c_str(), attr);
attr->attributes[kRequestTime] = TimeValue(std::chrono::system_clock::now());
attr->attributes[kRequestHeaders] =
StringMapValue(ExtractHeaders(header_map));
}

void FillResponseHeaderAttributes(const HeaderMap& header_map,
Attributes* attr) {
header_map.iterate(
[](const HeaderEntry& header, void* context) {
Attributes* attr = static_cast<Attributes*>(context);
attr->attributes[kResponseHeaderPrefix + header.key().c_str()] =
StringValue(header.value().c_str());
},
attr);
attr->attributes[kResponseHeaders] =
StringMapValue(ExtractHeaders(header_map));
attr->attributes[kResponseTime] = TimeValue(std::chrono::system_clock::now());
}

void FillRequestInfoAttributes(const AccessLog::RequestInfo& info,
int check_status_code, Attributes* attr) {
if (info.bytesReceived() >= 0) {
attr->attributes[kAttrNameRequestSize] = Int64Value(info.bytesReceived());
attr->attributes[kRequestSize] = Int64Value(info.bytesReceived());
}
if (info.bytesSent() >= 0) {
attr->attributes[kAttrNameResponseSize] = Int64Value(info.bytesSent());
attr->attributes[kResponseSize] = Int64Value(info.bytesSent());
}
if (info.duration().count() >= 0) {
attr->attributes[kAttrNameResponseTime] =
Int64Value(info.duration().count());

if (info.duration().count() > 0) {
attr->attributes[kResponseLatency] = DurationValue(
std::chrono::duration_cast<std::chrono::nanoseconds>(info.duration()));
}

if (info.responseCode().valid()) {
attr->attributes[kResponseHttpCode] =
Int64Value(info.responseCode().value());
Expand Down Expand Up @@ -184,6 +181,7 @@ void HttpControl::Report(HttpRequestDataPtr request_data,
// Use all Check attributes for Report.
// Add additional Report attributes.
FillResponseHeaderAttributes(*response_headers, &request_data->attributes);

FillRequestInfoAttributes(request_info, check_status,
&request_data->attributes);
log().debug("Send Report: {}", request_data->attributes.DebugString());
Expand Down
2 changes: 1 addition & 1 deletion src/envoy/mixer/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
################################################################################
#

MIXER_CLIENT = "7b8544d765f9d7d86d28770c8d27d69cbf9509ac"
MIXER_CLIENT = "d0c57ab0d74887feb11f8644fa98538208f14dbc"

def mixer_client_repositories(bind=True):
native.git_repository(
Expand Down

0 comments on commit fdfb73f

Please sign in to comment.