From: Eric Wong <e@80x24.org>
To: yahns-public@yhbt.net
Subject: [PATCH 2/3] extras/proxy_pass: support Unix domain sockets as backends
Date: Sat, 14 Mar 2015 03:17:57 +0000 [thread overview]
Message-ID: <1426303078-4525-3-git-send-email-e@80x24.org> (raw)
In-Reply-To: <1426303078-4525-1-git-send-email-e@80x24.org>
Of course, some users will prefer to bind HTTP application
servers to Unix domain sockets for better isolation and (maybe)
better performance.
---
| 7 +++--
| 69 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 2 deletions(-)
--git a/extras/proxy_pass.rb b/extras/proxy_pass.rb
index d435ebe..00adf18 100644
--- a/extras/proxy_pass.rb
+++ b/extras/proxy_pass.rb
@@ -112,12 +112,15 @@ class ProxyPass # :nodoc:
def initialize(dest, timeout = 5)
case dest
+ when %r{\Aunix:([^:]+)(?::(/.*))?\z}
+ path = $2
+ @sockaddr = Socket.sockaddr_un($1)
when %r{\Ahttp://([^/]+)(/.*)?\z}
path = $2
host, port = $1.split(':')
@sockaddr = Socket.sockaddr_in(port || 80, host)
else
- raise ArgumentError, "destination must be an HTTP URL"
+ raise ArgumentError, "destination must be an HTTP URL or unix: path"
end
init_path_vars(path)
@pool = ConnPool.new
@@ -125,7 +128,7 @@ class ProxyPass # :nodoc:
end
def init_path_vars(path)
- path ||= '$(fullpath)'
+ path ||= '$fullpath'
# methods from Rack::Request we want:
allow = %w(fullpath host_with_port host port url path)
want = path.scan(/\$(\w+)/).flatten! || []
--git a/test/test_extras_proxy_pass.rb b/test/test_extras_proxy_pass.rb
index 8842683..5bbce73 100644
--- a/test/test_extras_proxy_pass.rb
+++ b/test/test_extras_proxy_pass.rb
@@ -1,6 +1,7 @@
# Copyright (C) 2015 all contributors <yahns-public@yhbt.net>
# 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!
@@ -34,6 +35,74 @@ class TestExtrasProxyPass < Testcase
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 'proxy_pass'
+ cfg.instance_eval do
+ app(:rack, ProxyPass.new("unix:#{unix_path}:/$fullpath")) do
+ listen "#{host}:#{port}"
+ end
+ app(:rack, 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]
--
EW
next prev parent reply other threads:[~2015-03-14 3:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-14 3:17 [PATCH 0/3] towards becoming a fully-buffering reverse proxy Eric Wong
2015-03-14 3:17 ` [PATCH 1/3] extras/proxy_pass: implicit $fullpath expansion for upstreams Eric Wong
2015-03-14 3:17 ` Eric Wong [this message]
2015-03-14 3:17 ` [PATCH 3/3] proxy_pass: officially become a part of yahns Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/yahns/README
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1426303078-4525-3-git-send-email-e@80x24.org \
--to=e@80x24.org \
--cc=yahns-public@yhbt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/yahns.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).