我有一些通过HTTP2运行的远程REST API。它使用证书运行SSL。目标是通过HTTP2通过代理发送和接收带有SSL证书的数据。
有http-2& net-http2 gems,允许使用HTTP2发送请求。但是代理呢?在标准的Net :: HTTP库中,有一个子类Net :: HTTP :: Proxy,它复制了父的Net :: HTTP类的行为,除了它通过代理服务器发送请求的事实。但HTTP2宝石不支持它。
我提出的结论是制作类似于http1.1的代理实现的东西 - 将“Host:”和“Proxy-Authorization:”字段写入套接字,Net-Http2 gem使用:< / p>
@socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
@address, @port, HTTPVersion)
@socket.writeline "Host: #{@address}:#{@port}"
if proxy_user
credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
credential.delete!("\r\n")
@socket.writeline "Proxy-Authorization: Basic #{credential}"
end
@socket.writeline ''
但最终结果是:
SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
我可能会错过一些技术知识来实现这一点,所以我们非常感谢任何与研究方向相关的帮助。
答案 0 :(得分:0)
毕竟,我用net / http标准库中的示例完成了我的想法,并为Net-http2 gem创建了一个拉取请求:https://github.com/ostinelli/net-http2/pull/11
这个想法是正确的,我们所要做的就是使用任何tcp套接字发送代理“CONNECT”消息,其中包含我们想要连接的地址,因此它会创建一个绕过所有数据的TCP隧道,无论是HTTP1.1还是HTTP2,或其他任何内容都无关紧要。
以下是代码的一部分:
def self.proxy_tcp_socket(uri, options)
proxy_addr = options[:proxy_addr]
proxy_port = options[:proxy_port]
proxy_user = options[:proxy_user]
proxy_pass = options[:proxy_pass]
proxy_uri = URI.parse("#{proxy_addr}:#{proxy_port}")
# create a regular TCP socket (with or w/o SSL, if needed)
proxy_socket = tcp_socket(proxy_uri, options)
# The majority of proxies do not explicitly support HTTP/2 protocol,
# while they successfully create a TCP tunnel
# which can pass through binary data of HTTP/2 connection.
# So we’ll keep HTTP/1.1
http_version = '1.1'
buf = "CONNECT #{uri.host}:#{uri.port} HTTP/#{http_version}\r\n"
buf << "Host: #{uri.host}:#{uri.port}\r\n"
if proxy_user
credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
credential.delete!("\r\n")
buf << "Proxy-Authorization: Basic #{credential}\r\n"
end
buf << "\r\n"
proxy_socket.write(buf)
validate_proxy_response!(proxy_socket)
proxy_socket
end