mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 18:35:25 +00:00
Watcher: Ensure that HTTP headers are case insensitive in response
According to RFC 2616 HTTP headers are case insensitive. But `HttpResponse#contentType()` only looks up for Content-Type. This stores all header responses lower cased in the HTTP response. Closes elastic/elasticsearch#1357 Original commit: elastic/x-pack-elasticsearch@c009be8365
This commit is contained in:
parent
166e8786ea
commit
93a3d3f570
@ -201,7 +201,7 @@ public class HttpClient extends AbstractLifecycleComponent<HttpClient> {
|
||||
urlConnection.connect();
|
||||
|
||||
final int statusCode = urlConnection.getResponseCode();
|
||||
Map<String, String[]> responseHeaders = new HashMap<>();
|
||||
Map<String, String[]> responseHeaders = new HashMap<>(urlConnection.getHeaderFields().size());
|
||||
for (Map.Entry<String, List<String>> header : urlConnection.getHeaderFields().entrySet()) {
|
||||
// HttpURLConnection#getHeaderFields returns the first status line as a header
|
||||
// with a `null` key (facepalm)... so we have to skip that one.
|
||||
@ -209,7 +209,6 @@ public class HttpClient extends AbstractLifecycleComponent<HttpClient> {
|
||||
responseHeaders.put(header.getKey(), header.getValue().toArray(new String[header.getValue().size()]));
|
||||
}
|
||||
}
|
||||
responseHeaders = unmodifiableMap(responseHeaders);
|
||||
logger.debug("http status code [{}]", statusCode);
|
||||
if (statusCode < 400) {
|
||||
final byte[] body;
|
||||
|
@ -11,6 +11,7 @@ import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
@ -22,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
@ -60,7 +62,11 @@ public class HttpResponse implements ToXContent {
|
||||
public HttpResponse(int status, @Nullable BytesReference body, Map<String, String[]> headers) {
|
||||
this.status = status;
|
||||
this.body = body;
|
||||
this.headers = headers;
|
||||
MapBuilder<String, String[]> mapBuilder = MapBuilder.newMapBuilder();
|
||||
for (Map.Entry<String, String[]> entry : headers.entrySet()) {
|
||||
mapBuilder.put(entry.getKey().toLowerCase(Locale.ROOT), entry.getValue());
|
||||
}
|
||||
this.headers = mapBuilder.immutableMap();
|
||||
}
|
||||
|
||||
public int status() {
|
||||
@ -75,12 +81,12 @@ public class HttpResponse implements ToXContent {
|
||||
return body;
|
||||
}
|
||||
|
||||
public Map<String, String[]> headers() {
|
||||
return headers;
|
||||
public String[] header(String header) {
|
||||
return headers.get(header.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public String contentType() {
|
||||
String[] values = headers.get(HttpHeaders.Names.CONTENT_TYPE);
|
||||
String[] values = header(HttpHeaders.Names.CONTENT_TYPE);
|
||||
if (values == null || values.length == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -88,7 +94,7 @@ public class HttpResponse implements ToXContent {
|
||||
}
|
||||
|
||||
public XContentType xContentType() {
|
||||
String[] values = headers.get(HttpHeaders.Names.CONTENT_TYPE);
|
||||
String[] values = header(HttpHeaders.Names.CONTENT_TYPE);
|
||||
if (values == null || values.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
@ -77,9 +78,17 @@ public class HttpResponseTests extends ESTestCase {
|
||||
} else {
|
||||
assertThat(parsedResponse.body().toUtf8(), is(body));
|
||||
}
|
||||
assertThat(parsedResponse.headers().size(), is(headers.size()));
|
||||
for (Map.Entry<String, String[]> header : parsedResponse.headers().entrySet()) {
|
||||
assertThat(header.getValue(), arrayContaining(headers.get(header.getKey())));
|
||||
for (Map.Entry<String, String[]> headerEntry : headers.entrySet()) {
|
||||
assertThat(headerEntry.getValue(), arrayContaining(parsedResponse.header(headerEntry.getKey())));
|
||||
}
|
||||
}
|
||||
|
||||
public void testThatHeadersAreCaseInsensitive() {
|
||||
Map<String, String[]> headers = new HashMap<>();
|
||||
headers.put(randomFrom("key", "keY", "KEY", "Key"), new String[] { "value" });
|
||||
headers.put(randomFrom("content-type"), new String[] { "text/html" });
|
||||
HttpResponse response = new HttpResponse(200, headers);
|
||||
assertThat(response.header("key")[0], is("value"));
|
||||
assertThat(response.contentType(), is("text/html"));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user