@@ -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
0 commit comments