Skip to content

Commit

Permalink
Use TreeMap when processing response headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Feb 16, 2024
1 parent 8fb0e17 commit c61f7fa
Showing 1 changed file with 23 additions and 34 deletions.
57 changes: 23 additions & 34 deletions src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ private Response(HttpURLConnection conn, HttpConnection.Request request, HttpCon
statusMessage = conn.getResponseMessage();
contentType = conn.getContentType();

Map<String, List<String>> resHeaders = createHeaderMap(conn);
TreeMap<String, List<String>> resHeaders = createHeaderMap(conn);
processResponseHeaders(resHeaders); // includes cookie key/val read during header scan
CookieUtil.storeCookies(req, url, resHeaders); // add set cookies to cookie store

Expand All @@ -1093,47 +1093,36 @@ private Response(HttpURLConnection conn, HttpConnection.Request request, HttpCon
}
}

private static LinkedHashMap<String, List<String>> createHeaderMap(HttpURLConnection conn) {
// the default sun impl of conn.getHeaderFields() returns header values out of order
final LinkedHashMap<String, List<String>> headers = new LinkedHashMap<>();
int i = 0;
while (true) {
final String key = conn.getHeaderFieldKey(i);
final String val = conn.getHeaderField(i);
if (key == null && val == null)
break;
i++;
if (key == null || val == null)
continue; // skip http1.1 line

final List<String> vals = headers.computeIfAbsent(key, Functions.listFunction());
vals.add(val);
private static TreeMap<String, List<String>> createHeaderMap(HttpURLConnection conn) {
final TreeMap<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (Map.Entry<String, List<String>> entry : conn.getHeaderFields().entrySet()) {
if (entry.getKey() != null) { // skip http1.1 line
headers.put(entry.getKey(), entry.getValue());
}
}
return headers;
}

void processResponseHeaders(Map<String, List<String>> resHeaders) {
// Using TreeMap allows the key to be checked case-insensitively
for (String value : resHeaders.getOrDefault("Set-Cookie", Collections.emptyList())) {
if (value == null)
continue;
TokenQueue cd = new TokenQueue(value);
String cookieName = cd.chompTo("=").trim();
String cookieVal = cd.consumeTo(";").trim();
// ignores path, date, domain, validateTLSCertificates et al. full details will be available in cookiestore if required
// name not blank, value not null
if (!cookieName.isEmpty() && !cookies.containsKey(cookieName)) // if duplicates, only keep the first
super.cookie(cookieName, cookieVal);
}

for (Map.Entry<String, List<String>> entry : resHeaders.entrySet()) {
String name = entry.getKey();
if (name == null)
if (entry.getKey() == null)
continue; // http/1.1 line

List<String> values = entry.getValue();
if (name.equalsIgnoreCase("Set-Cookie")) {
for (String value : values) {
if (value == null)
continue;
TokenQueue cd = new TokenQueue(value);
String cookieName = cd.chompTo("=").trim();
String cookieVal = cd.consumeTo(";").trim();
// ignores path, date, domain, validateTLSCertificates et al. full details will be available in cookiestore if required
// name not blank, value not null
if (cookieName.length() > 0 && !cookies.containsKey(cookieName)) // if duplicates, only keep the first
cookie(cookieName, cookieVal);
}
}
for (String value : values) {
addHeader(name, fixHeaderEncoding(value));
for (String value : entry.getValue()) {
addHeader(entry.getKey(), fixHeaderEncoding(value));
}
}
}
Expand Down

0 comments on commit c61f7fa

Please sign in to comment.