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/12/20 14:05:41 UTC
svn commit: r1424448 - in /httpcomponents/httpclient/trunk: ./
httpclient/src/main/java/org/apache/http/impl/client/
httpclient/src/main/java/org/apache/http/impl/client/execchain/
httpclient/src/test/java/org/apache/http/impl/client/integration/
Author: olegk
Date: Thu Dec 20 13:05:41 2012
New Revision: 1424448
URL: http://svn.apache.org/viewvc?rev=1424448&view=rev
Log:
HTTPCLIENT-1284: HttpClient incorrectly generates Host header when physical connection route differs from the host name specified in the request URI
Added:
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java (with props)
Modified:
httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/execchain/ProtocolExec.java
Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=1424448&r1=1424447&r2=1424448&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Thu Dec 20 13:05:41 2012
@@ -1,6 +1,10 @@
Changes in trunk
-------------------
+* [HTTPCLIENT-1284] HttpClient incorrectly generates Host header when physical connection
+ route differs from the host name specified in the request URI.
+ Contributed by Oleg Kalnichevski <olegk at apache.org>
+
* Kerberos and SPNego auth schemes use incorrect authorization header name when authenticating
with a proxy.
Contributed by Oleg Kalnichevski <olegk at apache.org>
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java?rev=1424448&r1=1424447&r2=1424448&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java Thu Dec 20 13:05:41 2012
@@ -456,19 +456,24 @@ public class DefaultRequestDirector impl
new BasicScheme(), new UsernamePasswordCredentials(userinfo));
}
+ if (virtualHost != null) {
+ target = virtualHost;
+ } else {
+ URI requestURI = wrapper.getURI();
+ if (requestURI.isAbsolute()) {
+ target = new HttpHost(
+ requestURI.getHost(), requestURI.getPort(), requestURI.getScheme());
+ }
+ }
+ if (target == null) {
+ target = route.getTargetHost();
+ }
+
// Reset headers on the request wrapper
wrapper.resetHeaders();
-
// Re-write request URI if needed
rewriteRequestURI(wrapper, route);
- // Use virtual host if set
- target = virtualHost;
-
- if (target == null) {
- target = route.getTargetHost();
- }
-
// Populate the execution context
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
context.setAttribute(ClientContext.ROUTE, route);
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/execchain/ProtocolExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/execchain/ProtocolExec.java?rev=1424448&r1=1424447&r2=1424448&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/execchain/ProtocolExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/execchain/ProtocolExec.java Thu Dec 20 13:05:41 2012
@@ -35,6 +35,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
import org.apache.http.ProtocolException;
import org.apache.http.annotation.Immutable;
import org.apache.http.auth.AuthState;
@@ -42,6 +43,7 @@ import org.apache.http.auth.UsernamePass
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpExecutionAware;
import org.apache.http.client.methods.HttpRequestWrapper;
+import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.client.protocol.HttpClientContext;
@@ -113,15 +115,16 @@ public class ProtocolExec implements Cli
Args.notNull(request, "HTTP request");
Args.notNull(context, "HTTP context");
- HttpHost target = route.getTargetHost();
-
// Get user info from the URI
AuthState targetAuthState = context.getTargetAuthState();
if (targetAuthState != null) {
- String userinfo = request.getURI().getUserInfo();
- if (userinfo != null) {
- targetAuthState.update(
- new BasicScheme(), new UsernamePasswordCredentials(userinfo));
+ URI uri = request.getURI();
+ if (uri != null) {
+ String userinfo = uri.getUserInfo();
+ if (userinfo != null) {
+ targetAuthState.update(
+ new BasicScheme(), new UsernamePasswordCredentials(userinfo));
+ }
}
}
@@ -132,7 +135,7 @@ public class ProtocolExec implements Cli
HttpHost virtualHost = (HttpHost) params.getParameter(ClientPNames.VIRTUAL_HOST);
// HTTPCLIENT-1092 - add the port if necessary
if (virtualHost != null && virtualHost.getPort() == -1) {
- int port = target.getPort();
+ int port = route.getTargetHost().getPort();
if (port != -1){
virtualHost = new HttpHost(virtualHost.getHostName(), port, virtualHost.getSchemeName());
}
@@ -141,8 +144,24 @@ public class ProtocolExec implements Cli
}
}
+ HttpHost target = null;
+ if (virtualHost != null) {
+ target = virtualHost;
+ } else {
+ HttpRequest original = request.getOriginal();
+ if (original instanceof HttpUriRequest) {
+ URI uri = ((HttpUriRequest) original).getURI();
+ if (uri.isAbsolute()) {
+ target = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
+ }
+ }
+ }
+ if (target == null) {
+ target = route.getTargetHost();
+ }
+
// Run request protocol interceptors
- context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, virtualHost != null ? virtualHost : target);
+ context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
context.setAttribute(ClientContext.ROUTE, route);
context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
Added: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java?rev=1424448&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java Thu Dec 20 13:05:41 2012
@@ -0,0 +1,153 @@
+/*
+ * ====================================================================
+ *
+ * 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.client.integration;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.localserver.LocalTestServer;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.util.EntityUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class tests cookie matching when using Virtual Host.
+ */
+public class TestCookieVirtualHost extends IntegrationTestBase {
+
+ @Before
+ public void setUp() throws Exception {
+ this.localServer = new LocalTestServer(null, null);
+ this.localServer.registerDefaultHandlers();
+ this.localServer.start();
+ }
+
+ @Test
+ public void testCookieMatchingWithVirtualHosts() throws Exception {
+ this.localServer.register("*", new HttpRequestHandler() {
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
+ switch (n) {
+ case 1:
+ // Assert Host is forwarded from URI
+ Assert.assertEquals("app.mydomain.fr", request
+ .getFirstHeader("Host").getValue());
+
+ response.setStatusLine(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_OK);
+ // Respond with Set-Cookie on virtual host domain. This
+ // should be valid.
+ response.addHeader(new BasicHeader("Set-Cookie",
+ "name1=value1; domain=mydomain.fr; path=/"));
+ break;
+
+ case 2:
+ // Assert Host is still forwarded from URI
+ Assert.assertEquals("app.mydomain.fr", request
+ .getFirstHeader("Host").getValue());
+
+ // We should get our cookie back.
+ Assert.assertNotNull("We must get a cookie header",
+ request.getFirstHeader("Cookie"));
+ response.setStatusLine(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_OK);
+ break;
+
+ case 3:
+ // Assert Host is forwarded from URI
+ Assert.assertEquals("app.mydomain.fr", request
+ .getFirstHeader("Host").getValue());
+
+ response.setStatusLine(HttpVersion.HTTP_1_1,
+ HttpStatus.SC_OK);
+ break;
+ }
+ }
+
+ });
+
+ this.httpclient = HttpClients.createDefault();
+
+ CookieStore cookieStore = new BasicCookieStore();
+ HttpContext context = new BasicHttpContext();
+ context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
+
+ // First request : retrieve a domain cookie from remote server.
+ URI uri = new URI("http://app.mydomain.fr");
+ HttpRequest httpRequest = new HttpGet(uri);
+ httpRequest.addHeader("X-Request", "1");
+ HttpResponse response1 = this.httpclient.execute(getServerHttp(),
+ httpRequest, context);
+ HttpEntity e1 = response1.getEntity();
+ EntityUtils.consume(e1);
+
+ // We should have one cookie set on domain.
+ List<Cookie> cookies = cookieStore.getCookies();
+ Assert.assertNotNull(cookies);
+ Assert.assertEquals(1, cookies.size());
+ Assert.assertEquals("name1", cookies.get(0).getName());
+
+ // Second request : send the cookie back.
+ uri = new URI("http://app.mydomain.fr");
+ httpRequest = new HttpGet(uri);
+ httpRequest.addHeader("X-Request", "2");
+ HttpResponse response2 = this.httpclient.execute(getServerHttp(),
+ httpRequest, context);
+ HttpEntity e2 = response2.getEntity();
+ EntityUtils.consume(e2);
+
+ // Third request : Host header
+ uri = new URI("http://app.mydomain.fr");
+ httpRequest = new HttpGet(uri);
+ httpRequest.addHeader("X-Request", "3");
+ HttpResponse response3 = this.httpclient.execute(getServerHttp(),
+ httpRequest, context);
+ HttpEntity e3 = response3.getEntity();
+ EntityUtils.consume(e3);
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.java
------------------------------------------------------------------------------
svn:mime-type = text/plain