Client request implementations enforce RFC 6265 (cookies in a single header)
Issue: SPR-12196
(cherry picked from commit 26a93b6)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,6 @@ import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
@@ -33,6 +30,10 @@ import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.http.client.ClientHttpRequest} implementation that uses
|
||||
* Apache HttpComponents HttpClient to execute requests.
|
||||
@@ -53,7 +54,7 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR
|
||||
private final HttpContext httpContext;
|
||||
|
||||
|
||||
public HttpComponentsClientHttpRequest(HttpClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) {
|
||||
HttpComponentsClientHttpRequest(HttpClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) {
|
||||
this.httpClient = httpClient;
|
||||
this.httpRequest = httpRequest;
|
||||
this.httpContext = httpContext;
|
||||
@@ -71,15 +72,8 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR
|
||||
|
||||
@Override
|
||||
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
if (!headerName.equalsIgnoreCase(HTTP.CONTENT_LEN) &&
|
||||
!headerName.equalsIgnoreCase(HTTP.TRANSFER_ENCODING)) {
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.httpRequest.addHeader(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
addHeaders(this.httpRequest, headers);
|
||||
|
||||
if (this.httpRequest instanceof HttpEntityEnclosingRequest) {
|
||||
HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest;
|
||||
HttpEntity requestEntity = new ByteArrayEntity(bufferedOutput);
|
||||
@@ -89,4 +83,26 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR
|
||||
return new HttpComponentsClientHttpResponse(httpResponse);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the given headers to the given HTTP request.
|
||||
* @param httpRequest the request to add the headers to
|
||||
* @param headers the headers to add
|
||||
*/
|
||||
static void addHeaders(HttpUriRequest httpRequest, HttpHeaders headers) {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
if ("Cookie".equalsIgnoreCase(headerName)) { // RFC 6265
|
||||
String headerValue = StringUtils.collectionToDelimitedString(entry.getValue(), "; ");
|
||||
httpRequest.addHeader(headerName, headerValue);
|
||||
}
|
||||
else if (!HTTP.CONTENT_LEN.equalsIgnoreCase(headerName) &&
|
||||
!HTTP.TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
|
||||
for (String headerValue : entry.getValue()) {
|
||||
httpRequest.addHeader(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,12 +26,14 @@ import java.util.Map;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute buffered requests.
|
||||
* Created via the {@link SimpleClientHttpRequestFactory}.
|
||||
* {@link ClientHttpRequest} implementation that uses standard JDK facilities to
|
||||
* execute buffered requests. Created via the {@link SimpleClientHttpRequestFactory}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod)
|
||||
*/
|
||||
@@ -63,12 +65,7 @@ final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttp
|
||||
|
||||
@Override
|
||||
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.connection.addRequestProperty(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
addHeaders(this.connection, headers);
|
||||
|
||||
if (this.connection.getDoOutput() && this.outputStreaming) {
|
||||
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
|
||||
@@ -81,4 +78,25 @@ final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttp
|
||||
return new SimpleClientHttpResponse(this.connection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the given headers to the given HTTP connection.
|
||||
* @param connection the connection to add the headers to
|
||||
* @param headers the headers to add
|
||||
*/
|
||||
static void addHeaders(HttpURLConnection connection, HttpHeaders headers) {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
if ("Cookie".equalsIgnoreCase(headerName)) { // RFC 6265
|
||||
String headerValue = StringUtils.collectionToDelimitedString(entry.getValue(), "; ");
|
||||
connection.setRequestProperty(headerName, headerValue);
|
||||
}
|
||||
else {
|
||||
for (String headerValue : entry.getValue()) {
|
||||
connection.addRequestProperty(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,16 +21,14 @@ import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequest} implementation that uses standard J2SE facilities to execute streaming requests.
|
||||
* Created via the {@link SimpleClientHttpRequestFactory}.
|
||||
* {@link ClientHttpRequest} implementation that uses standard JDK facilities to
|
||||
* execute streaming requests. Created via the {@link SimpleClientHttpRequestFactory}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
@@ -79,22 +77,13 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
|
||||
this.connection.setChunkedStreamingMode(this.chunkSize);
|
||||
}
|
||||
}
|
||||
writeHeaders(headers);
|
||||
SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers);
|
||||
this.connection.connect();
|
||||
this.body = this.connection.getOutputStream();
|
||||
}
|
||||
return StreamUtils.nonClosing(this.body);
|
||||
}
|
||||
|
||||
private void writeHeaders(HttpHeaders headers) {
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String headerName = entry.getKey();
|
||||
for (String headerValue : entry.getValue()) {
|
||||
this.connection.addRequestProperty(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException {
|
||||
try {
|
||||
@@ -102,7 +91,7 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest {
|
||||
this.body.close();
|
||||
}
|
||||
else {
|
||||
writeHeaders(headers);
|
||||
SimpleBufferingClientHttpRequest.addHeaders(this.connection, headers);
|
||||
this.connection.connect();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user