added unix io type (so now one can open unix sockets), added a basic test to show that connectivity is possible

This commit is contained in:
HoneyryderChuck 2018-05-25 15:57:46 +01:00
parent 54d4c613d1
commit 6c49581dc2
3 changed files with 113 additions and 0 deletions

View File

@ -250,8 +250,10 @@ module HTTPX
end
end
module IO
require "httpx/io/unix"
extend Registry
register "tcp", TCP
register "ssl", SSL
register "unix", HTTPX::UNIX
end
end

55
lib/httpx/io/unix.rb Normal file
View File

@ -0,0 +1,55 @@
require "forwardable"
module HTTPX
class UNIX < TCP
extend Forwardable
def_delegator :@uri, :port, :scheme
def initialize(uri, options)
@uri = uri
@state = :idle
@options = Options.new(options)
@path = @options.transport_options[:path]
@fallback_protocol = @options.fallback_protocol
if @options.io
@io = case @options.io
when Hash
@options.io[@path]
else
@options.io
end
unless @io.nil?
@keep_open = true
@state = :connected
end
end
@io ||= build_socket
end
def hostname
@uri.host
end
def connect
return unless closed?
begin
if @io.closed?
transition(:idle)
@io = build_socket
end
@io.connect_nonblock(Socket.sockaddr_un(@path))
rescue Errno::EISCONN
end
transition(:connected)
rescue Errno::EINPROGRESS,
Errno::EALREADY,
::IO::WaitReadable
end
private
def build_socket
Socket.new(Socket::PF_UNIX, :STREAM, 0)
end
end
end

56
test/io/unix_test.rb Normal file
View File

@ -0,0 +1,56 @@
# frozen_string_literal: true
require "tempfile"
require_relative "../test_helper"
class UnixTest < Minitest::Test
include HTTPX
def test_unix_client
on_unix_server do |path|
client = Client.new(transport: "unix", transport_options: { path: path})
response = client.get("http://unix.com/ping")
assert response.status == 200, "unexpected code (#{response.status})"
assert response.to_s == "pong", "unexpected body (#{response.to_s})"
response.close
client.close
end
end
private
RESPONSE_HEADER = (<<-HTTP).lines.map.map(&:chomp).join("\r\n") << ("\r\n" * 2)
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Content-Length: 4
Content-Type: text/plain
Connection: close
HTTP
def on_unix_server
mutex = Mutex.new
resource = ConditionVariable.new
path = File.join(Dir.tmpdir, "httpx-unix.sock")
server = UNIXServer.new(path)
begin
th = Thread.start do
mutex.synchronize do
resource.signal
end
socket = server.accept
socket.readpartial(4096) # drain the socket for the request
socket.write(RESPONSE_HEADER)
socket.write("pong")
socket.close
end
mutex.synchronize do
resource.wait(mutex)
end
yield server.path
ensure
server.close
File.unlink(path)
th.terminate
end
end
end