2016-11-18 101 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