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 2005/05/04 19:12:52 UTC
svn commit: r168148 - in /jakarta/httpclient/trunk/http-common/src:
examples/org/apache/http/examples/ java/org/apache/http/impl/
java/org/apache/http/interceptor/ java/org/apache/http/params/
Author: olegk
Date: Wed May 4 10:12:50 2005
New Revision: 168148
URL: http://svn.apache.org/viewcvs?rev=168148&view=rev
Log:
Fixed broken 'expect-continue' client-side code
Added:
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java (with props)
Modified:
jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java
Modified: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java (original)
+++ jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java Wed May 4 10:12:50 2005
@@ -40,6 +40,7 @@
import org.apache.http.impl.HttpGetRequest;
import org.apache.http.interceptor.RequestConnControl;
import org.apache.http.interceptor.RequestContent;
+import org.apache.http.interceptor.RequestExpectContinue;
import org.apache.http.interceptor.RequestTargetHost;
import org.apache.http.interceptor.RequestUserAgent;
import org.apache.http.params.HttpParams;
@@ -70,6 +71,7 @@
// Recommended request interceptors
httpexecutor.setRequestInterceptor(new RequestConnControl());
httpexecutor.setRequestInterceptor(new RequestUserAgent());
+ httpexecutor.setRequestInterceptor(new RequestExpectContinue());
HttpHost host = new HttpHost("www.yahoo.com");
HttpClientConnection conn = new DefaultHttpClientConnection(host);
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java Wed May 4 10:12:50 2005
@@ -67,7 +67,7 @@
private static final String EXPECT_DIRECTIVE = "Expect";
private static final String EXPECT_CONTINUE = "100-Continue";
- private static final int CONTINUE_WAIT_MS = 3000;
+ private static final int WAIT_FOR_CONTINUE_MS = 10000;
private final HttpHost targethost;
private final InetAddress localAddress;
@@ -166,16 +166,16 @@
if (expect != null && EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue())) {
// flush the headers
this.datatransmitter.flush();
- if (this.datareceiver.isDataAvailable(CONTINUE_WAIT_MS)) {
- HttpResponse response = receiveResponse(request);
+ if (this.datareceiver.isDataAvailable(WAIT_FOR_CONTINUE_MS)) {
+ HttpResponse response = readResponse(request.getParams());
int status = response.getStatusLine().getStatusCode();
- if (status > 100) {
- return response;
- } else {
+ if (status < 200) {
if (status != HttpStatus.SC_CONTINUE) {
throw new ProtocolException("Unexpected response: " +
response.getStatusLine());
}
+ } else {
+ return response;
}
}
}
@@ -206,13 +206,30 @@
// reset the data receiver
this.datareceiver.reset(params);
- HttpMutableResponse response = processResponseStatusLine(params);
- processResponseHeaders(response);
- processResponseBody(response);
+ for (;;) {
+ HttpResponse response = readResponse(params);
+ int statuscode = response.getStatusLine().getStatusCode();
+ if (statuscode >= 200) {
+ return response;
+ }
+ if (isWarnEnabled()) {
+ warn("Unexpected provisional response: " + response.getStatusLine());
+ }
+ }
+ }
+
+ protected HttpResponse readResponse(final HttpParams params)
+ throws HttpException, IOException {
+ this.datareceiver.reset(params);
+ HttpMutableResponse response = readResponseStatusLine(params);
+ readResponseHeaders(response);
+ if (canResponseHaveBody(response)) {
+ readResponseBody(response);
+ }
return response;
}
-
- protected HttpMutableResponse processResponseStatusLine(final HttpParams params)
+
+ protected HttpMutableResponse readResponseStatusLine(final HttpParams params)
throws HttpException, IOException {
//read out the HTTP status string
int maxGarbageLines = params.getIntParameter(
@@ -247,7 +264,7 @@
return HttpResponseFactory.newHttpResponse(statusline);
}
- protected void processResponseHeaders(
+ protected void readResponseHeaders(
final HttpMutableResponse response) throws HttpException, IOException {
Header[] headers = HeadersParser.processHeaders(this.datareceiver);
for (int i = 0; i < headers.length; i++) {
@@ -266,26 +283,17 @@
&& status != HttpStatus.SC_NOT_MODIFIED;
}
- protected void processResponseBody(
+ protected void readResponseBody(
final HttpMutableResponse response) throws HttpException, IOException {
EntityGenerator entitygen = new DefaultEntityGenerator();
HttpMutableEntity entity = entitygen.generate(this.datareceiver, response);
- if (canResponseHaveBody(response)) {
- // if there is a result - ALWAYS wrap it in an observer which will
- // close the underlying stream as soon as it is consumed, and notify
- // the watcher that the stream has been consumed.
- InputStream instream = entity.getContent();
- instream = new AutoCloseInputStream(
- instream, new DefaultResponseConsumedWatcher(this, response));
- entity.setContent(instream);
- } else {
- if (entity.isChunked() || entity.getContentLength() > 0) {
- if (isWarnEnabled()) {
- warn("This response may not have a response body");
- }
- }
- entity.setContent(null);
- }
+ // if there is a result - ALWAYS wrap it in an observer which will
+ // close the underlying stream as soon as it is consumed, and notify
+ // the watcher that the stream has been consumed.
+ InputStream instream = entity.getContent();
+ instream = new AutoCloseInputStream(
+ instream, new DefaultResponseConsumedWatcher(this, response));
+ entity.setContent(instream);
response.setEntity(entity);
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java Wed May 4 10:12:50 2005
@@ -173,7 +173,7 @@
String line = response.getStatusLine().toString();
this.datatransmitter.writeLine(line);
if (isWirelogEnabled()) {
- wirelog(">> " + line + "[\\r][\\n]");
+ wirelog("<< " + line + "[\\r][\\n]");
}
}
@@ -184,12 +184,12 @@
String line = headers[i].toString();
this.datatransmitter.writeLine(line);
if (isWirelogEnabled()) {
- wirelog(">> " + line + "[\\r][\\n]");
+ wirelog("<< " + line + "[\\r][\\n]");
}
}
this.datatransmitter.writeLine("");
if (isWirelogEnabled()) {
- wirelog(">> [\\r][\\n]");
+ wirelog("<< [\\r][\\n]");
}
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java Wed May 4 10:12:50 2005
@@ -94,7 +94,8 @@
if (hasDataInBuffer()) {
return true;
} else {
- return this.selector.select(timeout) > 0;
+ this.selector.select(timeout);
+ return !this.selector.selectedKeys().isEmpty();
}
}
Added: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java?rev=168148&view=auto
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java (added)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java Wed May 4 10:12:50 2005
@@ -0,0 +1,79 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.interceptor;
+
+import java.io.IOException;
+
+import org.apache.http.Header;
+import org.apache.http.HttpContext;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpMutableRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpVersion;
+import org.apache.http.params.HttpProtocolParams;
+
+/**
+ * <p>
+ * </p>
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @version $Revision$
+ *
+ * @since 4.0
+ */
+public class RequestExpectContinue implements HttpRequestInterceptor {
+
+ private static final String EXPECT_DIRECTIVE = "Expect";
+
+ public RequestExpectContinue() {
+ super();
+ }
+
+ public void process(final HttpMutableRequest request, final HttpContext context)
+ throws HttpException, IOException {
+ if (request == null) {
+ throw new IllegalArgumentException("HTTP request may not be null");
+ }
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+ // Do not send the expect header if request body is known to be empty
+ if (entity != null && entity.getContentLength() != 0) {
+ HttpProtocolParams params = new HttpProtocolParams(request.getParams());
+ HttpVersion ver = request.getRequestLine().getHttpVersion();
+ if (params.useExpectContinue() && ver.greaterEquals(HttpVersion.HTTP_1_1)) {
+ request.addHeader(new Header(EXPECT_DIRECTIVE, "100-Continue", true));
+ }
+ }
+ }
+ }
+
+}
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java Wed May 4 10:12:50 2005
@@ -133,6 +133,34 @@
*/
public static final String STRICT_TRANSFER_ENCODING = "http.protocol.strict-transfer-encoding";
+ /**
+ * <p>
+ * Activates 'Expect: 100-Continue' handshake for the
+ * {@link org.apache.commons.httpclient.methods.ExpectContinueMethod
+ * entity enclosing methods}. The purpose of the 'Expect: 100-Continue'
+ * handshake to allow a client that is sending a request message with
+ * a request body to determine if the origin server is willing to
+ * accept the request (based on the request headers) before the client
+ * sends the request body.
+ * </p>
+ *
+ * <p>
+ * The use of the 'Expect: 100-continue' handshake can result in
+ * noticable peformance improvement for entity enclosing requests
+ * (such as POST and PUT) that require the target server's
+ * authentication.
+ * </p>
+ *
+ * <p>
+ * 'Expect: 100-continue' handshake should be used with
+ * caution, as it may cause problems with HTTP servers and
+ * proxies that do not support HTTP/1.1 protocol.
+ * </p>
+ *
+ * This parameter expects a value of type {@link Boolean}.
+ */
+ public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue";
+
private final HttpParams params;
/**
@@ -303,4 +331,11 @@
return setParameter(USER_AGENT, useragent);
}
+ public boolean useExpectContinue() {
+ return getBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+ }
+
+ public HttpProtocolParams setUseExpectContinue(boolean b) {
+ return setBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, b);
+ }
}