lib/knj/http2.rb in knjrbfw-0.0.39 vs lib/knj/http2.rb in knjrbfw-0.0.40

- old
+ new

@@ -163,10 +163,11 @@ header_str = "GET /#{addr} HTTP/1.1#{@nl}" header_str << self.header_str(self.default_headers(args), args) header_str << "#{@nl}" print "Http2: Writing headers.\n" if @debug + print "Header str: #{header_str}\n" if @debug self.write(header_str) print "Http2: Reading response.\n" if @debug resp = self.read_response(args) @@ -207,29 +208,50 @@ } if !@args.key?(:encoding_gzip) or @args[:encoding_gzip] headers["Accept-Encoding"] = "gzip" else - headers["Accept-Encoding"] = "none" + #headers["Accept-Encoding"] = "none" end return headers end - def self.post_convert_data(pdata) + #This is used to convert a hash to valid post-data recursivly. + def self.post_convert_data(pdata, args = nil) praw = "" if pdata.is_a?(Hash) pdata.each do |key, val| praw << "&" if praw != "" - praw << "#{Knj::Web.urlenc(Knj::Http2.post_convert_data(key))}=#{Knj::Web.urlenc(Knj::Http2.post_convert_data(val))}" + + if args and args[:orig_key] + key = "#{args[:orig_key]}[#{key}]" + end + + if val.is_a?(Hash) or val.is_a?(Array) + praw << self.post_convert_data(val, {:orig_key => key}) + else + praw << "#{Knj::Web.urlenc(key)}=#{Knj::Web.urlenc(Knj::Http2.post_convert_data(val))}" + end end elsif pdata.is_a?(Array) count = 0 pdata.each do |val| + if args and args[:orig_key] + key = "#{args[:orig_key]}[#{count}]" + else + key = count + end + + if val.is_a?(Hash) or val.is_a?(Array) + praw << self.post_convert_data(val, {:orig_key => key}) + else + praw << "#{Knj::Web.urlenc(key)}=#{Knj::Web.urlenc(Knj::Http2.post_convert_data(val))}" + end + count += 1 - praw << "#{count}=#{Knj::Web.urlenc(Knj::Http2.post_convert_data(val))}" end else return pdata.to_s end @@ -244,11 +266,11 @@ print "Doing post.\n" if @debug praw = Knj::Http2.post_convert_data(pdata) header_str = "POST /#{addr} HTTP/1.1#{@nl}" - header_str << self.header_str(self.default_headers(args).merge("Content-Length" => praw.length), args) + header_str << self.header_str(self.default_headers(args).merge("Content-Type" => "application/x-www-form-urlencoded", "Content-Length" => praw.length), args) header_str << "#{@nl}" header_str << praw print "Header str: #{header_str}\n" if @debug @@ -264,48 +286,92 @@ require "digest" @mutex.synchronize do boundary = Digest::MD5.hexdigest(Time.now.to_f.to_s) - praw = "" - pdata.each do |key, val| - praw << "--#{boundary}#{@nl}" - - if val.class.name == "Tempfile" and val.respond_to?("original_filename") - praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.original_filename}\";#{@nl}" - praw << "Content-Length: #{val.to_s.bytesize}#{@nl}" - elsif val.is_a?(Hash) and val[:filename] - praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val[:filename]}\";#{@nl}" - praw << "Content-Length: #{val[:content].to_s.bytesize}#{@nl}" - else - praw << "Content-Disposition: form-data; name=\"#{key}\";#{@nl}" - praw << "Content-Length: #{val.to_s.bytesize}#{@nl}" + #Generate 'praw'-variable with post-content. + tmp_path = "#{Knj::Os.tmpdir}/knj_http2_post_multiepart_tmp_#{boundary}" + + begin + File.open(tmp_path, "w") do |praw| + pdata.each do |key, val| + praw << "--#{boundary}#{@nl}" + + if val.class.name == "Tempfile" and val.respond_to?("original_filename") + praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val.original_filename}\";#{@nl}" + praw << "Content-Length: #{val.to_s.bytesize}#{@nl}" + elsif val.is_a?(Hash) and val[:filename] + praw << "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{val[:filename]}\";#{@nl}" + + if val[:content] + praw << "Content-Length: #{val[:content].to_s.bytesize}#{@nl}" + elsif val[:fpath] + praw << "Content-Length: #{File.size(val[:fpath])}#{@nl}" + else + raise "Could not figure out where to get content from." + end + else + praw << "Content-Disposition: form-data; name=\"#{key}\";#{@nl}" + praw << "Content-Length: #{val.to_s.bytesize}#{@nl}" + end + + praw << "Content-Type: text/plain#{@nl}" + praw << @nl + + if val.is_a?(StringIO) + praw << val.read + elsif val.is_a?(Hash) and val[:content] + praw << val[:content].to_s + elsif val.is_a?(Hash) and val[:fpath] + File.open(val[:fpath], "r") do |fp| + begin + while data = fp.sysread(4096) + praw << data + end + rescue EOFError + #ignore. + end + end + else + praw << val.to_s + end + + praw << @nl + end + + praw << "--#{boundary}--" end - praw << "Content-Type: text/plain#{@nl}" - praw << @nl - if val.is_a?(StringIO) - praw << val.read - elsif val.is_a?(Hash) and val[:content] - praw << val[:content].to_s - else - praw << val.to_s + #Generate header-string containing 'praw'-variable. + header_str = "POST /#{addr} HTTP/1.1#{@nl}" + header_str << self.header_str(self.default_headers(args).merge( + "Content-Type" => "multipart/form-data; boundary=#{boundary}", + "Content-Length" => File.size(tmp_path) + ), args) + header_str << @nl + + + #Debug. + print "Headerstr: #{header_str}\n" if @debug + + + #Write and return. + self.write(header_str) + File.open(tmp_path, "r") do |fp| + begin + while data = fp.sysread(4096) + @sock.write(data) + end + rescue EOFError + #ignore. + end end - praw << @nl + return self.read_response(args) + ensure + File.unlink(tmp_path) if File.exists?(tmp_path) end - - header_str = "POST /#{addr} HTTP/1.1#{@nl}" - header_str << self.header_str(self.default_headers(args).merge("Content-Type" => "multipart/form-data; boundary=#{boundary}", "Content-Length" => praw.bytesize), args) - header_str << "#{@nl}" - header_str << praw - header_str << "--#{boundary}--" - - print "Headerstr: #{header_str}\n" if @debug - - self.write(header_str) - return self.read_response(args) end end #Returns a header-string which normally would be used for a request in the given state. def header_str(headers_hash, args = {}) \ No newline at end of file