2

现在我尝试使用此代码连接到独角兽创建的套接字

require 'socket'

def foo
  socket = UNIXSocket.new("path_to_socket/tmp/unicorn.sock")

  data = "GET /time HTTP/1.1\n" 
  data << "Connection: Close\n" 
  data << "User-Agent: Mozilla/5.0\n" 
  data << "Accept: */*\n" 
  data << "Content-Type: application/x-www-form-urlencoded\n" 
  data << "\n\r\n\r"

  socket.puts(data)

  while(line = socket.gets) do
    puts line
  end 
end

foo

但总是收到“HTTP/1.1 400 Bad Request”

拜托,任何人都可以说我做错了什么吗???

4

2 回答 2

5

使用网络/http...

require "net/http"
require "socket"

sock = Net::BufferedIO.new(UNIXSocket.new("path_to_socket/tmp/unicorn.sock"))
request = Net::HTTP::Get.new("/time")
request.exec(sock, "1.1", "/time")

begin
  response = Net::HTTPResponse.read_new(sock)
end while response.kind_of?(Net::HTTPContinue)
response.reading_body(sock, request.response_body_permitted?) { }

response.body
response.code
于 2013-03-26T02:55:14.680 回答
2

这很有帮助,但请注意 Net::HTTP#exec 方法被标记为仅供内部使用。可能是因为它不进行资源管理等。

以下工作调整了建议的策略以覆盖 Net::HTTP#connect (连接到套接字)。我喜欢使用HTTParty gem来处理我的 HTTP 请求。所以这里的策略使用了 HTTParty 的自定义 ConnectionAdaptor。现在我可以更改包含类的 ::default_params= 调用,以控制我们使用的是 Unix 还是 TCP/HTTP 套接字。

###########################################################
#  net/socket_http.rb
###########################################################

module Net
  #  Overrides the connect method to simply connect to a unix domain socket.
  class SocketHttp < HTTP
    attr_reader :socket_path

    #  URI should be a relative URI giving the path on the HTTP server.
    #  socket_path is the filesystem path to the socket the server is listening to.
    def initialize(uri, socket_path)
      @socket_path = socket_path
      super(uri)
    end

    #  Create the socket object.
    def connect
      @socket = Net::BufferedIO.new UNIXSocket.new socket_path
      on_connect
    end

    #  Override to prevent errors concatenating relative URI objects.
    def addr_port
      File.basename(socket_path)
    end
  end
end


###########################################################
#  sock_party.rb, a ConnectionAdapter class
###########################################################
require "net/http"
require "socket"

class SockParty < HTTParty::ConnectionAdapter
  #  Override the base class connection method.
  #  Only difference is that we'll create a Net::SocketHttp rather than a Net::HTTP.
  #  Relies on :socket_path in the
  def connection
    http = Net::SocketHttp.new(uri, options[:socket_path])

    if options[:timeout] && (options[:timeout].is_a?(Integer) || options[:timeout].is_a?(Float))
      http.open_timeout = options[:timeout]
      http.read_timeout = options[:timeout]
    end

    if options[:debug_output]
      http.set_debug_output(options[:debug_output])
    end

    if options[:ciphers]
      http.ciphers = options[:ciphers]
    end

    return http
  end
end


###########################################################
#  class MockSockParty, a really *nix-y HTTParty
###########################################################
class MockSockParty
  include HTTParty
  self.default_options = {connection_adapter: SockParty, socket_path: '/tmp/thin.sock'}

  def party_hard
    self.class.get('/client').body
  end
end

###########################################################
#  sock_party_spec.rb
###########################################################

require 'spec_helper'

describe SockParty do
  it "should party until its socks fall off." do
    puts MockSockParty.new.party_hard
  end
end
于 2013-11-28T12:50:13.340 回答