Skip to content

Commit 6af0ef3

Browse files
committed
wip
1 parent 5f8c944 commit 6af0ef3

File tree

2 files changed

+80
-94
lines changed

2 files changed

+80
-94
lines changed

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/http/ClientIpAddressResolver.java

Lines changed: 80 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -204,108 +204,95 @@ enum ForwardedParseState {
204204

205205
@Override
206206
public InetAddress apply(String headerValue) {
207+
InetAddress resultPrivate = null;
208+
ForwardedParseState state = ForwardedParseState.BETWEEN;
209+
210+
// https://datatracker.ietf.org/doc/html/rfc7239#section-4
211+
int pos = 0;
207212
int end = headerValue.length();
208-
int entryEnd = end;
209-
// Parse entries right-to-left, separated by ','
210-
for (int i = end - 1; i >= -1; i--) {
211-
if (i == -1 || headerValue.charAt(i) == ',') {
212-
int entryStart = i + 1;
213-
// skip leading spaces
214-
while (entryStart < entryEnd && headerValue.charAt(entryStart) == ' ') {
215-
entryStart++;
216-
}
217-
String entry = headerValue.substring(entryStart, entryEnd);
218-
InetAddress resultPrivate = null;
219-
ForwardedParseState state = ForwardedParseState.BETWEEN;
220-
// https://datatracker.ietf.org/doc/html/rfc7239#section-4
221-
int pos = 0;
222-
int entryLen = entry.length();
223-
// compiler requires that these two be initialized:
224-
int start = 0;
225-
boolean considerValue = false;
226-
while (pos < entryLen) {
227-
char c = entry.charAt(pos);
228-
switch (state) {
229-
case BETWEEN:
230-
if (c == ' ' || c == ';' || c == ',') {
231-
break;
232-
}
233-
start = pos;
234-
state = ForwardedParseState.KEY;
235-
break;
236-
case KEY:
237-
if (c != '=') {
238-
break;
239-
}
240-
state = ForwardedParseState.BEFORE_VALUE;
241-
if (pos - start == 3) {
242-
String key = entry.substring(start, pos);
243-
considerValue = key.equalsIgnoreCase("for");
244-
} else {
245-
considerValue = false;
246-
}
247-
break;
248-
case BEFORE_VALUE:
249-
if (c == '"') {
250-
start = pos + 1;
251-
state = ForwardedParseState.VALUE_QUOTED;
252-
} else if (c == ' ' || c == ';' || c == ',') {
253-
// empty value
254-
state = ForwardedParseState.BETWEEN;
255-
} else {
256-
start = pos;
257-
state = ForwardedParseState.VALUE_TOKEN;
258-
}
213+
// compiler requires that these two be initialized:
214+
int start = 0;
215+
boolean considerValue = false;
216+
while (pos < end) {
217+
char c = headerValue.charAt(pos);
218+
switch (state) {
219+
case BETWEEN:
220+
if (c == ' ' || c == ';' || c == ',') {
221+
break;
222+
}
223+
start = pos;
224+
state = ForwardedParseState.KEY;
225+
break;
226+
case KEY:
227+
if (c != '=') {
228+
break;
229+
}
230+
231+
state = ForwardedParseState.BEFORE_VALUE;
232+
if (pos - start == 3) {
233+
String key = headerValue.substring(start, pos);
234+
considerValue = key.equalsIgnoreCase("for");
235+
} else {
236+
considerValue = false;
237+
}
238+
break;
239+
case BEFORE_VALUE:
240+
if (c == '"') {
241+
start = pos + 1;
242+
state = ForwardedParseState.VALUE_QUOTED;
243+
} else if (c == ' ' || c == ';' || c == ',') {
244+
// empty value
245+
state = ForwardedParseState.BETWEEN;
246+
} else {
247+
start = pos;
248+
state = ForwardedParseState.VALUE_TOKEN;
249+
}
250+
break;
251+
case VALUE_TOKEN:
252+
{
253+
int tokenEnd;
254+
if (c == ' ' || c == ';' || c == ',') {
255+
tokenEnd = pos;
256+
} else if (pos + 1 == end) {
257+
tokenEnd = end;
258+
} else {
259259
break;
260-
case VALUE_TOKEN:
261-
{
262-
int tokenEnd;
263-
if (c == ' ' || c == ';' || c == ',') {
264-
tokenEnd = pos;
265-
} else if (pos + 1 == entryLen) {
266-
tokenEnd = entryLen;
267-
} else {
268-
break;
269-
}
270-
if (considerValue) {
271-
InetAddress ipAddr =
272-
parseIpAddressAndMaybePort(entry.substring(start, tokenEnd));
273-
if (ipAddr != null) {
274-
if (isIpAddrPrivate(ipAddr)) {
275-
if (resultPrivate == null) {
276-
resultPrivate = ipAddr;
277-
}
278-
} else {
279-
return ipAddr;
280-
}
260+
}
261+
262+
if (considerValue) {
263+
InetAddress ipAddr =
264+
parseIpAddressAndMaybePort(headerValue.substring(start, tokenEnd));
265+
if (ipAddr != null) {
266+
if (isIpAddrPrivate(ipAddr)) {
267+
if (resultPrivate == null) {
268+
resultPrivate = ipAddr;
281269
}
270+
} else {
271+
return ipAddr;
282272
}
283-
state = ForwardedParseState.BETWEEN;
284-
break;
285273
}
286-
case VALUE_QUOTED:
287-
if (c == '"') {
288-
if (considerValue) {
289-
InetAddress ipAddr = parseIpAddressAndMaybePort(entry.substring(start, pos));
290-
if (ipAddr != null && !isIpAddrPrivate(ipAddr)) {
291-
return ipAddr;
292-
}
293-
}
294-
state = ForwardedParseState.BETWEEN;
295-
} else if (c == '\\') {
296-
pos++;
274+
}
275+
state = ForwardedParseState.BETWEEN;
276+
break;
277+
}
278+
case VALUE_QUOTED:
279+
if (c == '"') {
280+
if (considerValue) {
281+
InetAddress ipAddr = parseIpAddressAndMaybePort(headerValue.substring(start, pos));
282+
if (ipAddr != null && !isIpAddrPrivate(ipAddr)) {
283+
return ipAddr;
297284
}
298-
break;
285+
}
286+
state = ForwardedParseState.BETWEEN;
287+
} else if (c == '\\') {
288+
pos++;
299289
}
300-
pos++;
301-
}
302-
if (resultPrivate != null) {
303-
return resultPrivate;
304-
}
305-
entryEnd = i;
290+
break;
306291
}
292+
pos++;
307293
}
308-
return null;
294+
295+
return resultPrivate;
309296
}
310297
}
311298

dd-java-agent/agent-bootstrap/src/test/groovy/datadog/trace/bootstrap/instrumentation/decorator/http/ClientIpAddressResolverSpecification.groovy

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ class ClientIpAddressResolverSpecification extends Specification {
8282
'forwarded' | ' for=127.0.0.1,for= for=,for=;"for = for="" ,; for=8.8.8.8;' | '8.8.8.8'
8383
'forwarded' | 'for=192.0.2.60;proto=http;by=203.0.113.43' | '192.0.2.60'
8484
'forwarded' | 'For="[2001:db8:cafe::17]:4711"' | '2001:db8:cafe::17'
85-
'forwarded' | 'for=192.0.2.43, for=198.51.100.17' | '198.51.100.17'
8685
'forwarded' | 'for=192.0.2.43;proto=https;by=203.0.113.43' | '192.0.2.43'
8786
'forwarded' | 'for="_gazonk"' | null
8887
'forwarded' | 'for=unknown, for=8.8.8.8' | '8.8.8.8'

0 commit comments

Comments
 (0)