Skip to content

Commit

Permalink
refactor: move forwarded parsing into the UriFilterProxyHeaderParser
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneBab committed May 22, 2022
1 parent 9ace02f commit cbfac8a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 42 deletions.
35 changes: 1 addition & 34 deletions src/freenet/clients/http/FProxyToadlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import freenet.client.DefaultMIMETypes;
Expand Down Expand Up @@ -998,41 +996,10 @@ private String getSchemeHostAndPort(ToadletContext ctx) {

// get uri host and headers
MultiValueTable<String, String> headers = ctx.getHeaders();
Map<String, String> forwarded = parseForwardedHeader(headers.get("forwarded"));
String uriScheme = ctx.getUri().getScheme();
String uriHost = ctx.getUri().getHost();

return UriFilterProxyHeaderParser.parse(fProxyPort, fProxyBindTo, uriScheme, uriHost, headers, forwarded).toString();
}

private Map<String, String> parseForwardedHeader(String forwarded) {
if (forwarded == null || forwarded.trim().isEmpty()) {
return new HashMap<>();
}
Map<String, String> headerParams = new HashMap<>();

// if a multi-value header is given, only use the first value.
int indexOfComma = forwarded.indexOf(',');
if (indexOfComma != -1) {
forwarded = forwarded.substring(0, indexOfComma);
}
boolean hasAtLeastOneKey = forwarded.indexOf('=') != -1;
boolean hasMultipleKeys = forwarded.indexOf(';') != -1;
String[] fields;
if (hasMultipleKeys) {
fields = forwarded.split(";");
} else if (hasAtLeastOneKey) {
fields = new String[]{ forwarded };
} else {
return headerParams;
}
for (String field : fields) {
if (field.indexOf('=') != 1) {
String[] keyAndValue = field.split("=");
headerParams.put(keyAndValue[0], keyAndValue[1]);
}
}
return headerParams;
return UriFilterProxyHeaderParser.parse(fProxyPort, fProxyBindTo, uriScheme, uriHost, headers).toString();
}

private boolean isBrowser(String ua) {
Expand Down
39 changes: 35 additions & 4 deletions src/freenet/clients/http/utils/UriFilterProxyHeaderParser.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package freenet.clients.http.utils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand All @@ -13,14 +14,13 @@
public class UriFilterProxyHeaderParser {
private UriFilterProxyHeaderParser() {}

public static SchemeAndHostWithPort parse (
public static SchemeAndHostWithPort parse(
Option<?> fProxyPortConfig,
Option<?> fProxyBindToConfig,
String uriScheme,
String uriHost,
MultiValueTable<String, String> headers,
Map<String, String> forwarded
) {
MultiValueTable<String, String> headers
) {
Set<String> safeProtocols = new HashSet<>(Arrays.asList("http", "https"));

List<String> bindToHosts = Arrays.stream(fProxyBindToConfig.getValueString().split(","))
Expand All @@ -41,6 +41,7 @@ public static SchemeAndHostWithPort parse (
.map(host -> host + ":" + port)
.collect(Collectors.toList()));
// check uri host and headers
Map<String, String> forwarded = parseForwardedHeader(headers.get("forwarded"));
String protocol = forwarded.getOrDefault("proto", headers.containsKey("x-forwarded-proto")
? headers.get("x-forwarded-proto")
: uriScheme != null && !uriScheme.trim().isEmpty() ? uriScheme : "http");
Expand Down Expand Up @@ -73,4 +74,34 @@ public String toString() {
return scheme + "://" + host;
}
}

private static Map<String, String> parseForwardedHeader(String forwarded) {
if (forwarded == null || forwarded.trim().isEmpty()) {
return new HashMap<>();
}
Map<String, String> headerParams = new HashMap<>();

// if a multi-value header is given, only use the first value.
int indexOfComma = forwarded.indexOf(',');
if (indexOfComma != -1) {
forwarded = forwarded.substring(0, indexOfComma);
}
boolean hasAtLeastOneKey = forwarded.indexOf('=') != -1;
boolean hasMultipleKeys = forwarded.indexOf(';') != -1;
String[] fields;
if (hasMultipleKeys) {
fields = forwarded.split(";");
} else if (hasAtLeastOneKey) {
fields = new String[]{ forwarded };
} else {
return headerParams;
}
for (String field : fields) {
if (field.indexOf('=') != 1) {
String[] keyAndValue = field.split("=");
headerParams.put(keyAndValue[0], keyAndValue[1]);
}
}
return headerParams;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import static org.junit.Assert.assertTrue;

import java.util.HashMap;

import org.junit.Test;

import freenet.config.Config;
Expand Down Expand Up @@ -287,8 +285,7 @@ private void testUriPrefixMatchesExpected(
fakeBindToOption(fProxyBindTo),
uriScheme,
uriHost,
headers,
new HashMap<>())
headers)
.toString();
assertTrue(
String.format(
Expand Down

0 comments on commit cbfac8a

Please sign in to comment.