Skip to content

Instantly share code, notes, and snippets.

@igrigorik
Forked from taf2/em-proxy-http.rb
Created January 25, 2011 03:35
Show Gist options
  • Save igrigorik/794464 to your computer and use it in GitHub Desktop.
Save igrigorik/794464 to your computer and use it in GitHub Desktop.
require 'em-proxy'
require 'http/parser'
require 'uuid'
# > ruby em-proxy-http.rb
# > curl --proxy localhost:9889 www.google.com
host = "0.0.0.0"
port = 9889
puts "listening on #{host}:#{port}..."
Proxy.start(:host => host, :port => port) do |conn|
@p = Http::Parser.new
@p.on_headers_complete = proc do |h|
session = UUID.generate
puts "New session: #{session} (#{h.inspect})"
host, port = h['Host'].split(':')
conn.server session, :host => host, :port => (port || 80)
conn.relay_to_servers @buffer
@buffer.clear
end
@buffer = ''
conn.on_connect do |data,b|
puts [:on_connect, data, b].inspect
end
conn.on_data do |data|
@buffer << data
@p << data
data
end
conn.on_response do |backend, resp|
puts [:on_response, backend, resp].inspect
resp
end
conn.on_finish do |backend, name|
puts [:on_finish, name].inspect
end
end
@taf2
Copy link

taf2 commented Feb 1, 2011

It is actually keeping a persistent - I'm sure that is the issue.

@igrigorik
Copy link
Author

Hmm, so if its interfacing with it as an "HTTP proxy", then in theory it should send the absolute URI as part of the initial header on each request. The trick is to detect the request boundaries and start/close new backends on per request basis. In other words, this is getting more complicated..

Might actually be easier to instead of opening a TCP backend to actually open an http request (em-http) and pipe data back through the callbacks.

@steeve
Copy link

steeve commented Feb 9, 2011

any updates on this ?

@taf2
Copy link

taf2 commented Feb 9, 2011

Nothing yet from me - been pulled into other items, will hopefully get back to this soon...

@steeve
Copy link

steeve commented Feb 10, 2011

hey, thanks anyway :D

@siuying
Copy link

siuying commented Jan 4, 2012

The proxy above do not handle HTTP/1.1 persistence connection.

To workaround this, i disabled the persistence connection on both client and server side (by adding Connection: close). Not a good example for implementing proxy, but it work fine as a proxy that work on modern browsers and sites. Check my fork here: https://gist.github.com/1560703

@igrigorik
Copy link
Author

If you want an http proxy with persistent connections, etc, take a look at goliath + mongo logging example in there. What we're doing here is basically reimplementing all of the connection management that Goliath already provides. :-)

@siuying
Copy link

siuying commented Jan 4, 2012

@igrigorik thanks! this seems what i'm looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment