webrick_httpreverseproxyserver 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,14 @@
1
+ = HTTP Reverse proxy server
2
+
3
+ This library is not meant for production use. It is based on a snippet on
4
+ RubyForge and was packaged as gem to make it easily available.
5
+
6
+ Source: http://rubyforge.org/snippet/detail.php?type=snippet&id=117
7
+
8
+
9
+ You may use this class, to programmatically set up a quick and simple reverse
10
+ proxy. I found it useful to implement advanced inspection of an HTTP
11
+ communication between an uncontrolled client and server.
12
+
13
+
14
+ See WEBrick::HTTPReverseProxyServer for more information.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require 'rake'
3
+ require 'rake/rdoctask'
4
+
5
+ $: << File.expand_path('../lib', __FILE__)
6
+ require 'webrick/httpreverseproxyserver/version'
7
+
8
+ desc 'Generate documentation for the webrick_httpreverseproxyserver gem.'
9
+ Rake::RDocTask.new(:doc) do |doc|
10
+ doc.rdoc_dir = 'doc'
11
+ doc.title = 'WEBRick::HTTPReverseProxyServer'
12
+ doc.options << '--line-numbers' << '--inline-source'
13
+ doc.rdoc_files.include('README.rdoc')
14
+ doc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ desc 'Build gem'
18
+ task :build do
19
+ sh 'gem build webrick_httpreverseproxyserver.gemspec'
20
+ end
21
+
22
+ desc "Install gem locally"
23
+ task :install => :build do
24
+ sh "gem install webrick_httpreverseproxyserver-#{WEBrick::HTTPReverseProxyServer::VERSION}.gem"
25
+ end
26
+
27
+ desc 'Release gem'
28
+ task :release => :build do
29
+ sh "gem push webrick_httpreverseproxyserver-#{WEBrick::HTTPReverseProxyServer::VERSION}.gem"
30
+ end
@@ -0,0 +1,162 @@
1
+ # encoding: utf-8
2
+
3
+ require 'webrick'
4
+ require 'net/http'
5
+
6
+ module WEBrick
7
+ # Proxy rule to configure WEBrick::HTTPReverseProxyServer
8
+ class ProxyRule < Struct.new(:pattern, :host, :port, :replacement)
9
+ end
10
+
11
+ # == Use case
12
+ #
13
+ # You have several services running as different users for security purposes
14
+ # (they might even be chrooted). In production we use apache but for testing
15
+ # I prefer to use webrick because I find it more flexible for unit testing.
16
+ #
17
+ #
18
+ # == Configuration
19
+ #
20
+ # The proxy mapping is modelled on the ProxyPass directive of apache. For
21
+ # example:
22
+ #
23
+ # original URL proxies private URL
24
+ # ------------------------ ==> --------------------------
25
+ # /marmalade/index.html localhost:8081/index.html
26
+ # /apps/vegemite?id=123 localhost:8082/apps/someservlet?id=123
27
+ #
28
+ # Its not designed to be mod_rewrite (eg. query_string cannot be
29
+ # transformed), but you can specify proxy rules that match a fragment of the
30
+ # original URL and replace it with something else while also sending the new
31
+ # URL to the proxied host and port. So the rules in that example are
32
+ # specified thus:
33
+ #
34
+ # serverConfig = {
35
+ # :Port => 80,
36
+ # :ProxyRules => [
37
+ # WEBrick::ProxyRule.new('^/marmalade/', 'localhost', 8081, '/'),
38
+ # WEBrick::ProxyRule.new('vegemite', 'localhost', 8082, 'someservlet')
39
+ # ]
40
+ # }
41
+ # server = WEBrick::HTTPReverseProxyServer.new(serverConfig)
42
+ #
43
+ # ProxyRules is an array so the order is important - the first match is used!
44
+ # If no matches are found then the URL is handled by the local web server
45
+ # normally.
46
+ #
47
+ #
48
+ # == Running a server
49
+ #
50
+ # You may start a server, just like any WEBrick server.
51
+ #
52
+ # To get started using RubyGems, use the following example:
53
+ #
54
+ # require 'rubygems'
55
+ # require 'webrick/httpreverseproxyserver'
56
+ #
57
+ # # create a configuration and a server instance
58
+ # serverConfig = {
59
+ # :Port => 8080,
60
+ # :ProxyRules => [WEBrick::ProxyRule.new('/', 'www.example.com', 80, '/')]
61
+ # }
62
+ # server = WEBrick::HTTPReverseProxyServer.new(serverConfig)
63
+ #
64
+ # # catch ^C to quit cleanly
65
+ # trap("INT") { server.shutdown }
66
+ #
67
+ # # start request-response-loop
68
+ # server.start
69
+ #
70
+ #
71
+ # == Advanced inspection
72
+ #
73
+ # In order to better analyse an HTTP stream, you may easily subclass
74
+ # HTTPReverseProxyServer to add advanced request/response inspection.
75
+ #
76
+ # The following example implements basic Cookie logging:
77
+ #
78
+ # class CookieLoggingProxy < WEBrick::HTTPReverseProxyServer
79
+ # def service(request, response)
80
+ # super.tap do
81
+ # puts
82
+ # puts request.request_line
83
+ # print_cookie_headers request.header
84
+ # puts response.status_line
85
+ # print_cookie_headers response.header
86
+ # end
87
+ # end
88
+ #
89
+ # def print_cookie_headers(headers)
90
+ # headers.each do |key, val|
91
+ # puts "#{key}: #{val}" if key =~ /cookie/i
92
+ # end
93
+ # end
94
+ # end
95
+ class HTTPReverseProxyServer < HTTPServer
96
+ def service(request, response)
97
+ rule = first_matching_proxy_rule(request)
98
+ if rule.nil?
99
+ super(request, response)
100
+ else
101
+ service_proxy(request, response, rule)
102
+ end
103
+ end
104
+
105
+ protected
106
+ # find the *first* matching pattern in the proxy map
107
+ def first_matching_proxy_rule(request)
108
+ matching_rul = @config[:ProxyRules].detect { |rule|
109
+ re = Regexp.new(rule.pattern)
110
+ m = re.match(request.path)
111
+ not m.nil?
112
+ }
113
+ return(matching_rule)
114
+ end
115
+
116
+ def service_proxy(request, response, rule)
117
+ host, port, path = map_to_proxyURI(request, rule)
118
+ # convert WEBrick header (values wrapped in an array) into Net::HTTP
119
+ # header (simple values)
120
+ header = {}
121
+ request.header.keys { |key| header[key] = request.header[key][0] }
122
+ header['x-forwarded-for'] = request.peeraddr[2] # the name of the requesting host
123
+ # send the new request to the private server (hacked from WEBrick::HTTPProxyServer)
124
+ response = nil
125
+ begin
126
+ http = Net::HTTP.new(host, port)
127
+ http.start {
128
+ case request.request_method
129
+ when "GET" then response = http.get(path, header)
130
+ when "POST" then response = http.post(path, request.body || "", header)
131
+ when "HEAD" then response = http.head(path, header)
132
+ else
133
+ raise HTTPStatus::MethodNotAllowed,
134
+ "unsupported method `#{request.request_method}'."
135
+ end
136
+ }
137
+ rescue => err
138
+ logger.debug("#{err.class}: #{err.message}")
139
+ raise HTTPStatus::ServiceUnavailable, err.message
140
+ end
141
+ response['connection'] = "close"
142
+
143
+ # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
144
+ response.status = response.code.to_i
145
+ response.each { |key, val| response[key] = val }
146
+ response.body = response.body
147
+
148
+ # Process contents
149
+ if handler = @config[:ProxyContentHandler]
150
+ handler.call(request, response)
151
+ end
152
+ end
153
+
154
+ def map_to_proxyURI(request, rule)
155
+ path = (request.path).sub(%r!#{rule.pattern}!, rule.replacement)
156
+ path += '?' + request.query_string if request.query_string
157
+ return([rule.host, rule.port, path])
158
+ end
159
+ end
160
+ end
161
+
162
+ require 'webrick/httpreverseproxyserver/version'
@@ -0,0 +1,5 @@
1
+ module WEBrick
2
+ class HTTPReverseProxyServer
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webrick_httpreverseproxyserver
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Gregor Schmidt
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-22 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Implements a simple reverse HTTP proxy - useful for advanced configuration or inspection of reverse proxies in development.
22
+ email: g.schmidt@finn.de
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/webrick/httpreverseproxyserver/version.rb
31
+ - lib/webrick/httpreverseproxyserver.rb
32
+ - Rakefile
33
+ - README.rdoc
34
+ has_rdoc: true
35
+ homepage: http://github.com/finnlabs/webrick_httpreverseproxyserver
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project: "[none]"
60
+ rubygems_version: 1.3.6
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Implements a simple reverse HTTP proxy server
64
+ test_files: []
65
+