require 'net/http'
module NetX
class HTTPUnix < Net::HTTP
  BufferedIO = ::Net::BufferedIO
  UNIX_REGEXP = %r{^unix://}i

  def initialize(address, port=nil)
    super(address, port)
    case address
    when UNIX_REGEXP
      @socket_type = 'unix'
      @address = address.sub(UNIX_REGEXP, '')
      @port = nil
    else
      @socket_type = 'inet'
    end
  end

  def connect
    if @socket_type == 'unix'
      connect_unix
    else
      super
    end
  end

  ##
  # connect_unix is an alternative implementation of Net::HTTP#connect specific
  # to the use case of using a Unix Domain Socket.
  def connect_unix
    D "opening connection to #{conn_address()}..."
    s = timeout(@open_timeout) { UNIXSocket.open(conn_address()) }
    D "opened"
    @socket = BufferedIO.new(s)
    @socket.read_timeout = @read_timeout
    @socket.continue_timeout = @continue_timeout
    @socket.debug_output = @debug_output
    on_connect
  end
end
end

require 'net/http'
module NetX
class HTTPUnix < Net::HTTP
  BufferedIO = ::Net::BufferedIO
  UNIX_REGEXP = %r{^unix://}i

  def initialize(address, port=nil)
    super(address, port)
    case address
    when UNIX_REGEXP
      @socket_type = 'unix'
      @socket_path = address.sub(UNIX_REGEXP, '')
      # Address and port are set to localhost so the HTTP client constructs
      # a HOST request header nginx will accept.
      @address = 'localhost'
      @port = 80
    else
      @socket_type = 'inet'
    end
  end

  def connect
    if @socket_type == 'unix'
      connect_unix
    else
      super
    end
  end

  ##
  # connect_unix is an alternative implementation of Net::HTTP#connect specific
  # to the use case of using a Unix Domain Socket.
  def connect_unix
    D "opening connection to #{@socket_path}..."
    s = timeout(@open_timeout) { UNIXSocket.open(@socket_path) }
    D "opened"
    @socket = BufferedIO.new(s)
    @socket.read_timeout = @read_timeout
    @socket.continue_timeout = @continue_timeout
    @socket.debug_output = @debug_output
    on_connect
  end
end
end

Fix incorrect HOST request header causing 400 errors
Fix incorrect HOST request header causing 400 errors

Without this patch nginx returns a 400 error response for requests that
otherwise are 200 OK over TCP connections.  The specific error message
is:

    2014/11/25 21:47:24 [info] 19036#0: *1 client sent invalid host
    header while reading client request headers, client: unix:, server:
    localhost, request: "POST /command-api HTTP/1.1", host:
    "/var/run/command-api.sock:"

This patch addresses the problem by storing a valid hostname of
'localhost' in the @address instance variable rather than the socket
path.  This change allows the HTTP client to construct a HOST request
header nginx will accept.  The unix domain socket specific connection
method uses the @socket_path instance variable instead of relying on the
behavior of conn_address() which in turn used @address.
