Skip to content

Instantly share code, notes, and snippets.

@rhapsodyv
Created September 16, 2016 19:57
Show Gist options
  • Save rhapsodyv/509f43ba56329d42c4a498b80f5039da to your computer and use it in GitHub Desktop.
Save rhapsodyv/509f43ba56329d42c4a498b80f5039da to your computer and use it in GitHub Desktop.
send headers to proxy before ssl thing in ruby
require 'net/http'
require 'net/protocol'
# SUPPORT TO SEND HEADERS TO PROXY BEFORE THE SSL THING
module Net
class HTTP
# SUPPORT TO SEND HEADERS TO PROXY BEFORE THE SSL THING
attr_accessor :proxy_headers
def connect
if proxy? then
conn_address = proxy_address
conn_port = proxy_port
else
conn_address = address
conn_port = port
end
D "opening connection to #{conn_address}:#{conn_port}..."
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
}
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
D "opened"
if use_ssl?
ssl_parameters = Hash.new
iv_list = instance_variables
SSL_IVNAMES.each_with_index do |ivname, i|
if iv_list.include?(ivname) and
value = instance_variable_get(ivname)
ssl_parameters[SSL_ATTRIBUTES[i]] = value if value
end
end
@ssl_context = OpenSSL::SSL::SSLContext.new
@ssl_context.set_params(ssl_parameters)
D "starting SSL for #{conn_address}:#{conn_port}..."
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
s.sync_close = true
D "SSL established"
end
@socket = BufferedIO.new(s)
@socket.read_timeout = @read_timeout
@socket.continue_timeout = @continue_timeout
@socket.debug_output = @debug_output
if use_ssl?
begin
if proxy?
buf = "CONNECT #{@address}:#{@port} HTTP/#{HTTPVersion}\r\n"
# <<BEGIN>> SUPPORT TO SEND HEADERS TO PROXY BEFORE THE SSL THING
if proxy_headers
D 'Setting proxy headers'
proxy_headers.each do |k, v|
buf << "#{k}: #{v}\r\n"
end
end
# <<END>> SUPPORT TO SEND HEADERS TO PROXY BEFORE THE SSL THING
buf << "Host: #{@address}:#{@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"
@socket.write(buf)
HTTPResponse.read_new(@socket).value
end
if @ssl_session and
Time.now < @ssl_session.time + @ssl_session.timeout
s.session = @ssl_session if @ssl_session
end
# Server Name Indication (SNI) RFC 3546
s.hostname = @address if s.respond_to? :hostname=
Timeout.timeout(@open_timeout, Net::OpenTimeout) { s.connect }
if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
s.post_connection_check(@address)
end
@ssl_session = s.session
rescue => exception
D "Conn close because of connect error #{exception}"
@socket.close if @socket and not @socket.closed?
raise exception
end
end
on_connect
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment