From 42abd93b948881afe5c3e9d04ceb5f40fda4472c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 30 Oct 2012 21:41:01 +0000 Subject: [PATCH] http_reader: improve robustness of header reading It's possible for networks and servers to break up even small HTTP headers. We also better enforce the timeout if we too too long to write the request. --- lib/mogilefs/http_reader.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/mogilefs/http_reader.rb b/lib/mogilefs/http_reader.rb index 3afaae0..8a0337e 100644 --- a/lib/mogilefs/http_reader.rb +++ b/lib/mogilefs/http_reader.rb @@ -50,17 +50,18 @@ class MogileFS::HTTPReader < MogileFS::Socket # body of the response. def self.try(path, timeout, range) # :nodoc: uri = URI.parse(path) + expire_at = Time.now + timeout sock = tcp(uri.host, uri.port, timeout) buf = "GET #{uri.request_uri} HTTP/1.0\r\n#{range}\r\n" # no chunking sock.timed_write(buf, timeout) - sock.timed_peek(2048, buf, timeout) or - raise MogileFS::InvalidResponseError, "EOF while reading header", [] + begin + raise MogileFS::Timeout if Time.now > expire_at + sock.timed_peek(2048, buf, timeout) or + raise MogileFS::InvalidResponseError, "EOF while reading header", [] + end until /\r\n\r\n/ =~ buf head, _ = 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 recv(2) syscall. if ((range && head =~ %r{\AHTTP/\d+\.\d+\s+206\s*}) || (!range && head =~ %r{\AHTTP/\d+\.\d+\s+200\s*})) && head =~ %r{^Content-Length:\s*(\d+)}i -- 2.11.4.GIT