class Goliath::Proxy::Connection

Attributes

restarting[RW]

Public Instance Methods

on_body(data) click to toggle source
# File lib/goliath/proxy/connection.rb, line 55
def on_body(data)
  @requests.first.parse(data)
end
on_headers_complete(h) click to toggle source
# File lib/goliath/proxy/connection.rb, line 15
def on_headers_complete(h)
  self.restarting = false
  if @parser.http_method == 'CONNECT'
    restart_with_ssl(@parser.request_url, h)
  else

    env = Goliath::Env.new
    env[SERVER_PORT] = port.to_s
    env[RACK_LOGGER] = logger
    env[OPTIONS]     = options
    env[STATUS]      = status
    env[CONFIG]      = config
    env[REMOTE_ADDR] = remote_address
    add_original_headers(env) if @ssl

    r = Goliath::Request.new(@app, self, env)
    r.parse_header(h, @parser) do
      env[ASYNC_HEADERS] = api.method(:on_headers) if api.respond_to?(:on_headers)
      env[ASYNC_BODY]    = api.method(:on_body)    if api.respond_to?(:on_body)
      env[ASYNC_CLOSE]   = api.method(:on_close)   if api.respond_to?(:on_close)
    end
    modify_headers_for_ssl(env) if @ssl
    @requests.push(r)

  end
end
on_message_complete() click to toggle source
# File lib/goliath/proxy/connection.rb, line 58
def on_message_complete
  self.restarting = false
  req = @requests.shift

  if @current.nil?
    @current = req
    @current.succeed
  else
    @pending.push(req)
  end

  req.process if !@parser.upgrade? && !req.env[:terminate_connection]

end
post_init() click to toggle source

This is intentionally completely overriden from the superclass’s version as it is required to re use the listeners on the parser for a second time around if an SSL address is being proxied

# File lib/goliath/proxy/connection.rb, line 9
def post_init
  @current = nil
  @requests = []
  @pending  = []
  @parser = Http::Parser.new(self)
end
receive_data(data) click to toggle source

Deliberately overriding this from the superclass as we want to prevent everything after parsing of the data IF this is restarting

# File lib/goliath/proxy/connection.rb, line 75
def receive_data(data)
  begin
    @parser << data
    return if restarting
    if @parser.upgrade?
      if !@current.env[UPGRADE_DATA]
        @current.env[UPGRADE_DATA] = @parser.upgrade_data
        @current.process
      else
        @current.parse(data)
      end
    end

  rescue HTTP::Parser::Error => e
    terminate_request(false)
  end
end
restart_with_ssl(url, headers) click to toggle source
# File lib/goliath/proxy/connection.rb, line 42
def restart_with_ssl(url, headers)
  @ssl = url
  self.restarting = true
  @parser.reset!  ##Prevent any further parsing of this as it is the CONNECT request which we dont do anything else with
  @parser = Http::Parser.new(self)
  @original_headers = headers.clone
  send_data("HTTP/1.0 200 Connection established\r\nProxy-agent: goliath-proxy/0.0.0\r\n\r\n")
  start_tls(
      private_key_file: File.expand_path('../../../../mitm.key', __FILE__),
      cert_chain_file: File.expand_path('../../../../mitm.crt', __FILE__)
  )
end

Private Instance Methods

add_original_headers(env) click to toggle source
# File lib/goliath/proxy/connection.rb, line 96
def add_original_headers(env)
  @original_headers.each do |name, value|
    converted_name = "HTTP_#{name.gsub(/-/, '_').upcase}"
    env[converted_name] = value
  end

end
modify_headers_for_ssl(env) click to toggle source
# File lib/goliath/proxy/connection.rb, line 104
def modify_headers_for_ssl(env)
  uri = URI.parse(@parser.request_url)
  url = "https://#{@ssl}#{[uri.path, uri.query].compact.join('?')}"
  env['REQUEST_URI'] = url
  env['HTTPS'] = 'on'
end