rack-multipart_related 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Rack multipart/related middleware
2
+
3
+ Rack::MultipartRelated it's a rack middleware to parse multipart/related requests and rebuild a simple/merged parameters hash.
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'rake/testtask'
2
+
3
+ task :default => :test
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/**/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ desc "Build the gem"
11
+ task :build do
12
+ opers = Dir.glob('*.gem')
13
+ opers = ["rm #{ opers.join(' ') }"] unless opers.empty?
14
+ opers << ["gem build rack-multipart_related.gemspec"]
15
+ sh opers.join(" && ")
16
+ end
17
+
18
+ desc "Build and install the gem, removing old installation"
19
+ task :install => :build do
20
+ gem = Dir.glob('*.gem').first
21
+ if gem.nil?
22
+ puts "could not install the gem"
23
+ else
24
+ sh "gem uninstall rack-multipart_related; gem install #{ gem }"
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ module Rack
2
+ class MultipartRelated
3
+ path = File.expand_path('../../..', __FILE__)
4
+ v = nil
5
+ v = $1 if path =~ /\/rack-multipart_related-([\w\.\-]+)/
6
+ if v.nil?
7
+ $:.each do |path|
8
+ if path =~ /\/rack-multipart_related-([\w\.\-]+)/
9
+ v = $1
10
+ break
11
+ end
12
+ end
13
+ end
14
+ if v.nil?
15
+ path = File.expand_path('../../../../.git', __FILE__)
16
+ if File.exists?(path)
17
+ require "step-up"
18
+ v = StepUp::Driver::Git.last_version
19
+ end
20
+ end
21
+ if v.nil?
22
+ VERSION = "0.0.0"
23
+ else
24
+ v.sub!(/^v/, '')
25
+ v.sub!(/\+\d*$/, '')
26
+ VERSION = v
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ require 'json'
2
+
3
+ module Rack
4
+ class MultipartRelated
5
+ autoload :VERSION, 'rack/multipart_related/version.rb'
6
+
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ content_type = env['CONTENT_TYPE']
13
+
14
+ if content_type =~ /^multipart\/related/
15
+
16
+ start_part = content_type[/.* start=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni, 1]
17
+ start_part_type = content_type[/.* type=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni, 1]
18
+
19
+ if start_part_type == "application/json"
20
+
21
+ params = env["rack.request.form_hash"]
22
+ json_data = ::JSON.parse(get_attribute(params, start_part)[:tempfile].read)
23
+
24
+ new_params = handle_atributtes_with_part_refs(json_data, params)
25
+ env["rack.request.form_hash"] = new_params
26
+ end
27
+ end
28
+
29
+ @app.call(env)
30
+ end
31
+
32
+ private
33
+ def get_attribute(hash, attributes)
34
+ attributes = attributes.scan(/[^\[\]]+/) if attributes.is_a?(String)
35
+ attribute = attributes.shift
36
+ value = attribute.nil? ? nil : hash[attribute]
37
+
38
+ if value.is_a?(Hash) && ! attributes.empty?
39
+ get_attribute(value, attributes)
40
+ else
41
+ value
42
+ end
43
+ end
44
+
45
+ def handle_atributtes_with_part_refs(data, original_params)
46
+
47
+ if data.kind_of?(String)
48
+ part_ref = data[/^cid:(.+)$/ni, 1]
49
+
50
+ if part_ref
51
+ data = get_attribute(original_params, part_ref)[:tempfile]
52
+ end
53
+ elsif data.kind_of?(Array)
54
+ data.each_with_index do |value, index|
55
+ data[index] = handle_atributtes_with_part_refs(value, original_params)
56
+ end
57
+ elsif data.kind_of?(Hash)
58
+ data.each do |key, value|
59
+ data[key] = handle_atributtes_with_part_refs(value, original_params)
60
+ end
61
+ end
62
+
63
+ data
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
2
+
3
+ class MultipartRelatedTest < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ Rack::Builder.new do
8
+ use Rack::MultipartRelated
9
+ run Proc.new { |env| [200, {'Content-Type' => 'text/html'}, ['success']] }
10
+ end
11
+ end
12
+
13
+ def imagefile
14
+ @image_file ||= File.open(File.expand_path(File.dirname(__FILE__) + '/../resources/image.png'))
15
+ end
16
+
17
+ def make_tempfile(name, text)
18
+ tempfile = Tempfile.new(name)
19
+ tempfile.puts(text)
20
+ tempfile.rewind
21
+ tempfile
22
+ end
23
+
24
+ def test_request_without_multipart_related
25
+ get "/"
26
+
27
+ assert_equal "http://example.org/", last_request.url
28
+ assert last_response.ok?
29
+ end
30
+
31
+ def test_mutlipart_related_with_correct_json
32
+
33
+ jsonfile = make_tempfile("json", '{"user": {"name": "Jhon", "avatar": "cid:avatar_image"} }')
34
+
35
+ request_form_hash = {
36
+ "json" => {
37
+ :type => "application/json; charset=UTF-8",
38
+ :tempfile => jsonfile,
39
+ :head => "Content-Type: application/json; charset=UTF-8\r\nContent-Disposition: inline; name=\"json\"\r\n",
40
+ :name => "json"
41
+ },
42
+ "avatar_image" => {
43
+ :type => "image/png",
44
+ :filename =>"image.png",
45
+ :tempfile => imagefile,
46
+ :head => "Content-Type: image/gif\r\nContent-Disposition: inline; name=\"avatar_image\"; filename=\"image.png\"\r\n",
47
+ :name =>"avatar_image"
48
+ }
49
+ }
50
+
51
+ expected_request_form_hash_after_middleware = {
52
+ "user" => {
53
+ "name" => "Jhon",
54
+ "avatar" => imagefile
55
+ }
56
+ }
57
+
58
+ env = {
59
+ 'REQUEST_METHOD' => 'POST',
60
+ 'CONTENT_TYPE' => 'multipart/related; boundary="the_boundary"; type="application/json"; start="json"',
61
+ 'PATH_INFO' => '/some/path',
62
+ 'rack.request.form_hash' => request_form_hash
63
+ }
64
+
65
+ request(env['PATH_INFO'], env)
66
+
67
+ assert last_response.ok?
68
+ assert_equal last_request.env["rack.request.form_hash"], expected_request_form_hash_after_middleware
69
+ end
70
+ end
Binary file
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'rack/test'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'rack/multipart_related'
8
+
9
+ begin
10
+ require "redgreen"
11
+ require "ruby-debug"
12
+ rescue LoadError
13
+ # Not required gems.
14
+ end
15
+
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-multipart_related
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Lucas Fais
14
+ - Marcelo Manzan
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-12-17 00:00:00 -02:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: rack
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 15
31
+ segments:
32
+ - 1
33
+ - 0
34
+ version: "1.0"
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 1
48
+ - 0
49
+ version: "1.0"
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: step-up
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ type: :development
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: mocha
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ type: :development
79
+ version_requirements: *id004
80
+ description: It's a rack middleware to parse multipart/related requests and rebuild a simple/merged parameters hash.
81
+ email:
82
+ - lucasfais@gmail.com
83
+ - manzan@gmail.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files: []
89
+
90
+ files:
91
+ - README.md
92
+ - Rakefile
93
+ - lib/rack/multipart_related.rb
94
+ - lib/rack/multipart_related/version.rb
95
+ - test/rack/multipart_related_test.rb
96
+ - test/resources/image.png
97
+ - test/test_helper.rb
98
+ has_rdoc: true
99
+ homepage: https://github.com/lucasfais/rack-multipart_related
100
+ licenses: []
101
+
102
+ post_install_message:
103
+ rdoc_options: []
104
+
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ hash: 3
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: 23
122
+ segments:
123
+ - 1
124
+ - 3
125
+ - 6
126
+ version: 1.3.6
127
+ requirements: []
128
+
129
+ rubyforge_project: rack-multipart_related
130
+ rubygems_version: 1.3.7
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Makes easy to handle mutipart/related requests.
134
+ test_files:
135
+ - test/rack/multipart_related_test.rb
136
+ - test/resources/image.png
137
+ - test/test_helper.rb