about summary refs log tree commit homepage
path: root/lib/mogilefs/http_file.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mogilefs/http_file.rb')
-rw-r--r--lib/mogilefs/http_file.rb31
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/mogilefs/http_file.rb b/lib/mogilefs/http_file.rb
index 7871940..c96e695 100644
--- a/lib/mogilefs/http_file.rb
+++ b/lib/mogilefs/http_file.rb
@@ -136,14 +136,41 @@ class MogileFS::HTTPFile < StringIO
       sock.close if sock
   end
 
+  def nhp_put(devid, uri)
+    clen = @opts[:content_length]
+    if clen && clen != size
+      raise MogileFS::SizeMismatchError,
+        ":content_length expected: #{clen.inspect}, actual: #{size}"
+    end
+
+    put = Net::HTTP::Put.new(uri.path)
+    put["Content-Type"] = "application/octet-stream"
+    if md5 = @opts[:content_md5]
+      if md5.respond_to?(:call)
+        md5 = md5.call.strip
+      elsif md5 == :trailer
+        md5 = [ Digest::MD5.digest(string) ].pack("m").chomp!
+      end
+      put["Content-MD5"] = md5
+    end
+    put.body = string
+    res = MogileFS::NHP.request(uri, put)
+    return size if Net::HTTPSuccess === res
+    raise BadResponseError, "#{res.code} #{res.message}"
+  rescue => e
+    /\ANet::/ =~ "#{e.class}" and
+        raise RetryableError, "#{e.message} (#{e.class})", e.backtrace
+    raise
+  end
+
   def commit
     errors = nil
     @dests.each do |devid, path|
       begin
         uri = URI.parse(path)
-        bytes_uploaded = upload(devid, uri)
+        bytes_uploaded = size > 0 ? nhp_put(devid, uri) : upload(devid, uri)
         return create_close(devid, uri, bytes_uploaded)
-      rescue SystemCallError, RetryableError => e
+      rescue Timeout::Error, SystemCallError, RetryableError => e
         errors ||= []
         errors << "#{path} - #{e.message} (#{e.class})"
       end