Module: NetHttp2::Socket
- Defined in:
- lib/net-http2/socket.rb
Class Method Summary collapse
- .create(uri, options) ⇒ Object
- .proxy_tcp_socket(uri, options) ⇒ Object
- .ssl_socket(uri, options) ⇒ Object
- .tcp_socket(uri, options) ⇒ Object
Class Method Details
.create(uri, options) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/net-http2/socket.rb', line 5 def self.create(uri, ) return ssl_socket(uri, ) if [:ssl] return proxy_tcp_socket(uri, ) if [:proxy_addr] tcp_socket(uri, ) end |
.proxy_tcp_socket(uri, options) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/net-http2/socket.rb', line 57 def self.proxy_tcp_socket(uri, ) proxy_addr = [:proxy_addr] proxy_port = [:proxy_port] proxy_user = [:proxy_user] proxy_pass = [:proxy_pass] proxy_uri = URI.parse("#{proxy_addr}:#{proxy_port}") proxy_socket = tcp_socket(proxy_uri, ) # 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 |
.ssl_socket(uri, options) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/net-http2/socket.rb', line 12 def self.ssl_socket(uri, ) tcp = if [:proxy_addr] proxy_tcp_socket(uri, ) else tcp_socket(uri, ) end socket = OpenSSL::SSL::SSLSocket.new(tcp, [:ssl_context]) socket.sync_close = true socket.hostname = [:proxy_addr] || uri.host socket.connect socket end |
.tcp_socket(uri, options) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/net-http2/socket.rb', line 28 def self.tcp_socket(uri, ) family = ::Socket::AF_INET address = ::Socket.getaddrinfo(uri.host, nil, family).first[3] sockaddr = ::Socket.pack_sockaddr_in(uri.port, address) socket = ::Socket.new(family, ::Socket::SOCK_STREAM, 0) socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) begin socket.connect_nonblock(sockaddr) rescue IO::WaitWritable if IO.select(nil, [socket], nil, [:connect_timeout]) begin socket.connect_nonblock(sockaddr) rescue Errno::EISCONN # socket is connected rescue socket.close raise end else socket.close raise Errno::ETIMEDOUT end end socket end |