Skip to content

Commit ad47529

Browse files
committed
Added SimpleHTTPProxyServer by TCPServer
1 parent 489a1e9 commit ad47529

File tree

2 files changed

+95
-55
lines changed

2 files changed

+95
-55
lines changed

test/open-uri/test_proxy.rb

Lines changed: 20 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,10 @@
22
require 'test/unit'
33
require 'open-uri'
44
require_relative 'utils'
5-
require 'webrick'
6-
require 'webrick/httpproxy'
7-
begin
8-
require 'zlib'
9-
rescue LoadError
10-
end
115

126
class TestOpenURIProxy < Test::Unit::TestCase
137
include TestOpenURIUtils
148

15-
NullLog = Object.new
16-
def NullLog.<<(arg)
17-
#puts arg if / INFO / !~ arg
18-
end
19-
209
def with_env(h)
2110
begin
2211
old = {}
@@ -41,18 +30,12 @@ def teardown
4130
def test_proxy
4231
with_http {|srv, url|
4332
proxy_log = StringIO.new(''.dup)
44-
proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN)
4533
proxy_auth_log = ''.dup
46-
proxy = WEBrick::HTTPProxyServer.new({
47-
:ServerType => Thread,
48-
:Logger => proxy_logger,
49-
:AccessLog => [[NullLog, ""]],
50-
:ProxyAuthProc => lambda {|req, res|
34+
proxy_host = '127.0.0.1'
35+
proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res|
5136
proxy_auth_log << req.request_line
52-
},
53-
:BindAddress => '127.0.0.1',
54-
:Port => 0})
55-
_, proxy_port, _, proxy_host = proxy.listeners[0].addr
37+
}, proxy_log)
38+
proxy_port = proxy.instance_variable_get(:@server).addr[1]
5639
proxy_url = "http://#{proxy_host}:#{proxy_port}/"
5740
begin
5841
proxy_thread = proxy.start
@@ -95,21 +78,15 @@ def test_proxy
9578
def test_proxy_http_basic_authentication_failure
9679
with_http {|srv, url|
9780
proxy_log = StringIO.new(''.dup)
98-
proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN)
9981
proxy_auth_log = ''.dup
100-
proxy = WEBrick::HTTPProxyServer.new({
101-
:ServerType => Thread,
102-
:Logger => proxy_logger,
103-
:AccessLog => [[NullLog, ""]],
104-
:ProxyAuthProc => lambda {|req, res|
82+
proxy_host = '127.0.0.1'
83+
proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res|
10584
proxy_auth_log << req.request_line
10685
if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}"
107-
raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
86+
raise ProxyAuthenticationRequired
10887
end
109-
},
110-
:BindAddress => '127.0.0.1',
111-
:Port => 0})
112-
_, proxy_port, _, proxy_host = proxy.listeners[0].addr
88+
}, proxy_log)
89+
proxy_port = proxy.instance_variable_get(:@server).addr[1]
11390
proxy_url = "http://#{proxy_host}:#{proxy_port}/"
11491
begin
11592
th = proxy.start
@@ -121,28 +98,22 @@ def test_proxy_http_basic_authentication_failure
12198
proxy.shutdown
12299
th.join
123100
end
124-
assert_match(/ERROR WEBrick::HTTPStatus::ProxyAuthenticationRequired/, proxy_log.string)
101+
assert_match(/ERROR ProxyAuthenticationRequired/, proxy_log.string)
125102
}
126103
end
127104

128105
def test_proxy_http_basic_authentication_success
129106
with_http {|srv, url|
130107
proxy_log = StringIO.new(''.dup)
131-
proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN)
132108
proxy_auth_log = ''.dup
133-
proxy = WEBrick::HTTPProxyServer.new({
134-
:ServerType => Thread,
135-
:Logger => proxy_logger,
136-
:AccessLog => [[NullLog, ""]],
137-
:ProxyAuthProc => lambda {|req, res|
109+
proxy_host = '127.0.0.1'
110+
proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res|
138111
proxy_auth_log << req.request_line
139112
if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}"
140-
raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
113+
raise ProxyAuthenticationRequired
141114
end
142-
},
143-
:BindAddress => '127.0.0.1',
144-
:Port => 0})
145-
_, proxy_port, _, proxy_host = proxy.listeners[0].addr
115+
}, proxy_log)
116+
proxy_port = proxy.instance_variable_get(:@server).addr[1]
146117
proxy_url = "http://#{proxy_host}:#{proxy_port}/"
147118
begin
148119
th = proxy.start
@@ -169,21 +140,15 @@ def test_proxy_http_basic_authentication_success
169140
def test_authenticated_proxy_http_basic_authentication_success
170141
with_http {|srv, url|
171142
proxy_log = StringIO.new(''.dup)
172-
proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN)
173143
proxy_auth_log = ''.dup
174-
proxy = WEBrick::HTTPProxyServer.new({
175-
:ServerType => Thread,
176-
:Logger => proxy_logger,
177-
:AccessLog => [[NullLog, ""]],
178-
:ProxyAuthProc => lambda {|req, res|
144+
proxy_host = '127.0.0.1'
145+
proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res|
179146
proxy_auth_log << req.request_line
180147
if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}"
181-
raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
148+
raise ProxyAuthenticationRequired
182149
end
183-
},
184-
:BindAddress => '127.0.0.1',
185-
:Port => 0})
186-
_, proxy_port, _, proxy_host = proxy.listeners[0].addr
150+
}, proxy_log)
151+
proxy_port = proxy.instance_variable_get(:@server).addr[1]
187152
proxy_url = "http://user:pass@#{proxy_host}:#{proxy_port}/"
188153
begin
189154
th = proxy.start

test/open-uri/utils.rb

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,83 @@ def status_message(code)
148148
end
149149
end
150150

151+
class SimpleHTTPProxyServer
152+
def initialize(host, port, auth_proc = nil, log)
153+
@server = TCPServer.new(host, port)
154+
@auth_proc = auth_proc
155+
@log = log
156+
end
157+
158+
def start
159+
@thread = Thread.new do
160+
loop do
161+
client = @server.accept
162+
request_line = client.gets
163+
headers = {}
164+
while (line = client.gets) && (line != "\r\n")
165+
key, value = line.chomp.split(/:\s*/, 2)
166+
headers[key] = value
167+
end
168+
next unless request_line
169+
170+
method, path, _ = request_line.split(' ')
171+
handle_request(client, method, path, request_line, headers)
172+
end
173+
end
174+
end
175+
176+
def shutdown
177+
@thread.kill
178+
@server.close
179+
end
180+
181+
private
182+
183+
def handle_request(client, method, path, request_line, headers)
184+
if @auth_proc
185+
req = Request.new(method, path, request_line, headers)
186+
res = Struct.new(:body, :status).new("", 200)
187+
@auth_proc.call(req, res)
188+
if res.status != 200
189+
client.print "HTTP/1.1 #{res.status}\r\nContent-Type: text/plain\r\n\r\n#{res.body}"
190+
return
191+
end
192+
end
193+
194+
uri = URI(path)
195+
proxy_request(uri, client)
196+
rescue TestOpenURIProxy::ProxyAuthenticationRequired
197+
@log << "ERROR ProxyAuthenticationRequired"
198+
client.print "HTTP/1.1 407 Proxy Authentication Required\r\nContent-Length: 0\r\n\r\n"
199+
ensure
200+
client.close
201+
end
202+
203+
def proxy_request(uri, client)
204+
Net::HTTP.start(uri.host, uri.port) do |http|
205+
response = http.get(uri.path)
206+
client.print "HTTP/1.1 #{response.code}\r\nContent-Type: #{response.content_type}\r\n\r\n#{response.body}"
207+
end
208+
end
209+
210+
class Request
211+
attr_reader :method, :path, :request_line, :headers
212+
def initialize(method, path, request_line, headers)
213+
@method = method
214+
@path = path
215+
@request_line = request_line
216+
@headers = headers
217+
end
218+
219+
def [](key)
220+
@headers[key]
221+
end
222+
end
223+
end
224+
151225
module TestOpenURIUtils
152226
class Unauthorized < StandardError; end
227+
class ProxyAuthenticationRequired < StandardError; end
153228

154229
def with_http(log_tester=lambda {|log| assert_equal([], log) })
155230
log = []

0 commit comments

Comments
 (0)