Class: Proxi::HTTPHostSocketFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/proxi/socket_factory.rb

Overview

### HTTPHostSocketFactory

Dispatches HTTP traffic to multiple hosts, based on the HTTP ‘Host:` header.

HTTPHostSocketFactory expects to receive data events from the connection, so make sure you subscribe it to connection events. (see ‘Proxi.http_proxy` for an example).

To use this effectively, configure your local ‘/etc/hosts` so the relevant domains point to localhost. That way the proxy will be able to intercept them.

This class is single use only! Create a new instance for each ‘Proxi::Connection`.

Instance Method Summary collapse

Constructor Details

#initialize(host_mapping) ⇒ HTTPHostSocketFactory

Initialize a HTTPHostSocketFactory

‘host_mapping` - A Hash mapping hostnames to IP addresses, and, optionally, ports

For example:

HTTPHostSocketFactory.new(
  'foo.example.com' => '10.10.10.1:8080',
  'bar.example.com' => '10.10.10.2:8080'
)


59
60
61
# File 'lib/proxi/socket_factory.rb', line 59

def initialize(host_mapping)
  @host_mapping = host_mapping
end

Instance Method Details

#callObject



73
74
75
76
77
# File 'lib/proxi/socket_factory.rb', line 73

def call
  host, port = @host_to_ip.fetch(headers["host"]).split(':')
  port ||= 80
  TCPSocket.new(host, port.to_i)
end

#data_in(connection, data) ⇒ Object

This is an event listener, it will be broadcast by the ‘Connection` whenever it gets new request data. We capture the first packet, assuming it contains the HTTP headers.

‘Connection` will only request an outgoing socket from us (call `#call`) after it received the initial request payload.



69
70
71
# File 'lib/proxi/socket_factory.rb', line 69

def data_in(connection, data)
  @first_packet ||= data
end

#headersObject



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/proxi/socket_factory.rb', line 79

def headers
  Hash[
    @first_packet
    .sub(/\r\n\r\n.*/m, '')
    .each_line
    .drop(1) # GET / HTTP/1.1
    .map do |line|
      k,v = line.split(':', 2)
      [k.downcase, v.strip]
    end
  ]
end