From debcf108fab3904f6b39b7ee8612d1aa27c231a3 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 4 Jul 2024 17:42:35 +0900 Subject: [PATCH] [ruby/open-uri] Added SimpleHTTPProxyServer by TCPServer https://github.com/ruby/open-uri/commit/ad47529306 --- test/open-uri/test_proxy.rb | 75 ++++++++++--------------------------- test/open-uri/utils.rb | 75 +++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 55 deletions(-) diff --git a/test/open-uri/test_proxy.rb b/test/open-uri/test_proxy.rb index 4c651583f3..7fd1fd85c1 100644 --- a/test/open-uri/test_proxy.rb +++ b/test/open-uri/test_proxy.rb @@ -2,21 +2,10 @@ require 'test/unit' require 'open-uri' require_relative 'utils' -require 'webrick' -require 'webrick/httpproxy' -begin - require 'zlib' -rescue LoadError -end class TestOpenURIProxy < Test::Unit::TestCase include TestOpenURIUtils - NullLog = Object.new - def NullLog.<<(arg) - #puts arg if / INFO / !~ arg - end - def with_env(h) begin old = {} @@ -41,18 +30,12 @@ class TestOpenURIProxy < Test::Unit::TestCase def test_proxy with_http {|srv, url| proxy_log = StringIO.new(''.dup) - proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN) proxy_auth_log = ''.dup - proxy = WEBrick::HTTPProxyServer.new({ - :ServerType => Thread, - :Logger => proxy_logger, - :AccessLog => [[NullLog, ""]], - :ProxyAuthProc => lambda {|req, res| + proxy_host = '127.0.0.1' + proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res| proxy_auth_log << req.request_line - }, - :BindAddress => '127.0.0.1', - :Port => 0}) - _, proxy_port, _, proxy_host = proxy.listeners[0].addr + }, proxy_log) + proxy_port = proxy.instance_variable_get(:@server).addr[1] proxy_url = "http://#{proxy_host}:#{proxy_port}/" begin proxy_thread = proxy.start @@ -95,21 +78,15 @@ class TestOpenURIProxy < Test::Unit::TestCase def test_proxy_http_basic_authentication_failure with_http {|srv, url| proxy_log = StringIO.new(''.dup) - proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN) proxy_auth_log = ''.dup - proxy = WEBrick::HTTPProxyServer.new({ - :ServerType => Thread, - :Logger => proxy_logger, - :AccessLog => [[NullLog, ""]], - :ProxyAuthProc => lambda {|req, res| + proxy_host = '127.0.0.1' + proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res| proxy_auth_log << req.request_line if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}" - raise WEBrick::HTTPStatus::ProxyAuthenticationRequired + raise ProxyAuthenticationRequired end - }, - :BindAddress => '127.0.0.1', - :Port => 0}) - _, proxy_port, _, proxy_host = proxy.listeners[0].addr + }, proxy_log) + proxy_port = proxy.instance_variable_get(:@server).addr[1] proxy_url = "http://#{proxy_host}:#{proxy_port}/" begin th = proxy.start @@ -121,28 +98,22 @@ class TestOpenURIProxy < Test::Unit::TestCase proxy.shutdown th.join end - assert_match(/ERROR WEBrick::HTTPStatus::ProxyAuthenticationRequired/, proxy_log.string) + assert_match(/ERROR ProxyAuthenticationRequired/, proxy_log.string) } end def test_proxy_http_basic_authentication_success with_http {|srv, url| proxy_log = StringIO.new(''.dup) - proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN) proxy_auth_log = ''.dup - proxy = WEBrick::HTTPProxyServer.new({ - :ServerType => Thread, - :Logger => proxy_logger, - :AccessLog => [[NullLog, ""]], - :ProxyAuthProc => lambda {|req, res| + proxy_host = '127.0.0.1' + proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res| proxy_auth_log << req.request_line if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}" - raise WEBrick::HTTPStatus::ProxyAuthenticationRequired + raise ProxyAuthenticationRequired end - }, - :BindAddress => '127.0.0.1', - :Port => 0}) - _, proxy_port, _, proxy_host = proxy.listeners[0].addr + }, proxy_log) + proxy_port = proxy.instance_variable_get(:@server).addr[1] proxy_url = "http://#{proxy_host}:#{proxy_port}/" begin th = proxy.start @@ -169,21 +140,15 @@ class TestOpenURIProxy < Test::Unit::TestCase def test_authenticated_proxy_http_basic_authentication_success with_http {|srv, url| proxy_log = StringIO.new(''.dup) - proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN) proxy_auth_log = ''.dup - proxy = WEBrick::HTTPProxyServer.new({ - :ServerType => Thread, - :Logger => proxy_logger, - :AccessLog => [[NullLog, ""]], - :ProxyAuthProc => lambda {|req, res| + proxy_host = '127.0.0.1' + proxy = SimpleHTTPProxyServer.new(proxy_host, 0, lambda {|req, res| proxy_auth_log << req.request_line if req["Proxy-Authorization"] != "Basic #{['user:pass'].pack('m').chomp}" - raise WEBrick::HTTPStatus::ProxyAuthenticationRequired + raise ProxyAuthenticationRequired end - }, - :BindAddress => '127.0.0.1', - :Port => 0}) - _, proxy_port, _, proxy_host = proxy.listeners[0].addr + }, proxy_log) + proxy_port = proxy.instance_variable_get(:@server).addr[1] proxy_url = "http://user:pass@#{proxy_host}:#{proxy_port}/" begin th = proxy.start diff --git a/test/open-uri/utils.rb b/test/open-uri/utils.rb index 53bbc0afc3..3ae19598f0 100644 --- a/test/open-uri/utils.rb +++ b/test/open-uri/utils.rb @@ -148,8 +148,83 @@ class SimpleHTTPServer end end +class SimpleHTTPProxyServer + def initialize(host, port, auth_proc = nil, log) + @server = TCPServer.new(host, port) + @auth_proc = auth_proc + @log = log + end + + def start + @thread = Thread.new do + loop do + client = @server.accept + request_line = client.gets + headers = {} + while (line = client.gets) && (line != "\r\n") + key, value = line.chomp.split(/:\s*/, 2) + headers[key] = value + end + next unless request_line + + method, path, _ = request_line.split(' ') + handle_request(client, method, path, request_line, headers) + end + end + end + + def shutdown + @thread.kill + @server.close + end + + private + + def handle_request(client, method, path, request_line, headers) + if @auth_proc + req = Request.new(method, path, request_line, headers) + res = Struct.new(:body, :status).new("", 200) + @auth_proc.call(req, res) + if res.status != 200 + client.print "HTTP/1.1 #{res.status}\r\nContent-Type: text/plain\r\n\r\n#{res.body}" + return + end + end + + uri = URI(path) + proxy_request(uri, client) + rescue TestOpenURIProxy::ProxyAuthenticationRequired + @log << "ERROR ProxyAuthenticationRequired" + client.print "HTTP/1.1 407 Proxy Authentication Required\r\nContent-Length: 0\r\n\r\n" + ensure + client.close + end + + def proxy_request(uri, client) + Net::HTTP.start(uri.host, uri.port) do |http| + response = http.get(uri.path) + client.print "HTTP/1.1 #{response.code}\r\nContent-Type: #{response.content_type}\r\n\r\n#{response.body}" + end + end + + class Request + attr_reader :method, :path, :request_line, :headers + def initialize(method, path, request_line, headers) + @method = method + @path = path + @request_line = request_line + @headers = headers + end + + def [](key) + @headers[key] + end + end +end + module TestOpenURIUtils class Unauthorized < StandardError; end + class ProxyAuthenticationRequired < StandardError; end def with_http(log_tester=lambda {|log| assert_equal([], log) }) log = []