Skip to content

Commit 3598115

Browse files
committed
wip
1 parent 9c23def commit 3598115

File tree

1 file changed

+88
-79
lines changed

1 file changed

+88
-79
lines changed

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

Lines changed: 88 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -204,96 +204,105 @@ enum ForwardedParseState {
204204

205205
@Override
206206
public InetAddress apply(String headerValue) {
207-
String[] entries = headerValue.split(",");
208-
for (int i = entries.length - 1; i >= 0; i--) {
209-
String entry = entries[i].trim();
210-
InetAddress resultPrivate = null;
211-
ForwardedParseState state = ForwardedParseState.BETWEEN;
212-
// https://datatracker.ietf.org/doc/html/rfc7239#section-4
213-
int pos = 0;
214-
int end = entry.length();
215-
// compiler requires that these two be initialized:
216-
int start = 0;
217-
boolean considerValue = false;
218-
while (pos < end) {
219-
char c = entry.charAt(pos);
220-
switch (state) {
221-
case BETWEEN:
222-
if (c == ' ' || c == ';' || c == ',') {
207+
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;
223235
break;
224-
}
225-
start = pos;
226-
state = ForwardedParseState.KEY;
227-
break;
228-
case KEY:
229-
if (c != '=') {
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+
}
230247
break;
231-
}
232-
233-
state = ForwardedParseState.BEFORE_VALUE;
234-
if (pos - start == 3) {
235-
String key = entry.substring(start, pos);
236-
considerValue = key.equalsIgnoreCase("for");
237-
} else {
238-
considerValue = false;
239-
}
240-
break;
241-
case BEFORE_VALUE:
242-
if (c == '"') {
243-
start = pos + 1;
244-
state = ForwardedParseState.VALUE_QUOTED;
245-
} else if (c == ' ' || c == ';' || c == ',') {
246-
// empty value
247-
state = ForwardedParseState.BETWEEN;
248-
} else {
249-
start = pos;
250-
state = ForwardedParseState.VALUE_TOKEN;
251-
}
252-
break;
253-
case VALUE_TOKEN:
254-
{
255-
int tokenEnd;
256-
if (c == ' ' || c == ';' || c == ',') {
257-
tokenEnd = pos;
258-
} else if (pos + 1 == end) {
259-
tokenEnd = end;
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;
260255
} else {
261-
break;
256+
start = pos;
257+
state = ForwardedParseState.VALUE_TOKEN;
262258
}
263-
264-
if (considerValue) {
265-
InetAddress ipAddr = parseIpAddressAndMaybePort(entry.substring(start, tokenEnd));
266-
if (ipAddr != null) {
267-
if (isIpAddrPrivate(ipAddr)) {
268-
if (resultPrivate == null) {
269-
resultPrivate = ipAddr;
259+
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;
270280
}
271-
} else {
272-
return ipAddr;
273281
}
274282
}
283+
state = ForwardedParseState.BETWEEN;
284+
break;
275285
}
276-
state = ForwardedParseState.BETWEEN;
277-
break;
278-
}
279-
case VALUE_QUOTED:
280-
if (c == '"') {
281-
if (considerValue) {
282-
InetAddress ipAddr = parseIpAddressAndMaybePort(entry.substring(start, pos));
283-
if (ipAddr != null && !isIpAddrPrivate(ipAddr)) {
284-
return ipAddr;
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+
}
285293
}
294+
state = ForwardedParseState.BETWEEN;
295+
} else if (c == '\\') {
296+
pos++;
286297
}
287-
state = ForwardedParseState.BETWEEN;
288-
} else if (c == '\\') {
289-
pos++;
290-
}
291-
break;
298+
break;
299+
}
300+
pos++;
292301
}
293-
pos++;
294-
}
295-
if (resultPrivate != null) {
296-
return resultPrivate;
302+
if (resultPrivate != null) {
303+
return resultPrivate;
304+
}
305+
entryEnd = i;
297306
}
298307
}
299308
return null;

0 commit comments

Comments
 (0)