【问题标题】:Apache Http Client - Stop Removing Double Slashes from URLApache Http 客户端 - 停止从 URL 中删除双斜杠
【发布时间】:2019-02-08 11:08:22
【问题描述】:

我正在使用 Apache HTTP Components Client 4.5.7 请求包含双斜杠的 URL。当我查看电线日志时,我看到双斜线被“固定”为只有一个斜线。不幸的是,这对我来说不是可取的行为,因为它会导致请求失败。

背景:我正在从 Thumbor(图像大小调整服务器)请求调整大小的图像。 Thumbor URL 基本上如下所示:

此 URL 将导致 thumbor 下载 http://host.com/image.jpg 并调整其大小以适应 200x200 像素。

代码如下所示:

HttpGet httpUriRequest = new HttpGet("http://thumbors-server/usafe/200x200/http://host.com/image.jpg");
CLIENT.execute(httpUriRequest, responseHandler); 

httpclient 发送到服务器的内容。然而这是:

DEBUG o.a.h.headers     http-outgoing-1 >> GET /unsafe/300x300/http:/host.com/image1.jpg HTTP/1.1 
DEBUG o.a.h.headers     http-outgoing-1 >> Host: localhost:4002 
DEBUG o.a.h.headers     http-outgoing-1 >> Connection: Keep-Alive 
DEBUG o.a.h.headers     http-outgoing-1 >> User-Agent: Apache-HttpClient/4.5.7 (Java/11.0.1) 
DEBUG o.a.h.headers     http-outgoing-1 >> Accept-Encoding: gzip,deflate 

请注意http://host.com 已替换为 http:/host.com(注意缺少的第二个 /)。这将导致请求失败。

如何阻止 http 客户端“修复”我传递给它的 url?

【问题讨论】:

    标签: java apache-httpcomponents


    【解决方案1】:

    对于我遇到的类似情况,最好的解决方案是使用 URLEncoder.encode 对嵌入的 URL 进行 url 编码。

    在你的例子中,

    new HttpGet("http://thumbors-server/usafe/200x200/" + URLEncoder.encode("http://host.com/image.jpg", "UTF-8"))
    

    【讨论】:

      【解决方案2】:

      我今天在 http-client v4.5.13 中遇到了这个问题。我正在点击/测试的服务器无法正确处理 URI,因此 URLEncoding 不起作用。我需要在我的代码中使用一种解决方法(不使用原始套接字)。

      经过调试发现可以在设置客户端配置时使用RequestConfig.custom().setNormlizeUri()方法禁用URI规范化。

      Javadoc link to the RequestConfig builder

      例子:

      requestConfig = RequestConfig.custom()
                          .setConnectTimeout(connectionTimeoutMS)
                          .setConnectionRequestTimeout(connectionTimeoutMS)
                          .setSocketTimeout(connectionTimeoutMS)
                          .setNormalizeUri(normalizeUri)
                          .build();
      

      【讨论】:

        【解决方案3】:

        问题出在URIUtils.rewriteURI() 这段代码在哪里:

        final StringBuilder buf = new StringBuilder(path.length());
        boolean foundSlash = false;
        for (int i = 0; i < path.length(); i++) {
            final char ch = path.charAt(i);
            if (ch != '/' || !foundSlash) {
                buf.append(ch);
            }
            foundSlash = ch == '/';
        }
        uribuilder.setPath(buf.toString());
        

        所以 uri 路径中的双斜杠总是用一个斜杠替换。您可以使用另一个 http 客户端,例如 OkHttp,它不会进行这种标准化。

        【讨论】:

        • 有谁知道他们为什么这样做?有什么好处?
        猜你喜欢
        • 2016-08-07
        • 1970-01-01
        • 2018-08-14
        • 2019-09-03
        • 1970-01-01
        • 2011-06-25
        • 1970-01-01
        • 2021-07-06
        • 2014-12-21
        相关资源
        最近更新 更多