Skip to content

Commit

Permalink
Support forwarded proto field and x-forwarded-proto (#5357)
Browse files Browse the repository at this point in the history
* Renames for the better

* Support forwarded proto

* fix

* Fix checkstyle complaining about abbrevation

* checkstyle
  • Loading branch information
trask authored Feb 22, 2022
1 parent 704f161 commit 23ec767
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 247 deletions.
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

0 comments on commit 23ec767

Please sign in to comment.