5 require 'mogilefs/backend'
8 # HTTPFile wraps up the new file operations for storing files onto an HTTP
11 # You really don't want to create an HTTPFile by hand. Instead you want to
12 # create a new file using MogileFS::MogileFS.new_file.
14 # WARNING! HTTP mode is completely untested as I cannot make it work on
15 # FreeBSD. Please send patches/tests if you find bugs.
17 # TODO dup'd content in MogileFS::NFSFile
19 class MogileFS::HTTPFile < StringIO
22 # The path this file will be stored to.
27 # The key for this file. This key won't represent a real file until you've
33 # The class of this file.
38 # Works like File.open. Use MogileFS::MogileFS#new_file instead of this
44 return fp unless block_given?
54 # Creates a new HTTPFile with MogileFS-specific data. Use
55 # MogileFS::MogileFS#new_file instead of this method.
57 def initialize(mg, fid, path, devid, klass, key, dests, content_length)
66 @dests = dests.map { |(_,u)| URI.parse u }
73 # Closes the file handle and marks it as closed in MogileFS.
78 @socket.write "PUT #{@path.request_uri} HTTP/1.0\r\nContent-length: #{length}\r\n\r\n#{string}"
82 raise 'Unable to read response line from server' if line.nil?
84 if line =~ %r%^HTTP/\d+\.\d+\s+(\d+)% then
87 when 200..299 then # success!
94 found_header = true if line.nil?
95 next unless found_header
98 body = body[0, 512] if body.length > 512
99 raise "HTTP response status from upload: #{body}"
102 raise "Response line not understood: #{line}"
107 @mg.backend.create_close(:fid => @fid, :devid => @devid,
108 :domain => @mg.domain, :key => @key,
109 :path => @path, :size => length)
116 return !(@socket.nil? or @socket.closed?)
120 return @socket if connected?
127 raise 'Unable to open socket to storage node' if @path.nil?
130 @socket = TCPSocket.new @path.host, @path.port
135 @dests.each do |dest|
136 unless @tried.include? dest then