Skip to content

Commit

Permalink
Use TreeMap to store headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Jan 30, 2024
1 parent 1f1f72d commit 8fb0e17
Showing 1 changed file with 13 additions and 46 deletions.
59 changes: 13 additions & 46 deletions src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,14 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.TreeMap;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import static org.jsoup.Connection.Method.HEAD;
import static org.jsoup.helper.DataUtil.UTF_8;
import static org.jsoup.internal.Normalizer.lowerCase;

/**
* Implementation of {@link Connection}.
Expand Down Expand Up @@ -405,18 +404,18 @@ private static abstract class Base<T extends Connection.Base<T>> implements Conn
Map<String, String> cookies;

private Base() {
headers = new LinkedHashMap<>();
headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
cookies = new LinkedHashMap<>();
}

private Base(Base<T> copy) {
this();
url = copy.url; // unmodifiable object
method = copy.method;
headers = new LinkedHashMap<>();
for (Map.Entry<String, List<String>> entry : copy.headers.entrySet()) {
headers.put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
cookies = new LinkedHashMap<>(); cookies.putAll(copy.cookies); // just holds strings
cookies.putAll(copy.cookies); // just holds strings
}

@Override
Expand Down Expand Up @@ -448,8 +447,8 @@ public T method(Method method) {
@Override
public String header(String name) {
Validate.notNullParam(name, "name");
List<String> vals = getHeadersCaseInsensitive(name);
if (vals.size() > 0) {
List<String> vals = headers.get(name);
if (vals != null) {
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
return StringUtil.join(vals, ", ");
}
Expand All @@ -460,23 +459,17 @@ public String header(String name) {
@Override
public T addHeader(String name, @Nullable String value) {
Validate.notEmptyParam(name, "name");
//noinspection ConstantConditions
value = value == null ? "" : value;

List<String> values = headers(name);
if (values.isEmpty()) {
values = new ArrayList<>();
headers.put(name, values);
}
values.add(value);
headers.computeIfAbsent(name, Functions.listFunction())
.add(value == null ? "" : value);

return (T) this;
}

@Override
public List<String> headers(String name) {
Validate.notEmptyParam(name, "name");
return getHeadersCaseInsensitive(name);
return headers.getOrDefault(name, Collections.emptyList());
}

@Override
Expand All @@ -490,7 +483,7 @@ public T header(String name, String value) {
@Override
public boolean hasHeader(String name) {
Validate.notEmptyParam(name, "name");
return !getHeadersCaseInsensitive(name).isEmpty();
return headers.containsKey(name);
}

/**
Expand All @@ -500,20 +493,14 @@ public boolean hasHeader(String name) {
public boolean hasHeaderWithValue(String name, String value) {
Validate.notEmpty(name);
Validate.notEmpty(value);
List<String> values = headers(name);
for (String candidate : values) {
if (value.equalsIgnoreCase(candidate))
return true;
}
return false;
return headers.getOrDefault(name, Collections.emptyList()).stream()
.anyMatch(value::equalsIgnoreCase);
}

@Override
public T removeHeader(String name) {
Validate.notEmptyParam(name, "name");
Map.Entry<String, List<String>> entry = scanHeaders(name); // remove is case-insensitive too
if (entry != null)
headers.remove(entry.getKey()); // ensures correct case
headers.remove(name); // remove is case-insensitive too
return (T) this;
}

Expand All @@ -534,26 +521,6 @@ public Map<String, List<String>> multiHeaders() {
return headers;
}

private List<String> getHeadersCaseInsensitive(String name) {
Validate.notNull(name);

for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
if (name.equalsIgnoreCase(entry.getKey()))
return entry.getValue();
}

return Collections.emptyList();
}

private Map.@Nullable Entry<String, List<String>> scanHeaders(String name) {
String lc = lowerCase(name);
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
if (lowerCase(entry.getKey()).equals(lc))
return entry;
}
return null;
}

@Override
public String cookie(String name) {
Validate.notEmptyParam(name, "name");
Expand Down

0 comments on commit 8fb0e17

Please sign in to comment.