所以,我正在管理一个公司超文本传输协议服务器,并被要求升级服务器以支持使用超文本传输协议2的代理请求
这是测试客户端。我正在jdk 17中使用HttpClient。下面是测试用例。
public static void main(String[] args)throws Exception
{
HttpClient client=HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("192.168.1.2",1000))) //proxy to 192.168.1.2:1000
.version(HttpClient.Version.HTTP_2) //use http 2
.build();
//request to 192.168.1.2:2000
HttpRequest request=HttpRequest.newBuilder(URI.create("http://192.168.1.2:2000/Test.txt"))
.build();
HttpResponse response=client.send(request,BodyHandlers.ofString());
System.out.println("Status code: " + response.statusCode());
System.out.println("Headers: " + response.headers().map());
System.out.println("Body: " + response.body());
}
我的服务器运行在超文本传输协议2上,我没有得到任何响应。在调试我的服务器上收到的数据包时看起来像这样:
GET http://192.168.1.2:2000/Test.txt HTTP/1.1
Content-Length: 0
Host: 192.168.1.2:2000
User-Agent: Java-http-client/17.0.2
这既不是超文本传输协议2格式,也没有我的服务器被设计为解析的任何升级标头,在不使用代理的情况下通常看起来像这样:
GET /Test.txt HTTP/1.1
Connection: Upgrade, HTTP2-Settings
Content-Length: 0
Host: 192.168.1.2:2000
HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
Upgrade: h2c
User-Agent: Java-http-client/17.0.2
我的服务器被设计来解析这个请求,因为它是包含客户端http 2设置的升级请求。
所以,当我收到这样的请求时,我的问题是:
GET http://192.168.1.2:2000/Test.txt HTTP/1.1
Content-Length: 0
Host: 192.168.1.2:2000
User-Agent: Java-http-client/17.0.2
>
有没有办法让HttpClient包含升级头,这样我就可以以HTTP 2格式回复?
编辑
为了调试响应,我创建了一个运行在端口1000上的简单TCP服务器,并通过它进行代理。我只需打印在这个代理上接收到的字节,就可以得到完全相同的输出
//Test Proxy server running on port 1000. No parsing data simply print and close for debugging purposes
public static void main(String[] args)throws Exception
{
try(ServerSocket server=new ServerSocket(1000))
{
try(Socket client=server.accept())
{
try(InputStream input=client.getInputStream())
{
byte[] data=new byte[8196];
int length=input.read(data);
System.out.println(new String(data,0,length));
}
}
}
}
显然,OpenJDK的HttpClient只能向代理发送HTTP/1.1请求。
即使您指定了HttpClient。版本HTTP_2
,因为存在代理,OpenJDK的HttpClient
会忽略您指定的版本,将请求格式化为HTTP/1.1并将其发送到代理。
OpenJDK的HttpClient
代理功能非常有限(例如,您无法轻松使用安全协议与代理通信),因此您可能需要查看不同的HTTP客户端。
[免责声明,我是Jetty团队的一员。]
Jetty的HttpClient支持更灵活的代理配置,因此您可以指定代理所使用的协议(以及是否安全)。
请注意,您需要代理协作才能获得所需的内容,因为连接
是一个逐跳标头,因此它仅在单跳上有效,即从客户端到代理。
代理可以合法地将客户端的HTTP/1.1升级请求获取到HTTP/2,但随后使用HTTP/1.1与服务器对话,从服务器获取HTTP/1.1响应并生成101 Upgrad
响应,然后是获得的HTTP/2响应,将服务器的HTTP/1.1响应转换为HTTP/2:
client proxy server
| ---- h1+upgrade ---> | |
| | -- h1 request --> |
| | <-- h1 response -- |
| <-- h1 101 upgrade -- |
| <--- h2c response --- |
支持h2c
的代理可以执行您想要的操作:
client proxy server
| ---- h1+upgradeA ---> | |
| | --- h1+upgradeB ---> |
| | <-- h1 101 upgrade -- |
| | <--- h2c response ---- |
| <-- h1 101 upgrade -- |
| <--- h2c response ---- |
然而,请注意,upgradeA
可能与upgradeB
不同,这正是因为Connection
和Upgrade
都是逐跳的头,并且代理可能具有与客户端不同的HTTP/2配置(因此也发送不同的HTTP2设置
头)。
如果客户端和代理之间的通信是明文的,您必须事先知道代理是否支持h2c
,否则客户端将默认为HTTP/1.1(就像OpenJDK的HttpClient
一样)。相比之下,Jetty的HttpClient
可以配置您想要使用的协议来与代理对话。
或者,您必须通过TLS使用安全通信,以便客户端和代理可以协商他们想要说话的协议(例如h2
)。
代理也是如此:如果与服务器的通信是明文的(您的案例),那么代理必须事先知道服务器支持h2c
,因此您需要使用该信息配置代理,否则代理可能会默认为HTTP/1.1。
显然,代理必须同时支持HTTP/1.1和HTTP/2。
如果您正在实现代理,将Connection
(和其他逐跳标头)复制到服务器在技术上是错误的,但它可能在受限、更简单的情况下工作。请参阅RFC 7230的本节,该节指定代理应如何删除逐跳标头。
FTR,该测试表明Jetty(客户端和服务器)可以支持客户端、代理和服务器之间的任何协议组合(HTTP/1.1和HTTP/2、明文和安全)。
需要通过代理执行REST请求。有几个HTTP代理服务器可用,受基本身份验证的保护。使用Java16。 访问HTTP资源时完全工作的请求示例:
问题内容: 我正在尝试使用HttpsUrlConnection类将请求发送到服务器。服务器存在证书问题,因此我设置了一个可信任所有内容的TrustManager以及同样宽松的主机名验证程序。当我直接发出请求时,此管理器工作正常,但是当我通过代理发送请求时,似乎根本没有使用过。 我这样设置代理设置: 默认SSLSocketFactory的TrustManager的设置如下: 如果运行以下代码,则最终
我正在用python创建一个基于BaseHTTPServer的代理服务器。它所做的是创建到squid代理的连接,识别浏览器请求(GET、CONNECT、POST等),并向其添加代理授权标头,然后将此请求转发给squid代理。 问题是,据我所知,当我发送连接请求时,我应该将所有相应的流量中继到squid代理。但是,正如我在wireshark中看到的,squid代理没有回复握手的“Client Hel
我有一个WPF应用程序,需要从远程API检索配置数据。该API已经过测试,并且工作正常,返回我认为是正确的格式。我已经为响应等创建了一个数据类型,但是当我到达通过HttpClient获取响应的行时,它不会向API发送任何请求。 数据类型:- 我已经在API上运行了日志,我们没有看到请求,如果我们使用相同的代码模型调用另一个API控制器来调用Uri2(https://example.com/API/
我的一个EC2实例上有一个graphql服务器正在运行。我也有AWS appsync运行,但目前它只与几个Lambda集成。 我想将我的Appsync连接到graphql服务器,这样Appsync将作为特定查询/变化的代理。 因此,从客户端来看,它将如下所示: 客户端将一个查询发送到APPESNC,让我们假设它看起来像这样: Appsync已经定义了一个查询,它被配置为在graphql服务器上代理
我如何发送此信息: 到API: 使用cURL,我目前一直在使用: 其中我得到了结果(NGrok): GET/testDir/curlPost。php HTTP/1.1 接受:text/html、Application/xhtml xml、image/jxr、/ 接受语言:en-GB 用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537