ruby 1.9.3简单GET通过套接字请求独角兽

时间:2013-03-25 08:40:42

标签: ruby sockets

现在我尝试使用此代码连接到由unicorn创建的套接字

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”

拜托,任何人都能说出我做错了吗?

2 个答案:

答案 0 :(得分:5)

使用net / 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

答案 1 :(得分: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