Permalink
Browse files

debug mode off by default

  • Loading branch information...
1 parent 6d6d6ba commit 0b469e1db8167577bb73594c77710cf00dd80c73 @igrigorik committed Sep 26, 2009
Showing with 166 additions and 149 deletions.
  1. +11 −2 README.rdoc
  2. +2 −2 em-proxy.gemspec
  3. +1 −1 examples/port_forward.rb
  4. +46 −43 lib/em-proxy/backend.rb
  5. +85 −82 lib/em-proxy/connection.rb
  6. +21 −19 lib/em-proxy/proxy.rb
View
@@ -1,11 +1,13 @@
= EM-Proxy
-EventMachine Proxy DSL:
+EventMachine Proxy DSL for writing high-performance transparent / intercepting proxies in Ruby.
+
- Slides from RailsConf 2009: http://bit.ly/D7oWB
+- GoGaRuCo notes & Slides: http://www.igvita.com/2009/04/20/ruby-proxies-for-scale-and-monitoring/
== Simple port forwarding proxy
- Proxy.start(:host => "0.0.0.0", :port => 80) do |conn|
+ Proxy.start(:host => "0.0.0.0", :port => 80, :debug => true) do |conn|
conn.server :srv, :host => "127.0.0.1", :port => 81
# modify / process request stream
@@ -20,3 +22,10 @@ EventMachine Proxy DSL:
resp
end
end
+
+For more examples see the /examples directory.
+ - SMTP Spam Filtering
+ - Duplicating traffic
+ - Selective forwarding
+ - Beanstalkd interceptor
+ - etc.
View
@@ -4,8 +4,8 @@ spec = Gem::Specification.new do |s|
s.date = '2009-09-19'
s.summary = 'EventMachine Proxy DSL'
s.description = s.summary
- s.email = 'mark@imbriaco.com'
- s.homepage = "http://github.com/imbriaco/em-proxy"
+ s.email = 'ilya@igvita.com'
+ s.homepage = "http://github.com/igrigorik/em-proxy"
s.has_rdoc = true
s.authors = ["Ilya Grigorik", "Mark Imbriaco"]
s.add_dependency('eventmachine', '>= 0.12.2')
View
@@ -1,6 +1,6 @@
require 'lib/em-proxy'
-Proxy.start(:host => "0.0.0.0", :port => 80) do |conn|
+Proxy.start(:host => "0.0.0.0", :port => 80, :debug => true) do |conn|
conn.server :srv, :host => "127.0.0.1", :port => 81
# modify / process request stream
View
@@ -1,43 +1,46 @@
-module EventMachine
- module ProxyServer
- class Backend < EventMachine::Connection
- attr_accessor :plexer, :data, :name, :debug
-
- def initialize(debug = false)
- @debug = debug
- @connected = EM::DefaultDeferrable.new
- @data = []
- end
-
- def connection_completed
- debug [@name, :conn_complete]
- @connected.succeed
- end
-
- def receive_data(data)
- debug [@name, data]
- @data.push data
- @plexer.relay_from_backend(@name, data)
- end
-
- # Buffer data until the connection to the backend server
- # is established and is ready for use
- def send(data)
- @connected.callback { send_data data }
- end
-
- # Notify upstream plexer that the backend server is done
- # processing the request
- def unbind
- debug [@name, :unbind]
- @plexer.unbind_backend(@name)
- end
-
- private
-
- def debug(*data)
- p data if @debug
- end
- end
- end
-end
+module EventMachine
+ module ProxyServer
+ class Backend < EventMachine::Connection
+ attr_accessor :plexer, :data, :name, :debug
+
+ def initialize(debug = false)
+ @debug = debug
+ @connected = EM::DefaultDeferrable.new
+ @data = []
+ end
+
+ def connection_completed
+ debug [@name, :conn_complete]
+ @connected.succeed
+ end
+
+ def receive_data(data)
+ debug [@name, data]
+ @data.push data
+ @plexer.relay_from_backend(@name, data)
+ end
+
+ # Buffer data until the connection to the backend server
+ # is established and is ready for use
+ def send(data)
+ @connected.callback { send_data data }
+ end
+
+ # Notify upstream plexer that the backend server is done
+ # processing the request
+ def unbind
+ debug [@name, :unbind]
+ @plexer.unbind_backend(@name)
+ end
+
+ private
+
+ def debug(*data)
+ return unless @debug
+ require 'pp'
+ pp data
+ puts
+ end
+ end
+ end
+end
View
@@ -1,82 +1,85 @@
-module EventMachine
- module ProxyServer
- class Connection < EventMachine::Connection
- attr_accessor :debug
-
- ##### Proxy Methods
- def on_data(&blk); @on_data = blk; end
- def on_response(&blk); @on_response = blk; end
- def on_finish(&blk); @on_finish = blk; end
-
- ##### EventMachine
- def initialize(options)
- @debug = options[:debug] || false
- @servers = {}
- end
-
- def receive_data(data)
- debug [:connection, data]
- processed = @on_data.call(data)
-
- if processed.is_a? Array
- data, servers = *processed
-
- # guard for "unbound" servers
- servers = servers.collect {|s| @servers[s]}.compact
- else
- data = processed
- servers ||= @servers.values.compact
- end
-
- servers.each do |s|
- s.send_data data unless data.nil?
- end
- end
-
- #
- # initialize connections to backend servers
- #
- def server(name, opts)
- srv = EventMachine::connect(opts[:host], opts[:port], EventMachine::ProxyServer::Backend, @debug) do |c|
- c.name = name
- c.plexer = self
- end
-
- @servers[name] = srv
- end
-
- #
- # relay data from backend server to client
- #
- def relay_from_backend(name, data)
- debug [:relay_from_backend, name, data]
-
- data = @on_response.call(name, data)
- send_data data unless data.nil?
- end
-
- def unbind
- # terminate any unfinished connections
- @servers.values.compact.each do |s|
- s.close_connection_after_writing
- end
-
- close_connection_after_writing
- @on_finish.call(:done) if @servers.values.compact.size.zero? if @on_finish
- end
-
- def unbind_backend(name)
- debug [:unbind_backend, name]
- @servers[name] = nil
- @on_finish.call(name) if @on_finish
- close_connection_after_writing if @servers.values.compact.size.zero?
- end
-
- private
-
- def debug(*data)
- p data if @debug
- end
- end
- end
-end
+module EventMachine
+ module ProxyServer
+ class Connection < EventMachine::Connection
+ attr_accessor :debug
+
+ ##### Proxy Methods
+ def on_data(&blk); @on_data = blk; end
+ def on_response(&blk); @on_response = blk; end
+ def on_finish(&blk); @on_finish = blk; end
+
+ ##### EventMachine
+ def initialize(options)
+ @debug = options[:debug] || false
+ @servers = {}
+ end
+
+ def receive_data(data)
+ debug [:connection, data]
+ processed = @on_data.call(data)
+
+ if processed.is_a? Array
+ data, servers = *processed
+
+ # guard for "unbound" servers
+ servers = servers.collect {|s| @servers[s]}.compact
+ else
+ data = processed
+ servers ||= @servers.values.compact
+ end
+
+ servers.each do |s|
+ s.send_data data unless data.nil?
+ end
+ end
+
+ #
+ # initialize connections to backend servers
+ #
+ def server(name, opts)
+ srv = EventMachine::connect(opts[:host], opts[:port], EventMachine::ProxyServer::Backend, @debug) do |c|
+ c.name = name
+ c.plexer = self
+ end
+
+ @servers[name] = srv
+ end
+
+ #
+ # relay data from backend server to client
+ #
+ def relay_from_backend(name, data)
+ debug [:relay_from_backend, name, data]
+
+ data = @on_response.call(name, data)
+ send_data data unless data.nil?
+ end
+
+ def unbind
+ # terminate any unfinished connections
+ @servers.values.compact.each do |s|
+ s.close_connection_after_writing
+ end
+
+ close_connection_after_writing
+ @on_finish.call(:done) if @servers.values.compact.size.zero? if @on_finish
+ end
+
+ def unbind_backend(name)
+ debug [:unbind_backend, name]
+ @servers[name] = nil
+ @on_finish.call(name) if @on_finish
+ close_connection_after_writing if @servers.values.compact.size.zero?
+ end
+
+ private
+
+ def debug(*data)
+ return unless @debug
+ require 'pp'
+ pp data
+ puts
+ end
+ end
+ end
+end
View
@@ -1,19 +1,21 @@
-class Proxy
- def self.start(options, &blk)
- EM.epoll
- EM.run do
- trap("TERM") { stop }
- trap("INT") { stop }
-
- EventMachine::start_server(options[:host], options[:port],
- EventMachine::ProxyServer::Connection, options) do |c|
- c.instance_eval(&blk)
- end
- end
- end
-
- def self.stop
- puts "Terminating ProxyServer"
- EventMachine.stop
- end
-end
+class Proxy
+
+ def self.start(options, &blk)
+ EM.epoll
+ EM.run do
+
+ trap("TERM") { stop }
+ trap("INT") { stop }
+
+ EventMachine::start_server(options[:host], options[:port],
+ EventMachine::ProxyServer::Connection, options) do |c|
+ c.instance_eval(&blk)
+ end
+ end
+ end
+
+ def self.stop
+ puts "Terminating ProxyServer"
+ EventMachine.stop
+ end
+end

0 comments on commit 0b469e1

Please sign in to comment.