2016-11-18 5 views
0

Ich habe einige Remote-REST-API über HTTP2 ausgeführt. Es läuft durch SSL mit Zertifikat. Ziel ist das Senden und Empfangen von Daten über HTTP2 mit SSL-Zertifikat über Proxy.HTTP2-Anfragen über PROXY, Ruby

Es gibt http-2 & net-http2 Edelsteine, die Anfragen mit HTTP2 senden können. Aber was ist mit Proxy? In einer standardmäßigen Net :: HTTP-Bibliothek gibt es eine untergeordnete Klasse, Net :: HTTP :: Proxy, die das Verhalten der Net :: HTTP-Klasse der Eltern dupliziert, mit der Ausnahme, dass Anfragen über Proxy-Server gesendet werden. Aber HTTP2-Edelsteine ​​unterstützt es nicht.

Das schließt Idee kam ich ist etwas ähnlich wie Proxy Implementierung von http1.1 zu machen - „Host:“ zu schreiben und „Proxy-Authorization:“ Felder an die Buchse, dass Net-Http2 gem verwendet:

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

Aber es endet mit:

SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A 

ich könnte einige technische Kenntnisse vermissen dies zu erreichen, so dass jede Hilfe zu Forschungsrichtung bezogen wird geschätzt.

Antwort

0

Schließlich habe ich meine Idee mit einem Beispiel in net fertig/http-Standardbibliothek und erstellt eine Pull-Anforderung für Net-http2 gem: https://github.com/ostinelli/net-http2/pull/11

Die Idee war richtig, alles, was wir tun müssen, ist zu senden Proxy "CONNECT" Nachricht mit einem TCP-Socket, mit einer Adresse, die wir verbinden möchten, so dass es einen TCP-Tunnel erstellt, die alle Daten ein- und ausleiten, spielt keine Rolle, ob es HTTP1.1 oder HTTP2 oder irgendetwas anderes ist .

ist hier ein Teil des Codes:

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