about summary refs log tree commit homepage
path: root/lib/mogilefs/http_file.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-11-20 06:29:26 +0000
committerEric Wong <normalperson@yhbt.net>2011-11-20 08:17:51 +0000
commit21fc20b7d798c3eab6155b24dcb58c95b53ef856 (patch)
treefef27d545c9263862e305a66b1b5a867e0138121 /lib/mogilefs/http_file.rb
parent6018860fe20c82daa131cb9e30dba228c862c540 (diff)
downloadmogilefs-client-21fc20b7d798c3eab6155b24dcb58c95b53ef856.tar.gz
This should allow any Rack server to become an HTTP server for
mogstored.

When using one of Unicorn/Rainbows!/Zbatery, the Content-MD5
HTTP Trailer will be supported.  Otherwise, Content-MD5 can
always be supported as a regular HTTP header (at the cost of
requiring the client to read whatever they upload twice).
Diffstat (limited to 'lib/mogilefs/http_file.rb')
-rw-r--r--lib/mogilefs/http_file.rb18
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/mogilefs/http_file.rb b/lib/mogilefs/http_file.rb
index 5ed69a4..1611a5d 100644
--- a/lib/mogilefs/http_file.rb
+++ b/lib/mogilefs/http_file.rb
@@ -20,6 +20,8 @@ class MogileFS::HTTPFile < StringIO
   end
   class NonRetryableError < MogileFS::Error; end
 
+  MD5_TRAILER_NODES = {} # :nodoc: # EXPERIMENTAL
+
   ##
   # The URI this file will be stored to.
 
@@ -45,15 +47,23 @@ class MogileFS::HTTPFile < StringIO
   end
 
   def request_put(sock, uri, file_size, input = nil)
+    host_with_port = "#{uri.host}:#{uri.port}"
+    md5 = false
+    if MD5_TRAILER_NODES[host_with_port]
+      file_size = nil
+      md5 = true
+    end
+
     if file_size
       sock.write("PUT #{uri.request_uri} HTTP/1.0\r\n" \
                  "Content-Length: #{file_size}\r\n\r\n")
       input ? MogileFS.io.copy_stream(@active = input, sock) : yield(sock)
     else
+      trailers = md5 ? "Trailer: Content-MD5\r\n" : ""
       sock.write("PUT #{uri.request_uri} HTTP/1.1\r\n" \
-                 "Host: #{uri.host}:#{uri.port}\r\n" \
+                 "Host: #{host_with_port}\r\n#{trailers}" \
                  "Transfer-Encoding: chunked\r\n\r\n")
-      tmp = MogileFS::Chunker.new(sock)
+      tmp = MogileFS::Chunker.new(sock, md5)
       rv = input ? MogileFS.io.copy_stream(@active = input, tmp) : yield(tmp)
       tmp.flush
       rv
@@ -105,8 +115,8 @@ class MogileFS::HTTPFile < StringIO
         file_size = request_put(sock, uri, size, @big_io)
       end
     else
-      sock.write("PUT #{uri.request_uri} HTTP/1.0\r\n" \
-                 "Content-Length: #{file_size}\r\n\r\n#{string}")
+      rewind
+      request_put(sock, uri, file_size, self)
     end
 
     case line = sock.timed_read(23, "")