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 +3 -0
- data/Rakefile +26 -0
- data/lib/rack/multipart_related/version.rb +29 -0
- data/lib/rack/multipart_related.rb +66 -0
- data/test/rack/multipart_related_test.rb +70 -0
- data/test/resources/image.png +0 -0
- data/test/test_helper.rb +15 -0
- metadata +137 -0
data/README.md
ADDED
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
|
data/test/test_helper.rb
ADDED
@@ -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
|