lib/tap/http/utils.rb in tap-http-0.3.0 vs lib/tap/http/utils.rb in tap-http-0.3.1

- old
+ new

@@ -20,21 +20,10 @@ # # :version => "1.1", # # :headers => {}, # # :params => {}, # # } # - # If splat_values is specified, single-value headers and parameters - # will be hashed as single values. Otherwise, all header and parameter - # values will be arrays. - # - # str = "GET /path?one=a&one=b&two=c HTTP/1.1\n" - # req = parse_http_request(str) - # req[:params] # => {'one' => ['a', 'b'], 'two' => 'c'} - # - # req = parse_http_request(str, false) - # req[:params] # => {'one' => ['a', 'b'], 'two' => ['c']} - # # ==== WEBrick parsing of HTTP format # # WEBrick will parse headers then the body of a request, and currently # (1.8.6) considers an empty line as a break between the headers and # body. In general header parsing is forgiving with end-line @@ -82,25 +71,25 @@ # #-- # TODO: check if there are other headers to capture from # a multipart/form file. Currently only # 'Filename' and 'Content-Type' are added - def parse_http_request(socket, splat_values=true) + def parse_http_request(socket, keep_content=true) socket = StringIO.new(socket) if socket.kind_of?(String) req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP) req.parse(socket) - parse_webrick_request(req, splat_values) + parse_webrick_request(req, keep_content) end # Parses a WEBrick::HTTPRequest, with the same activity as # parse_http_request. - def parse_webrick_request(req, splat_values=true) + def parse_webrick_request(req, keep_content=true) headers = {} req.header.each_pair do |key, values| - headers[headerize(key)] = splat_values ? splat(values) : values + headers[headerize(key)] = splat(values) end if req.header params = {} req.query.each_pair do |key, value| # no sense for how robust this is... @@ -110,97 +99,79 @@ # Senseless. No wonder WEBrick has no documentation, who could # write it? values = [] value.each_data do |data| values << if data.filename - {'Filename' => data.filename, 'Content-Type' => data['Content-Type']} + hash = {'Filename' => data.filename, 'Content-Type' => data['Content-Type']} + hash['Content'] = data.to_a.join("\n") if keep_content + hash else data.to_s end end - params[key] = splat_values ? splat(values) : values + params[key] = splat(values) end if req.query { :url => headers['Host'] ? File.join("http://", headers['Host'], req.path_info) : req.path_info, :request_method => req.request_method, :version => req.http_version.to_s, :headers => headers, :params => params} end - # Parses the input CGI into a hash that may be resubmitted by Dispatch. - # To work properly, the standard CGI environmental variables must be - # set in ENV. - # - def parse_cgi_request(cgi, splat_values=true) + # Parses a Rack::Request, with the same activity as parse_http_request. + def parse_rack_request(request, keep_content=true) headers = {} - ENV.each_pair do |key, values| + request.env.each_pair do |key, value| key = case key when "HTTP_VERSION" then next when /^HTTP_(.*)/ then $1 when 'CONTENT_TYPE' then key else next end - - headers[headerize(key)] = splat_values ? splat(values) : values + + headers[headerize(key)] = value end - + params = {} - cgi.params.each_pair do |key, values| - values = values.collect do |value| - case - when !value.respond_to?(:read) - value - when value.original_filename.empty? - value.read - else - {'Filename' => value.original_filename, 'Content-Type' => value.content_type} + request.params.each_pair do |key, value| + params[key] = each_member(value) do |obj| + if obj.kind_of?(Hash) + file = {'Content-Type' => value[:type], 'Filename' => value[:filename]} + file['Content'] = value[:tempfile].read if keep_content + file + else value end end - - params[key] = splat_values ? splat(values) : values end - - { :url => File.join("http://", headers['Host'], ENV['PATH_INFO']), - :request_method => ENV['REQUEST_METHOD'], - :version => ENV['HTTP_VERSION'] =~ /^HTTP\/(.*)$/ ? $1.to_f : ENV['HTTP_VERSION'], + + { + :uri => File.join("http://", headers['Host'], request.env['PATH_INFO']), + :request_method => request.request_method, + :version => request.env['HTTP_VERSION'] =~ /^HTTP\/(.*)$/ ? $1.to_f : request.env['HTTP_VERSION'], :headers => headers, - :params => params} + :params => params + } end - def determine_url(action, referer) - base = File.basename(referer) - - case action - when /^https?:/ then action - when /\// - # only use host of page_url - File.join(base, action) - else File.join(base, action) - end + # Yields each member of an input array to the block and collects the + # result. If obj is not an array, the value is simply yielded to the + # block. + def each_member(obj) + if obj.kind_of?(Array) + obj.collect {|value| yield(value) } + else + yield(obj) + end end - - # Headerizes an underscored string. The input is be converted to - # a string using to_s. - # - # headerize('SOME_STRING') # => 'Some-String' - # headerize('some string') # => 'Some-String' - # headerize('Some-String') # => 'Some-String' - # - def headerize(str) - str.to_s.gsub(/\s|-/, "_").split("_").collect do |s| - s =~ /^(.)(.*)/ - $1.upcase + $2.downcase - end.join("-") - end # Returns the first member of arrays length <= 1, or the array in all - # other cases. Splat is useful to simplify hashes of http headers + # other cases. Splat is useful to simplify hashes of http headers # and parameters that may have multiple values, but typically only # have one. - # + # # splat([]) # => nil # splat([:one]) # => :one # splat([:one, :two]) # => [:one, :two] # def splat(array) @@ -209,9 +180,23 @@ case array.length when 0 then nil when 1 then array.first else array end + end + + # Headerizes an underscored string. The input is be converted to + # a string using to_s. + # + # headerize('SOME_STRING') # => 'Some-String' + # headerize('some string') # => 'Some-String' + # headerize('Some-String') # => 'Some-String' + # + def headerize(str) + str.to_s.gsub(/\s|-/, "_").split("_").collect do |s| + s =~ /^(.)(.*)/ + $1.upcase + $2.downcase + end.join("-") end # Inflates (ie unzips) a gzip string, as may be returned by requests # that accept 'gzip' and 'deflate' content encoding. # \ No newline at end of file