2016-11-18 132 views
0

我有一些远程REST API通过HTTP2运行。它使用证书运行SSL。目标是通过代理通过HTTP2发送和接收带有SSL证书的数据。通过PROXY HTTP2请求,红宝石

还有http-2 & net-http2允许使用HTTP2发送请求的gem。但是代理呢?在标准的Net :: HTTP库中,除了通过代理服务器发送请求的事实外,还有一个子类Net :: HTTP :: Proxy,它重复了父类的Net :: HTTP类的行为。但HTTP2宝石不支持它。

该关闭的想法,我想出了是让类似代理实现的http1.1东西 - 写“主持人:”和“代理授权:”字段插座,净-Http2宝石用途:

@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

毕竟,我完成了我的想法与目前在网/ HTTP标准库为例,产生的净-http2宝石拉入请求:https://github.com/ostinelli/net-http2/pull/11

的想法是正确的,我们所要做的就是送代理“连接”消息使用任何TCP套接字,我们想要连接的地址,所以它创建一个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