HttpClient HTTP Wagon 的高级配置

您可以使用给定协议的默认 wagon 实现,也可以基于每个协议选择替代 wagon provider。如需更多信息,请参阅Wagon 供应商指南[3]。默认 wagon http(s) 是基于Apache Http Client 4.5的 HttpClient 。HTTP 连接池可防止为每个请求重新打开与同一服务器的新连接。此池功能可通过一些参数 [4] 进行配置。默认旅行车带有一些默认配置:

  • http(s) 连接池:默认为 20。
  • readTimeout:默认为 1,800,000 毫秒(约 30 分钟)(见Read time out下文)
  • 仅使用 PUT 进行默认抢先式身份验证(GET 不再使用默认抢先式身份验证)

介绍

基于 HttpClient 的 HTTP wagon 提供了对用于访问基于 HTTP 的 Maven 存储库的配置的更多控制。对于初学者,您可以对解析工件时使用的 HTTP 标头进行细粒度控制。此外,您还可以配置多种参数来控制 HttpClient 本身的行为。最重要的是,您可以控制所有请求或单个请求类型(GET、HEAD 和 PUT)的这些标头和参数。

基础

没有任何特殊配置,Maven 的 HTTP wagon 在管理工件时使用一些默认的 HTTP 标头和客户端参数。默认标题是:

Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip

此外,使用 HTTP wagon 发出的 PUT 请求使用以下 HttpClient 参数:

http.protocol.expect-continue=true

从 HttpClient 文档 [2] 中,此参数提供以下功能:

Activates 'Expect: 100-Continue' handshake for the entity enclosing methods. 
The 'Expect: 100-Continue' handshake allows 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.

The use of the 'Expect: 100-continue' handshake can result in noticeable performance 
improvement for entity enclosing requests (such as POST and PUT) that require 
the target server's authentication.

'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.

如果没有此设置,需要身份验证的 PUT 请求会在服务器发出身份验证质询之前将其整个有效负载传输到服务器。为了完成 PUT 请求,客户端必须使用 HTTP 标头中指定的正确凭据重新发送有效负载。这导致带宽使用量增加一倍,传输每个工件的时间增加一倍。

避免这种双重传输的另一个选项是所谓的抢先式身份验证,它涉及将身份验证标头与原始 PUT 请求一起发送。但是,这种方法存在一些潜在问题。一方面,如果您有一个未使用的<server>条目指定了无效的用户名/密码组合,401 Unauthorized即使服务器实际上并不要求对请求进行任何身份验证,某些服务器也可能会响应。此外,无论服务器是否提出质询,在每个请求中盲目地发送身份验证凭据可能会导致安全漏洞,因为服务器可能不会为不需要身份验证的路径提供安全凭据。

我们将在下面的另一个示例中讨论抢先式身份验证。

配置 GET、HEAD、PUT 或以上所有

在下面的所有示例中,重要的是要了解您可以为对给定服务器发出的所有请求或仅一种方法配置 HTTP 设置。要为服务器配置所有方法,请使用文件的以下部分settings.xml

<settings>
  [...]
  <servers>
    <server>
      <id>the-server</id>
      <configuration>
        <httpConfiguration>
          <all>
            [ Your configuration here. ]
          </all>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

另一方面,如果您可以使用大多数请求的默认配置 - 例如 HEAD 和 GET 请求,它们分别用于检查文件是否存在并检索文件 - 也许您只需要配置 PUT 方法:

<settings>
  [...]
  <servers>
    <server>
      <id>the-server</id>
      <configuration>
        <httpConfiguration>
          <put>
            [ Your configuration here. ]
          </put>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

为清楚起见,其他两个部分<get>用于 GET 请求和<head>HEAD 请求。我知道这将很难记住...

控制您的 HTTP 标头

正如您在上面可能已经注意到的,默认的 HTTP 标头确实有可能导致问题。例如,一些网站将下载 GZipped 文件的编码设置为gzip,尽管 HTTP 请求本身并未使用 GZip 压缩发送。如果客户端使用Accept-Encoding: gzipheader,这可能会导致客户端在传输过程中自己解压GZipped文件,并将解压后的文件以原始文件名写入本地磁盘。至少可以说这可能会产生误导,并且会占用本地计算机上过多的磁盘空间。

要关闭此默认行为,只需禁用默认标头即可。然后,重新指定您仍然感兴趣的其他标头,如下所示:

<settings>
  [...]
  <servers>
    <server>
      <id>openssl</id>
      <configuration>
        <httpConfiguration>
          <put>
            <useDefaultHeaders>false</useDefaultHeaders>
            <headers>
              <property>
                <name>Cache-control</name>
                <value>no-cache</value>
              </property>
              <property>
                <name>Cache-store</name>
                <value>no-store</value>
              </property>
              <property>
                <name>Pragma</name>
                <value>no-cache</value>
              </property>
              <property>
                <name>Expires</name>
                <value>0</value>
              </property>
              <property>
                <name>Accept-Encoding</name>
                <value>*</value>
              </property>
            </headers>
          </put>
        </httpConfiguration>
      </configuration>
    </server>
    [...]
  </servers>
  [...]
</settings>

微调 HttpClient 参数

除了 HTTP 请求参数的强大功能之外,HttpClient 还提供了许多其他配置选项。在大多数情况下,您不需要自定义这些。但万一你这样做了,Maven 提供了为 HttpClient 指定你自己的细粒度配置的访问权限。同样,您可以为每个方法(HEAD、GET 或 PUT)或与给定服务器交互的所有方法指定这些参数自定义。有关受支持参数的完整列表,请参阅下面参考资料部分中的链接 [2]。

非字符串参数值

HttpClient 的许多配置参数都有简单的字符串值;然而,这也有重要的例外。在某些情况下,您可能需要指定布尔值、整数或长整数值。在其他情况下,您甚至可能需要指定字符串值的集合。您可以使用简单的格式化语法指定这些,如下所示:

  1. 布尔值: %b,<value>
  2. 整数: %i,<value>
  3. 长:( %l,<value>是的,那是“L”,而不是“1”)
  4. 双倍的: %d,<value>
  5. 字符串集合: %c,<value1>,<value2>,<value3>,...,也可以指定为:
    %c,
    <value1>,
    <value2>,
    <value3>,
    ...

您可能已经注意到,这种语法类似于sprintf()许多语言中的函数使用的格式和数据策略。选择语法时考虑到了这种相似性,使其使用起来更直观。

示例:使用抢先式身份验证

使用上述语法,您可以使用布尔 HttpClient 参数为 PUT 请求配置抢占式身份验证http.authentication.preemptive,如下所示:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpConfiguration>
          <put>
            <params>
              <property>
                <name>http.authentication.preemptive</name>
                <value>%b,true</value>
              </property>
            </params>
          </put>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

另一种选择是这样写:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpConfiguration>
          <put>
            <usePreemptive>true</usePreemptive>
          </put>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

示例:取消外部身份验证系统的身份验证范围限制

默认情况下,Maven Wagon 将提供的凭据限制为主机:端口组合范围,忽略任何其他目标服务器。当目标服务器将身份验证委托给外部系统时,您需要有意解除该范围限制。配置您的服务器元素以将身份验证传递给挑战客户端的所有目标服务器。+---+ settings servers server id my-server /id configuration basicAuthScope host ANY /host port ANY /port !-- 甚至 443 强制使用 TLS -- /basicAuthScope httpConfiguration all params 属性 http.protocol.cookie-policy /name 标准/value /property /params /all /httpConfiguration /configuration /server /servers /settings +---+

忽略 Cookie

和上面的例子一样,告诉 HttpClient 忽略所有请求方法的 cookie 是配置http.protocol.cookie-policy参数的简单问题(它使用常规字符串值,因此不需要特殊语法):

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpConfiguration>
          <all>
            <params>
              <param>
                <name>http.protocol.cookie-policy</name>
                <value>ignore</value>
              </param>
            </params>
          </all>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

上面的配置在存储库使用 cookie 的情况下很有用——比如在应用服务器中经常错误地打开或保留的会话 cookie——以及 HTTP 重定向。Path在这些情况下,应用服务器发出的 cookie 使用的 cookie与客户端访问服务器时使用的 cookie 不一致的可能性更大。如果你有这个问题,并且知道你不需要使用这个会话cookie,你可以通过上面的配置忽略来自这个服务器的cookie。

支持通用货车配置标准

应该注意的是,除了这种新的细粒度方法之外,仍然支持以前在 HttpClient 驱动的 HTTP wagon 中可用的配置选项。其中包括 HTTP 标头和连接超时的配置。让我们简要地检查其中的每一个:

HTTP 标头

在所有 HTTP Wagon 实现中,您可以像这样添加自己的 HTTP 标头:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Foo</name>
            <value>Bar</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
</settings>

重要的是要了解上述方法不允许您关闭所有默认 HTTP 标头。它也不允许您基于每个方法指定标头。但是,此配置在轻量级和基于 httpclient 的 Wagon 实现中仍然可用。

连接超时

所有扩展AbstractWagon该类的 wagon 实现,包括 SCP、HTTP、FTP 等的实现,都允许配置连接超时,以允许用户告诉 Maven 在放弃没有响应的连接之前等待多长时间。此选项保留在基于 HttpClient 的 wagon 中,但此 wagon 还提供了细粒度的替代配置,可以允许您为给定服务器指定每个方法的超时。旧的配置选项 - 仍然受支持 - 如下所示:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <timeout>6000</timeout> <!-- milliseconds -->
      </configuration>
    </server>
  </servers>
</settings>

...而新的配置选项看起来更像这样:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpConfiguration>
          <put>
            <connectionTimeout>10000</connectionTimeout> <!-- milliseconds -->
          </put>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

如果您只需要每个服务器的超时配置,您仍然可以选择使用旧<timeout>参数。如果您需要根据 HTTP 方法分离超时首选项,您可以使用上面直接指定的多一个。

阅读超时

对于 Wagon 2.0 和 Apache Maven 3.0.4,默认超时时间为 30 分钟。如果要更改此值,可以在设置中添加以下设置:

<settings>
  <servers>
    <server>
      <id>my-server</id>
      <configuration>
        <httpConfiguration>
          <put>
            <readTimeout>120000</readTimeout> <!-- milliseconds -->
          </put>
        </httpConfiguration>
      </configuration>
    </server>
  </servers>
</settings>

资源

  1. HttpClient 网站
  2. HttpClient 首选项架构和配置指南
  3. 货车供应商指南
  4. Wagon Http