about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-11-10 05:28:08 +0000
committerEric Wong <normalperson@yhbt.net>2011-11-10 05:28:08 +0000
commitfebf8fc2aab898218333e245bab4bda972de5692 (patch)
tree1e2a9e38e7d526335d4d5570fd53c3f2ad57861c
parent9c0a7c670494fb55fb8ef98838fa0f53aab38d0d (diff)
downloadmogilefs-client-febf8fc2aab898218333e245bab4bda972de5692.tar.gz
We don't want to silently truncate data on our users,
that would be bad.
-rw-r--r--lib/mogilefs/http_reader.rb7
-rw-r--r--lib/mogilefs/mogilefs.rb2
-rw-r--r--test/test_http_reader.rb33
3 files changed, 41 insertions, 1 deletions
diff --git a/lib/mogilefs/http_reader.rb b/lib/mogilefs/http_reader.rb
index d7a36e6..c338e70 100644
--- a/lib/mogilefs/http_reader.rb
+++ b/lib/mogilefs/http_reader.rb
@@ -19,6 +19,13 @@ class MogileFS::HTTPReader < MogileFS::Socket
           "read=#{buf.size} bytes, expected=#@content_length from #@uri", []
   end
 
+  def stream_to(dest)
+    rv = MogileFS::X.copy_stream(self, dest)
+    return rv if rv == @content_length
+    raise MogileFS::SizeMismatchError,
+          "read=#{rv} bytes, expected=#@content_length from #@uri", []
+  end
+
   def self.first(paths, timeout, count = nil, offset = nil)
     errors = nil
     if offset || count
diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb
index e1b3eb6..d926926 100644
--- a/lib/mogilefs/mogilefs.rb
+++ b/lib/mogilefs/mogilefs.rb
@@ -62,7 +62,7 @@ class MogileFS::MogileFS < MogileFS::Client
     sock = MogileFS::HTTPReader.first(paths, @get_file_data_timeout,
                                       count, offset)
     if dest
-      MogileFS::X.copy_stream(sock, dest)
+      sock.stream_to(dest)
     elsif block_given?
       yield(sock)
     else
diff --git a/test/test_http_reader.rb b/test/test_http_reader.rb
new file mode 100644
index 0000000..634b28c
--- /dev/null
+++ b/test/test_http_reader.rb
@@ -0,0 +1,33 @@
+# -*- encoding: binary -*-
+require "./test/setup"
+
+class TestHTTPReader < Test::Unit::TestCase
+  def rsock
+    host = "127.0.0.1"
+    s = TCPServer.new(host, 0)
+    th = Thread.new do
+      c = s.accept
+      c.readpartial(0x666)
+      c.write("HTTP/1.0 200 OK\r\nContent-Length: 666\r\n\r\n666")
+      c.close
+    end
+    path = "http://#{host}:#{s.addr[1]}/"
+    r = MogileFS::HTTPReader.try(path, 666, nil)
+    assert_kind_of IO, r
+    r
+    ensure
+      s.close
+  end
+
+  def test_short_to_s
+    r = rsock
+    assert_raises(MogileFS::SizeMismatchError) { r.to_s }
+    r.close
+  end
+
+  def test_short_stream_to
+    r = rsock
+    assert_raises(MogileFS::SizeMismatchError) { r.stream_to("/dev/null") }
+    r.close
+  end
+end