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