class Proxi::HTTPHostSocketFactory

### 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`.

Public Class Methods

new(host_mapping) click to toggle source

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'
)
# File lib/proxi/socket_factory.rb, line 59
def initialize(host_mapping)
  @host_mapping = host_mapping
end

Public Instance Methods

call() click to toggle source
# 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) click to toggle source

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.

# File lib/proxi/socket_factory.rb, line 69
def data_in(connection, data)
  @first_packet ||= data
end
headers() click to toggle source
# 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