From 4b8cc437c502e5fda86ac5935baf69ec5a585e74 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 2 Nov 2011 02:06:19 +0000 Subject: make http_read_sock and friends use new socket API This will need further refactoring --- lib/mogilefs/mogilefs.rb | 25 +++++++++++++++---------- lib/mogilefs/socket_common.rb | 13 +++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb index ccee907..cdb53f8 100644 --- a/lib/mogilefs/mogilefs.rb +++ b/lib/mogilefs/mogilefs.rb @@ -64,7 +64,7 @@ class MogileFS::MogileFS < MogileFS::Client sock = http_read_sock(URI.parse(path)) begin return yield(sock) if block_given? - return sysread_full(sock, sock.mogilefs_size, @get_file_data_timeout) + return sock.read(sock.mogilefs_size, "", @get_file_data_timeout) ensure sock.close rescue nil end @@ -250,26 +250,31 @@ class MogileFS::MogileFS < MogileFS::Client # given a URI, this returns a readable socket with ready data from the # body of the response. def http_read_sock(uri, http_method = "GET") - sock = Socket.mogilefs_new_request(uri.host, uri.port, - "#{http_method} #{uri.request_uri} HTTP/1.0\r\n\r\n", - @get_file_data_timeout) - buf = sock.recv_nonblock(4096, Socket::MSG_PEEK) + tout = @get_file_data_timeout + sock = MogileFS::Socket.tcp(uri.host, uri.port, tout) + buf = "#{http_method} #{uri.request_uri} HTTP/1.0\r\n\r\n" # no chunking + + sock.timed_write(buf, tout) + sock.timed_peek(4096, buf, tout) or + raise MogileFS::InvalidResponseError, "EOF on #{http_method} #{uri}" + head, body = buf.split(/\r\n\r\n/, 2) # we're dealing with a seriously slow/stupid HTTP server if we can't - # get the header in a single read(2) syscall. + # get the header in a single recv(2) syscall. if head =~ %r{\AHTTP/\d+\.\d+\s+200\s*} && head =~ %r{^Content-Length:\s*(\d+)}i sock.mogilefs_size = $1.to_i case http_method - when "HEAD" then sock.close - when "GET" then sock.recv(head.size + 4, 0) + when "HEAD" + sock.close + when "GET" + sock.read(head.size + 4) # will allow IO.copy_stream to work end return sock end sock.close rescue nil raise MogileFS::InvalidResponseError, "#{http_method} on #{uri} returned: #{head.inspect}" - end # def http_read_sock - + end end diff --git a/lib/mogilefs/socket_common.rb b/lib/mogilefs/socket_common.rb index 7ab733c..567e715 100644 --- a/lib/mogilefs/socket_common.rb +++ b/lib/mogilefs/socket_common.rb @@ -3,6 +3,7 @@ require "socket" module MogileFS::SocketCommon attr_reader :mogilefs_addr + attr_accessor :mogilefs_size def post_init(host, port) @mogilefs_addr = "#{host}:#{port}" @@ -38,4 +39,16 @@ module MogileFS::SocketCommon end end while true end + + def read(size, buf = "", timeout = 5) + timed_read(size, buf, timeout) or return # nil/EOF + + while size > buf.bytesize + tmp ||= "" + timed_read(size - buf.bytesize, tmp, timeout) or return buf # truncated + buf << tmp + end + + buf # full read + end end -- cgit v1.2.3-24-ge0c7