MultipartParser
A c backed multipart/form-data parser.
Ruby extenstion for https://github.com/iafonov/multipart-parser-c, modeled after http_parser.rb
Multipart-parser C has been modfied to have a more consistent callback structure with http_parser.rb
Installation
Add this line to your application's Gemfile:
gem 'multipart_parser'
And then execute:
$ bundle
Or install it yourself as:
$ gem install multipart_parser
Usage
require 'multipart_parser'
parser = MultipartParser.new("Boundary+17376C87E2579930")
# Setups callbacks
parser. = proc { puts "# => on_message_begin"}
parser.on_part_begin = proc { puts "# => on_part_begin"}
parser.on_headers_complete = proc {|headers| puts "# => on_headers_complete: #{headers.inspect}"}
parser.on_data = proc {|data| puts "# => on_data: #{data}"}
parser.on_part_complete = proc {puts "# => on_part_complete"}
parser. = proc {puts "# => on_message_complete"}
parser << "--Boundary+17376C87E2579930\r\n"
# => on_message_begin
# => on_part_begin
parser << "Content-Disposition: form-data; name=ID1\r\n"
parser << "Content-Type: text/plain\r\n\r\n"
parser << "This is the first part.\r\n"
# => on_headers_complete: {"Content-Disposition"=>"form-data; name=ID1", "Content-Type"=>"text/plain"}
# => on_data: This is the first part.
parser << "--Boundary+17376C87E2579930\r\n"
# => on_part_complete
# => on_part_begin
# =>
parser << "Content-Disposition: form-data; name=ID2\r\n"
parser << "Content-Type: text/plain\r\n\r\n"
parser << "This is the second part.\r\n";
parser << "--Boundary+17376C87E2579930--\r\n"
# => on_headers_complete: {"Content-Disposition"=>"form-data; name=ID2", "Content-Type"=>"text/plain"}
# => on_data: This is the second part.
# => on_part_complete
# => on_message_complete
# Also allows you to pass a callback object
class Handler
def ; puts "# => on_message_begin"; end
def on_part_begin; puts "# => on_part_begin"; end
def on_headers_complete(headers); puts "# => on_headers_complete: #{headers.inspect}"; end
def on_data(data); puts "# => on_data: #{data}"; end
def on_part_complete; puts "# => on_part_complete"; end
def ; puts "# => on_message_complete"; end
end
parser = MultipartParser.new("Boundary+17376C87E2579930", Handler.new)
parser << "--Boundary+17376C87E2579930\r\n"
# => on_message_begin
# => on_part_begin
parser << "Content-Disposition: form-data; name=ID1\r\n"
parser << "Content-Type: text/plain\r\n\r\n"
parser << "This is the first part.\r\n"
# => on_headers_complete: {"Content-Disposition"=>"form-data; name=ID1", "Content-Type"=>"text/plain"}
# => on_data: This is the first part.
parser << "--Boundary+17376C87E2579930\r\n"
# => on_part_complete
# => on_part_begin
parser << "Content-Disposition: form-data; name=ID2\r\n"
parser << "Content-Type: text/plain\r\n\r\n"
parser << "This is the second part.\r\n";
parser << "--Boundary+17376C87E2579930--\r\n"
# => on_headers_complete: {"Content-Disposition"=>"form-data; name=ID2", "Content-Type"=>"text/plain"}
# => on_data: This is the second part.
# => on_part_complete
# => on_message_complete
# Accepts a config paramter to modify how the headers are returned
parser = MultipartParser.new("Boundary+17376C87E2579930", Handler.new, :arrays)
# valid values are :arrays, :strings, :mixed
parser << "--Boundary+17376C87E2579930\r\n"
parser << "Content-Disposition: form-data; name=ID_A\r\n"
parser << "Content-Disposition: form-data; name=ID_B\r\n"
parser << "Content-Type: text/plain\r\n\r\n"
parser << "This is the first part.\r\n"
# => on_headers_complete: {"Content-Disposition"=>["form-data; name=ID_A", "form-data; name=ID_B"], "Content-Type"=>["text/plain"]}
parser = MultipartParser.new("Boundary+17376C87E2579930", Handler.new, :strings)
# => on_headers_complete: {"Content-Disposition"=>"form-data; name=ID_A, form-data; name=ID_B", "Content-Type"=>"text/plain"}
parser = MultipartParser.new("Boundary+17376C87E2579930", Handler.new, :mixed)
# => on_headers_complete: {"Content-Disposition"=>["form-data; name=ID_A", "form-data; name=ID_B"], "Content-Type"=>"text/plain"}
# Set the default(:mixed)
MultipartParser.default_header_value_type = :arrays
parser = MultipartParser.new("Boundary+17376C87E2579930", Handler.new)
# => on_headers_complete: {"Content-Disposition"=>["form-data; name=ID_A", "form-data; name=ID_B"], "Content-Type"=>["text/plain"]}
Contributing
- Fork it ( https://github.com/[my-github-username]/multipart_parser/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request