lib/riak/util/multipart.rb in riak-client-0.9.0.beta vs lib/riak/util/multipart.rb in riak-client-0.9.0.beta2

- old
+ new

@@ -15,38 +15,52 @@ module Riak module Util # Utility methods for handling multipart/mixed responses module Multipart + autoload :StreamParser, "riak/util/multipart/stream_parser" extend self # Parses a multipart/mixed body into its constituent parts, including nested multipart/mixed sections # @param [String] data the multipart body data # @param [String] boundary the boundary string given in the Content-Type header def parse(data, boundary) - contents = data.match(/\r?\n--#{Regexp.escape(boundary)}--\r?\n/).pre_match rescue "" - contents.split(/\r?\n--#{Regexp.escape(boundary)}\r?\n/).reject(&:blank?).map do |part| - headers = Headers.new - if md = part.match(/\r?\n\r?\n/) - body = md.post_match - md.pre_match.split(/\r?\n/).each do |line| - headers.parse(line) - end - - if headers["content-type"] =~ /multipart\/mixed/ - boundary = extract_boundary(headers.to_hash["content-type"].first) - parse(body, boundary) - else - {:headers => headers.to_hash, :body => body} - end - end + contents = data.match(end_boundary_regex(boundary)).pre_match rescue "" + contents.split(inner_boundary_regex(boundary)).reject(&:blank?).map do |part| + parse_multipart_section(part) end.compact end # Extracts the boundary string from a Content-Type header that is a multipart type # @param [String] header_string the Content-Type header # @return [String] the boundary string separating each part def extract_boundary(header_string) $1 if header_string =~ /boundary=([A-Za-z0-9\'()+_,-.\/:=?]+)/ + end + + private + def end_boundary_regex(boundary) + /\r?\n--#{Regexp.escape(boundary)}--\r?\n/ + end + + def inner_boundary_regex(boundary) + /\r?\n--#{Regexp.escape(boundary)}\r?\n/ + end + + def parse_multipart_section(part) + headers = Headers.new + if md = part.match(/\r?\n\r?\n/) + body = md.post_match + md.pre_match.split(/\r?\n/).each do |line| + headers.parse(line) + end + + if headers["content-type"] =~ /multipart\/mixed/ + boundary = extract_boundary(headers.to_hash["content-type"].first) + parse(body, boundary) + else + {:headers => headers.to_hash, :body => body} + end + end end end end end