You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Jesse Glick (Jira)" <ji...@apache.org> on 2020/08/27 18:54:00 UTC

[jira] [Commented] (HTTPCLIENT-2113) Asynch client fails to set Host header during cross-site redirect

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-2113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17186054#comment-17186054 ] 

Jesse Glick commented on HTTPCLIENT-2113:
-----------------------------------------

Curiously, using

{code}
CloseableHttpAsyncClient c = HttpAsyncClients.custom().addRequestInterceptorLast(new RequestTargetHost()).build();
{code}

seems to force the client to pass the {{Host}} header after redirects, but now the _second_ request (rather than the third) fails with a 400, which I cannot reproduce with {{curl}}.

> Asynch client fails to set Host header during cross-site redirect
> -----------------------------------------------------------------
>
>                 Key: HTTPCLIENT-2113
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2113
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpClient (async)
>    Affects Versions: 5.0.1
>            Reporter: Jesse Glick
>            Priority: Major
>
> Run this project:
> {code:xml}
> <?xml version="1.0" encoding="UTF-8"?>
> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>     <modelVersion>4.0.0</modelVersion>
>     <groupId>demo</groupId>
>     <artifactId>httpclientbug</artifactId>
>     <version>0-SNAPSHOT</version>
>     <packaging>jar</packaging>
>     <properties>
>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
>         <maven.compiler.source>8</maven.compiler.source>
>         <maven.compiler.target>8</maven.compiler.target>
>     </properties>
>     <dependencies>
>         <dependency>
>             <groupId>org.apache.httpcomponents.client5</groupId>
>             <artifactId>httpclient5</artifactId>
>             <version>5.0.1</version>
>         </dependency>
>         <dependency>
>             <groupId>org.slf4j</groupId>
>             <artifactId>slf4j-jdk14</artifactId>
>             <version>1.7.26</version>
>             <scope>runtime</scope>
>         </dependency>
>     </dependencies>
> </project>
> {code}
> {code}
> import java.util.logging.ConsoleHandler;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
> import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
> import org.apache.hc.client5.http.classic.methods.HttpGet;
> import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
> import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
> import org.apache.hc.client5.http.impl.classic.HttpClients;
> import org.apache.hc.core5.concurrent.FutureCallback;
> public class Main {
>     public static void main(String[] args) throws Exception {
>         Logger l = Logger.getLogger("org.apache.hc.client5.http.headers");
>         l.setLevel(Level.ALL);
>         ConsoleHandler h = new ConsoleHandler();
>         h.setLevel(Level.ALL);
>         l.addHandler(h);
>         String url = "https://updates.jenkins.io/download/plugins/checkmarx/2020.3.3/checkmarx.hpi";
>         System.err.println("classic: " + HttpClients.createDefault().execute(new HttpGet(url)).getCode());
>         CloseableHttpAsyncClient c = HttpAsyncClients.createDefault();
>         c.start();
>         System.err.println("asynch: " + c.execute(SimpleHttpRequests.get(url), new FutureCallback<SimpleHttpResponse>() {
>             @Override
>             public void completed(SimpleHttpResponse result) {}
>             @Override
>             public void failed(Exception x) {
>                 x.printStackTrace();
>             }
>             @Override
>             public void cancelled() {}
>         }).get().getCode());
>     }
> }
> {code}
> You will see that the synch client processes the two redirects (first to {{get.jenkins.io}} then to some mirror such as {{ftp.yz.yamagata-u.ac.jp}}) and successfully returns a 200 code. But the asynch client gets a 400 code after the second redirect, I believe because it is neglecting to send a {{Host}} header upon redirects (which apparently {{get.jenkins.io}} tolerates but the mirrors do not).
> I had difficulty following the control flow in the code here. {{AsyncRedirectExec}} and {{RequestTargetHost}} are involved; in a debugger I could confirm that {{RequestTargetHost}} is called for all three requests in synch mode, but only for the original request in asynch mode. I suspect the issue is related to the fact that {{HttpAsyncClientBuilder}} treats {{RequestTargetHost}} specially as part of a {{DefaultHttpProcessor}} rather than being included in the {{HttpProcessorBuilder}}; for example, {{User-Agent}} from {{RequestUserAgent}} _is_ sent on all requests.
> {{TestRedirectExec.testCrossSiteRedirect}} seems like the most applicable test case but I could not follow what it was doing or where to verify concrete things like headers being set on requests.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org