Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support forwarded proto field and x-forwarded-proto #5357

Merged
merged 8 commits into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,31 @@

import javax.annotation.Nullable;

final class ForwarderHeaderParser {
final class ForwardedHeaderParser {

// VisibleForTesting
/** Extract proto (aka scheme) from "Forwarded" http header. */
@Nullable
static String extractForwarded(String forwarded) {
static String extractProtoFromForwardedHeader(String forwarded) {
int start = forwarded.toLowerCase().indexOf("proto=");
if (start < 0) {
return null;
}
start += 6; // start is now the index after proto=
if (start >= forwarded.length() - 1) { // the value after for= must not be empty
return null;
}
return extractProto(forwarded, start);
}

/** Extract proto (aka scheme) from "X-Forwarded-Proto" http header. */
@Nullable
static String extractProtoFromForwardedProtoHeader(String forwardedProto) {
return extractProto(forwardedProto, 0);
}

/** Extract client IP address from "Forwarded" http header. */
@Nullable
static String extractClientIpFromForwardedHeader(String forwarded) {
int start = forwarded.toLowerCase().indexOf("for=");
if (start < 0) {
return null;
Expand All @@ -23,10 +43,30 @@ static String extractForwarded(String forwarded) {
return extractIpAddress(forwarded, start);
}

// VisibleForTesting
/** Extract client IP address from "X-Forwarded-For" http header. */
@Nullable
static String extractClientIpFromForwardedForHeader(String forwardedFor) {
return extractIpAddress(forwardedFor, 0);
}

@Nullable
static String extractForwardedFor(String forwarded) {
return extractIpAddress(forwarded, 0);
private static String extractProto(String forwarded, int start) {
if (forwarded.length() == start) {
return null;
}
if (forwarded.charAt(start) == '"') {
return extractProto(forwarded, start + 1);
}
for (int i = start; i < forwarded.length(); i++) {
char c = forwarded.charAt(i);
if (c == ',' || c == ';' || c == '"') {
if (i == start) { // empty string
return null;
}
return forwarded.substring(start, i);
}
}
return forwarded.substring(start);
}

// from https://www.rfc-editor.org/rfc/rfc7239
Expand All @@ -53,7 +93,7 @@ private static String extractIpAddress(String forwarded, int start) {
return forwarded.substring(start + 1, end);
}
boolean inIpv4 = false;
for (int i = start; i < forwarded.length() - 1; i++) {
for (int i = start; i < forwarded.length(); i++) {
char c = forwarded.charAt(i);
if (c == '.') {
inIpv4 = true;
Expand All @@ -67,5 +107,5 @@ private static String extractIpAddress(String forwarded, int start) {
return forwarded.substring(start);
}

private ForwarderHeaderParser() {}
private ForwardedHeaderParser() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

package io.opentelemetry.instrumentation.api.instrumenter.http;

import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwarderHeaderParser.extractForwarded;
import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwarderHeaderParser.extractForwardedFor;
import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwardedHeaderParser.extractClientIpFromForwardedForHeader;
import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwardedHeaderParser.extractClientIpFromForwardedHeader;
import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwardedHeaderParser.extractProtoFromForwardedHeader;
import static io.opentelemetry.instrumentation.api.instrumenter.http.ForwardedHeaderParser.extractProtoFromForwardedProtoHeader;

import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
Expand Down Expand Up @@ -64,7 +66,11 @@ public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST
super.onStart(attributes, parentContext, request);

set(attributes, SemanticAttributes.HTTP_FLAVOR, getter.flavor(request));
set(attributes, SemanticAttributes.HTTP_SCHEME, getter.scheme(request));
String forwardedProto = forwardedProto(request);
set(
attributes,
SemanticAttributes.HTTP_SCHEME,
forwardedProto != null ? forwardedProto : getter.scheme(request));
set(attributes, SemanticAttributes.HTTP_HOST, host(request));
set(attributes, SemanticAttributes.HTTP_TARGET, getter.target(request));
set(attributes, SemanticAttributes.HTTP_ROUTE, getter.route(request));
Expand All @@ -89,12 +95,32 @@ private String host(REQUEST request) {
return firstHeaderValue(getter.requestHeader(request, "host"));
}

@Nullable
private String forwardedProto(REQUEST request) {
// try Forwarded
String forwarded = firstHeaderValue(getter.requestHeader(request, "forwarded"));
if (forwarded != null) {
forwarded = extractProtoFromForwardedHeader(forwarded);
if (forwarded != null) {
return forwarded;
}
}

// try X-Forwarded-Proto
forwarded = firstHeaderValue(getter.requestHeader(request, "x-forwarded-proto"));
if (forwarded != null) {
return extractProtoFromForwardedProtoHeader(forwarded);
}

return null;
}

@Nullable
private String clientIp(REQUEST request) {
// try Forwarded
String forwarded = firstHeaderValue(getter.requestHeader(request, "forwarded"));
if (forwarded != null) {
forwarded = extractForwarded(forwarded);
forwarded = extractClientIpFromForwardedHeader(forwarded);
if (forwarded != null) {
return forwarded;
}
Expand All @@ -103,7 +129,7 @@ private String clientIp(REQUEST request) {
// try X-Forwarded-For
forwarded = firstHeaderValue(getter.requestHeader(request, "x-forwarded-for"));
if (forwarded != null) {
return extractForwardedFor(forwarded);
return extractClientIpFromForwardedForHeader(forwarded);
}

return null;
Expand Down
Loading