From 7542c8365613d0104b8a3171418bb8c7f1a518cb Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 14 Mar 2015 01:39:23 +0000 Subject: proxy_pass: officially become a part of yahns This will rely on rack.hijack in the future to support asynchronous execution without tying up a thread when waiting for upstreams. For now, this allows simpler code with fewer checks and the use of monotonic time on newer versions of Ruby. --- test/test_proxy_pass.rb | 169 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 test/test_proxy_pass.rb (limited to 'test/test_proxy_pass.rb') diff --git a/test/test_proxy_pass.rb b/test/test_proxy_pass.rb new file mode 100644 index 0000000..530b53c --- /dev/null +++ b/test/test_proxy_pass.rb @@ -0,0 +1,169 @@ +# Copyright (C) 2015 all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require_relative 'server_helper' +require 'json' + +class TestExtrasProxyPass < Testcase + ENV["N"].to_i > 1 and parallelize_me! + include ServerHelper + + class ProxiedApp + def call(env) + h = [ %w(Content-Length 3), %w(Content-Type text/plain) ] + case env['REQUEST_METHOD'] + when 'GET' + [ 200, h, [ "hi\n"] ] + when 'HEAD' + [ 200, h, [] ] + when 'PUT' + buf = env['rack.input'].read + [ 201, { + 'Content-Length' => buf.bytesize.to_s, + 'Content-Type' => 'text/plain', + }, [ buf ] ] + end + end + end + + def setup + @srv2 = TCPServer.new(ENV["TEST_HOST"] || "127.0.0.1", 0) + server_helper_setup + end + + def teardown + @srv2.close if defined?(@srv2) && !@srv2.closed? + server_helper_teardown + end + + def test_unix_socket_no_path + tmpdir = Dir.mktmpdir + unix_path = "#{tmpdir}/proxy_pass.sock" + unix_srv = UNIXServer.new(unix_path) + err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] + host2, port2 = @srv2.addr[3], @srv2.addr[1] + pid = mkserver(cfg) do + @srv.autoclose = @srv2.autoclose = false + ENV["YAHNS_FD"] = "#{@srv.fileno},#{@srv2.fileno}" + $LOAD_PATH.unshift "#{Dir.pwd}/extras" + require 'yahns/proxy_pass' + cfg.instance_eval do + app(:rack, Yahns::ProxyPass.new("unix:#{unix_path}:/$fullpath")) do + listen "#{host}:#{port}" + end + app(:rack, Yahns::ProxyPass.new("unix:#{unix_path}:/foo$fullpath")) do + listen "#{host2}:#{port2}" + end + stderr_path err.path + end + end + + pid2 = mkserver(cfg, unix_srv) do + @srv.close + @srv2.close + cfg.instance_eval do + rapp = lambda do |env| + body = env.to_json + hdr = { + 'Content-Length' => body.bytesize.to_s, + 'Content-Type' => 'application/json', + } + [ 200, hdr, [ body ] ] + end + app(:rack, rapp) { listen unix_path } + stderr_path err.path + end + end + Net::HTTP.start(host, port) do |http| + res = http.request(Net::HTTP::Get.new('/f00')) + assert_equal 200, res.code.to_i + body = JSON.parse(res.body) + assert_equal '/f00', body['PATH_INFO'] + + res = http.request(Net::HTTP::Get.new('/f00foo')) + assert_equal 200, res.code.to_i + body = JSON.parse(res.body) + assert_equal '/f00foo', body['PATH_INFO'] + end + + Net::HTTP.start(host2, port2) do |http| + res = http.request(Net::HTTP::Get.new('/Foo')) + assert_equal 200, res.code.to_i + body = JSON.parse(res.body) + assert_equal '/foo/Foo', body['PATH_INFO'] + + res = http.request(Net::HTTP::Get.new('/Foofoo')) + assert_equal 200, res.code.to_i + body = JSON.parse(res.body) + assert_equal '/foo/Foofoo', body['PATH_INFO'] + end + ensure + quit_wait(pid) + quit_wait(pid2) + unix_srv.close if unix_srv + FileUtils.rm_rf(tmpdir) if tmpdir + end + + def test_proxy_pass + err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] + host2, port2 = @srv2.addr[3], @srv2.addr[1] + pid = mkserver(cfg) do + $LOAD_PATH.unshift "#{Dir.pwd}/extras" + require 'yahns/proxy_pass' + @srv2.close + cfg.instance_eval do + app(:rack, Yahns::ProxyPass.new("http://#{host2}:#{port2}/")) do + listen "#{host}:#{port}" + end + stderr_path err.path + end + end + + pid2 = mkserver(cfg, @srv2) do + @srv.close + cfg.instance_eval do + app(:rack, ProxiedApp.new) do + listen "#{host2}:#{port2}" + end + stderr_path err.path + end + end + + gplv3 = File.open('COPYING') + + Net::HTTP.start(host, port) do |http| + res = http.request(Net::HTTP::Get.new('/')) + assert_equal 200, res.code.to_i + n = res.body.bytesize + assert_operator n, :>, 1 + res = http.request(Net::HTTP::Head.new('/')) + assert_equal 200, res.code.to_i + assert_equal n, res['Content-Length'].to_i + assert_nil res.body + + # chunked encoding + req = Net::HTTP::Put.new('/') + req.body_stream = gplv3 + req.content_type = 'application/octet-stream' + req['Transfer-Encoding'] = 'chunked' + res = http.request(req) + gplv3.rewind + assert_equal gplv3.read, res.body + assert_equal 201, res.code.to_i + + # normal content-length + gplv3.rewind + req = Net::HTTP::Put.new('/') + req.body_stream = gplv3 + req.content_type = 'application/octet-stream' + req.content_length = gplv3.size + res = http.request(req) + gplv3.rewind + assert_equal gplv3.read, res.body + assert_equal 201, res.code.to_i + end + ensure + gplv3.close if gplv3 + quit_wait pid + quit_wait pid2 + end +end -- cgit v1.2.3-24-ge0c7