rack-multipart_related 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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