You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2012/03/18 16:10:58 UTC
svn commit: r1302139 - in /httpcomponents/httpcore/branches/4.1.x:
httpcore-nio/src/main/java/org/apache/http/impl/nio/
httpcore/src/main/java/org/apache/http/impl/
httpcore/src/main/java/org/apache/http/impl/entity/
httpcore/src/test/java/org/apache/h...
Author: olegk
Date: Sun Mar 18 15:10:58 2012
New Revision: 1302139
URL: http://svn.apache.org/viewvc?rev=1302139&view=rev
Log:
HTTPCORE-296: server side connections (both blocking and non-blocking) to reject entity enclosing requests without Content-Length and Transfer-Encoding headers as invalid
Added:
httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java (with props)
Modified:
httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java
httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/mockup/HttpClient.java
httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.java
Modified: httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java?rev=1302139&r1=1302138&r2=1302139&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java (original)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/DefaultNHttpServerConnection.java Sun Mar 18 15:10:58 2012
@@ -37,6 +37,9 @@ import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestFactory;
import org.apache.http.HttpResponse;
+import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy;
+import org.apache.http.impl.entity.LaxContentLengthStrategy;
import org.apache.http.impl.nio.codecs.DefaultHttpRequestParser;
import org.apache.http.impl.nio.codecs.DefaultHttpResponseWriter;
import org.apache.http.nio.NHttpMessageParser;
@@ -92,6 +95,11 @@ public class DefaultNHttpServerConnectio
this.responseWriter = createResponseWriter(this.outbuf, params);
}
+ @Override
+ protected ContentLengthStrategy createIncomingContentStrategy() {
+ return new DisallowIdentityContentLengthStrategy(new LaxContentLengthStrategy());
+ }
+
/**
* Creates an instance of {@link NHttpMessageParser} to be used
* by this connection for parsing incoming {@link HttpRequest} messages.
Modified: httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java?rev=1302139&r1=1302138&r2=1302139&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java (original)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java Sun Mar 18 15:10:58 2012
@@ -139,8 +139,8 @@ public class NHttpConnectionBase
this.inbuf = new SessionInputBufferImpl(buffersize, linebuffersize, allocator, params);
this.outbuf = new SessionOutputBufferImpl(buffersize, linebuffersize, allocator, params);
- this.incomingContentStrategy = new LaxContentLengthStrategy();
- this.outgoingContentStrategy = new StrictContentLengthStrategy();
+ this.incomingContentStrategy = createIncomingContentStrategy();
+ this.outgoingContentStrategy = createOutgoingContentStrategy();
this.inTransportMetrics = createTransportMetrics();
this.outTransportMetrics = createTransportMetrics();
@@ -160,6 +160,37 @@ public class NHttpConnectionBase
}
/**
+<<<<<<< HEAD
+=======
+ * Binds the connection to a different {@link IOSession}. This may be necessary
+ * when the underlying I/O session gets upgraded with SSL/TLS encryption.
+ *
+ * @since 4.2
+ */
+ protected void bind(final IOSession session) {
+ if (session == null) {
+ throw new IllegalArgumentException("I/O session may not be null");
+ }
+ this.session.setBufferStatus(null);
+ setSession(session);
+ }
+
+ /**
+ * @since 4.2
+ */
+ protected ContentLengthStrategy createIncomingContentStrategy() {
+ return new LaxContentLengthStrategy();
+ }
+
+ /**
+ * @since 4.2
+ */
+ protected ContentLengthStrategy createOutgoingContentStrategy() {
+ return new StrictContentLengthStrategy();
+ }
+
+ /**
+>>>>>>> 74acee1... HTTPCORE-296: server side connections (both blocking and non-blocking) can now handle entity enclosing requests without Content-Length and Transfer-Encoding headers
* @since 4.1
*/
protected HttpTransportMetricsImpl createTransportMetrics() {
Modified: httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java?rev=1302139&r1=1302138&r2=1302139&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java (original)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/AbstractHttpServerConnection.java Sun Mar 18 15:10:58 2012
@@ -38,6 +38,7 @@ import org.apache.http.HttpRequestFactor
import org.apache.http.HttpResponse;
import org.apache.http.HttpServerConnection;
import org.apache.http.entity.ContentLengthStrategy;
+import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy;
import org.apache.http.impl.entity.EntityDeserializer;
import org.apache.http.impl.entity.EntitySerializer;
import org.apache.http.impl.entity.LaxContentLengthStrategy;
@@ -114,7 +115,8 @@ public abstract class AbstractHttpServer
* @return HTTP entity deserializer
*/
protected EntityDeserializer createEntityDeserializer() {
- return new EntityDeserializer(new LaxContentLengthStrategy());
+ return new EntityDeserializer(new DisallowIdentityContentLengthStrategy(
+ new LaxContentLengthStrategy()));
}
/**
Added: httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java?rev=1302139&view=auto
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java (added)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java Sun Mar 18 15:10:58 2012
@@ -0,0 +1,58 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.entity;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpMessage;
+import org.apache.http.ProtocolException;
+import org.apache.http.entity.ContentLengthStrategy;
+
+/**
+ * Decorator for {@link ContentLengthStrategy} implementations that disallows the use of
+ * identity transfer encoding.
+ *
+ * @since 4.2
+ */
+public class DisallowIdentityContentLengthStrategy implements ContentLengthStrategy {
+
+ private final ContentLengthStrategy contentLengthStrategy;
+
+ public DisallowIdentityContentLengthStrategy(final ContentLengthStrategy contentLengthStrategy) {
+ super();
+ this.contentLengthStrategy = contentLengthStrategy;
+ }
+
+ public long determineLength(final HttpMessage message) throws HttpException {
+ long result = this.contentLengthStrategy.determineLength(message);
+ if (result == ContentLengthStrategy.IDENTITY) {
+ throw new ProtocolException("Identity transfer encoding cannot be used");
+ }
+ return result;
+ }
+
+}
Propchange: httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/branches/4.1.x/httpcore/src/main/java/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/mockup/HttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/mockup/HttpClient.java?rev=1302139&r1=1302138&r2=1302139&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/mockup/HttpClient.java (original)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/mockup/HttpClient.java Sun Mar 18 15:10:58 2012
@@ -63,25 +63,29 @@ public class HttpClient {
private final ConnectionReuseStrategy connStrategy;
private final HttpContext context;
- public HttpClient() {
+ public HttpClient(final HttpProcessor httpproc) {
super();
+ this.httpproc = httpproc;
+ this.connStrategy = new DefaultConnectionReuseStrategy();
this.params = new SyncBasicHttpParams();
this.params
.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1)
.setParameter(CoreProtocolPNames.USER_AGENT, "TEST-CLIENT/1.1");
- this.httpproc = new ImmutableHttpProcessor(
+ this.httpexecutor = new HttpRequestExecutor();
+ this.context = new BasicHttpContext();
+ }
+
+ public HttpClient() {
+ this(new ImmutableHttpProcessor(
new HttpRequestInterceptor[] {
new RequestContent(),
new RequestTargetHost(),
new RequestConnControl(),
new RequestUserAgent(),
new RequestExpectContinue()
- });
- this.httpexecutor = new HttpRequestExecutor();
- this.connStrategy = new DefaultConnectionReuseStrategy();
- this.context = new BasicHttpContext();
+ }));
}
public HttpParams getParams() {
Modified: httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.java?rev=1302139&r1=1302138&r2=1302139&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.java (original)
+++ httpcomponents/httpcore/branches/4.1.x/httpcore/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.java Sun Mar 18 15:10:58 2012
@@ -46,6 +46,7 @@ import org.apache.http.HttpEntityEnclosi
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
@@ -58,6 +59,15 @@ import org.apache.http.message.BasicHttp
import org.apache.http.mockup.HttpClient;
import org.apache.http.mockup.HttpServer;
import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpExpectationVerifier;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.RequestConnControl;
+import org.apache.http.protocol.RequestExpectContinue;
+import org.apache.http.protocol.RequestTargetHost;
+import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EncodingUtils;
import org.apache.http.util.EntityUtils;
@@ -753,4 +763,158 @@ public class TestHttpServiceAndExecutor
}
}
+ public void testHttpPostNoEntity() throws Exception {
+ this.server.registerHandler("*", new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+ ByteArrayEntity outgoing = new ByteArrayEntity(data);
+ response.setEntity(outgoing);
+ } else {
+ StringEntity outgoing = new StringEntity("No content");
+ response.setEntity(outgoing);
+ }
+ }
+
+ });
+
+ this.server.start();
+
+ DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
+ HttpHost host = new HttpHost("localhost", this.server.getPort());
+
+ try {
+ if (!conn.isOpen()) {
+ Socket socket = new Socket(host.getHostName(), host.getPort());
+ conn.bind(socket, this.client.getParams());
+ }
+
+ BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+ post.setEntity(null);
+
+ HttpResponse response = this.client.execute(post, host, conn);
+ assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+ byte[] received = EntityUtils.toByteArray(response.getEntity());
+ assertEquals(0, received.length);
+ } finally {
+ conn.close();
+ this.server.shutdown();
+ }
+ }
+
+ public void testHttpPostNoContentLength() throws Exception {
+ this.server.registerHandler("*", new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+ ByteArrayEntity outgoing = new ByteArrayEntity(data);
+ response.setEntity(outgoing);
+ } else {
+ StringEntity outgoing = new StringEntity("No content");
+ response.setEntity(outgoing);
+ }
+ }
+
+ });
+
+ this.server.start();
+
+ DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
+ HttpHost host = new HttpHost("localhost", this.server.getPort());
+
+ try {
+ if (!conn.isOpen()) {
+ Socket socket = new Socket(host.getHostName(), host.getPort());
+ conn.bind(socket, this.client.getParams());
+ }
+
+ BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+ post.setEntity(null);
+
+ this.client = new HttpClient(new ImmutableHttpProcessor(
+ new HttpRequestInterceptor[] {
+ new RequestTargetHost(),
+ new RequestConnControl(),
+ new RequestUserAgent(),
+ new RequestExpectContinue() }));
+
+ HttpResponse response = this.client.execute(post, host, conn);
+ assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode());
+ } finally {
+ conn.close();
+ this.server.shutdown();
+ }
+ }
+
+ public void testHttpPostIdentity() throws Exception {
+ this.server.registerHandler("*", new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+ ByteArrayEntity outgoing = new ByteArrayEntity(data);
+ response.setEntity(outgoing);
+ } else {
+ StringEntity outgoing = new StringEntity("No content");
+ response.setEntity(outgoing);
+ }
+ }
+
+ });
+
+ this.server.start();
+
+ DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
+ HttpHost host = new HttpHost("localhost", this.server.getPort());
+
+ try {
+ if (!conn.isOpen()) {
+ Socket socket = new Socket(host.getHostName(), host.getPort());
+ conn.bind(socket, this.client.getParams());
+ }
+
+ BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/");
+ post.setEntity(null);
+
+ this.client = new HttpClient(new ImmutableHttpProcessor(
+ new HttpRequestInterceptor[] {
+ new HttpRequestInterceptor() {
+
+ public void process(
+ final HttpRequest request,
+ final HttpContext context) throws HttpException, IOException {
+ request.addHeader(HTTP.TRANSFER_ENCODING, "identity");
+ }
+
+ },
+ new RequestTargetHost(),
+ new RequestConnControl(),
+ new RequestUserAgent(),
+ new RequestExpectContinue() }));
+
+ HttpResponse response = this.client.execute(post, host, conn);
+ assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusLine().getStatusCode());
+ } finally {
+ conn.close();
+ this.server.shutdown();
+ }
+ }
+
}