rack-raw-upload 1.0.11 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ group :development, :test do
6
6
  gem 'rake'
7
7
  gem 'rack-test'
8
8
  gem 'shoulda'
9
+ gem 'rr'
9
10
  end
@@ -7,6 +7,7 @@ GEM
7
7
  rack-test (0.5.6)
8
8
  rack (>= 1.0)
9
9
  rake (0.8.7)
10
+ rr (1.0.4)
10
11
  shoulda (2.11.3)
11
12
 
12
13
  PLATFORMS
@@ -17,4 +18,5 @@ DEPENDENCIES
17
18
  json
18
19
  rack-test
19
20
  rake
21
+ rr
20
22
  shoulda
data/README.md CHANGED
@@ -1,17 +1,23 @@
1
+ # WARNING: you may not need this
2
+
3
+ If you want to use this because you are performing HTML5 file uploads, you may be doing it [the "old way"](http://blog.new-bamboo.co.uk/2010/7/30/html5-powered-ajax-file-uploads).
4
+
5
+ There is a "new", [better way of doing this](http://blog.new-bamboo.co.uk/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata). It may be a better solution for your problems.
6
+
7
+ However, if this is not the case, please read on. I hope you find this middleware useful.
8
+
1
9
  # Rack Raw Upload middleware
2
10
 
3
11
  Rack::RawUpload converts raw uploads into normal multipart requests, like those in a form. Rack applications can then read these as normal (using `params` for example), rather than from `env['rack.input']` or similar.
4
12
 
5
- Rack::RawUpload processes a request this way when the mimetype **is not** one of the following:
6
-
7
13
  ## Assumptions
8
14
 
9
15
  Rack::RawUpload performs this conversion when all these conditions are met:
10
16
 
11
17
  1. The request method is POST or PUT
12
18
  2. The mimetype is one of
13
- * application/x-www-form-urlencoded
14
- * multipart/form-data
19
+ * `application/x-www-form-urlencoded`
20
+ * `multipart/form-data`
15
21
  3. The Content-Length is greater than 0
16
22
 
17
23
  ## Configuration
@@ -53,7 +59,10 @@ The upload is made into a request argument called `file`. In several popular fra
53
59
  Raw uploads, due to their own nature, can't provide additional arguments in the request. This limitation can be worked around using headers.
54
60
 
55
61
  * `X-File-Name`: specify the name of the uploaded file.
56
- * `X-Query-Params`: JSON-formatted hash containing additional arguments. On Rails or Sinatra, you can read these as `params[:name_of_argument]`
62
+ * `X-File-Upload`: explicitly tells whether to perform the conversion or not. Possible values are 'true' (string), 'false' (string) or 'smart'. Default is 'smart', unless the middleware is initialized with `:explicit => true`, in which case default is 'false'.
63
+ * `X-Params`: query string with additional arguments. On Rails or Sinatra, you can read these as `params[:name_of_argument]`.
64
+ * `X-JSON-Params`: same thing, but in the form of a JSON string.
65
+ * `X-Query-Params`: **deprecated**. Equivalent to `X-JSON-Params`. Will be removed in future versions.
57
66
 
58
67
 
59
68
  ## Additional info
@@ -3,7 +3,7 @@ require 'tmpdir' # Needed in 1.8.7 to access Dir::tmpdir
3
3
  module Rack
4
4
  class RawUpload
5
5
 
6
- VERSION = '1.0.11'
6
+ VERSION = '1.1.0'
7
7
 
8
8
  def initialize(app, opts = {})
9
9
  @app = app
@@ -57,11 +57,15 @@ module Rack
57
57
  env['rack.request.query_hash'] ||= {}
58
58
  env['rack.request.form_hash']['file'] = fake_file
59
59
  env['rack.request.query_hash']['file'] = fake_file
60
- if query_params = env['HTTP_X_QUERY_PARAMS']
61
- require 'json'
62
- params = JSON.parse(query_params)
63
- env['rack.request.form_hash'].merge!(params)
64
- env['rack.request.query_hash'].merge!(params)
60
+ if env['HTTP_X_QUERY_PARAMS']
61
+ env['rack.errors'].puts("Warning! The header X-Query-Params is deprecated. Please use X-JSON-Params instead.")
62
+ inject_json_params!(env, env['HTTP_X_QUERY_PARAMS'])
63
+ end
64
+ if env['HTTP_X_JSON_PARAMS']
65
+ inject_json_params!(env, env['HTTP_X_JSON_PARAMS'])
66
+ end
67
+ if env['HTTP_X_PARAMS']
68
+ inject_query_params!(env, env['HTTP_X_PARAMS'])
65
69
  end
66
70
  @app.call(env)
67
71
  end
@@ -101,6 +105,19 @@ module Rack
101
105
  def random_string
102
106
  (0...8).map{65.+(rand(25)).chr}.join
103
107
  end
108
+
109
+ def inject_json_params!(env, params)
110
+ require 'json'
111
+ hsh = JSON.parse(params)
112
+ env['rack.request.form_hash'].merge!(hsh)
113
+ env['rack.request.query_hash'].merge!(hsh)
114
+ end
115
+
116
+ def inject_query_params!(env, params)
117
+ hsh = Rack::Utils.parse_query(params)
118
+ env['rack.request.form_hash'].merge!(hsh)
119
+ env['rack.request.query_hash'].merge!(hsh)
120
+ end
104
121
  end
105
122
 
106
123
 
@@ -0,0 +1,4 @@
1
+ APP_ROOT = File.dirname(File.expand_path(__FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'simple_app'
@@ -0,0 +1,17 @@
1
+ require 'pp'
2
+ require 'sinatra/base'
3
+
4
+ class SimpleApp < Sinatra::Base
5
+
6
+ set :root, APP_ROOT
7
+ set :static, true
8
+
9
+ get '/' do
10
+ erb :index
11
+ end
12
+
13
+ post '/' do
14
+ Rack::Utils.escape_html(PP.pp(params, ''))
15
+ end
16
+
17
+ end
@@ -0,0 +1,44 @@
1
+ require 'httparty'
2
+
3
+ class TflCountdown
4
+ include HTTParty
5
+ base_uri 'http://countdown.tfl.gov.uk'
6
+
7
+ def initialize(status = {})
8
+ @cookies = status['cookies'] if status['cookies']
9
+ end
10
+
11
+ def search(q)
12
+ get_json('/search', 'searchTerm' => q)
13
+ end
14
+
15
+ def markers(swlat, swlng, nelat, nelng)
16
+ path = "/markers/swLat/#{swlat}/swLng/#{swlng}/neLat/#{nelat}/neLng/#{nelng}/"
17
+ get_json(path)
18
+ end
19
+
20
+
21
+ def get_json(path, query = {})
22
+ query_params = {
23
+ '_dc' => Time.now.to_i,
24
+ }.merge(query)
25
+
26
+ headers = {
27
+ 'X-Requested-With' => 'XMLHttpRequest',
28
+ 'Referer' => 'http://countdown.tfl.gov.uk/',
29
+ 'User-Agent' => 'Pablito\'s own',
30
+ }
31
+ headers['Cookie'] = @cookies if @cookies
32
+
33
+ res = self.class.get(path, :query => query_params, :headers => headers, :format => :json)
34
+ @cookies = res.headers['set-cookie']
35
+ res.body
36
+ end
37
+
38
+ def to_hash
39
+ ret = {}
40
+ ret['cookies'] = @cookies if @cookies
41
+ ret
42
+ end
43
+
44
+ end
@@ -4,9 +4,11 @@ require 'shoulda'
4
4
  require 'rack-raw-upload'
5
5
  require 'json'
6
6
  require 'digest'
7
+ require 'rr'
7
8
 
8
9
  class RawUploadTest < Test::Unit::TestCase
9
10
  include Rack::Test::Methods
11
+ include RR::Adapters::TestUnit
10
12
 
11
13
  def app
12
14
  opts = @middleware_opts
@@ -79,9 +81,7 @@ class RawUploadTest < Test::Unit::TestCase
79
81
  should "not work when there is no input" do
80
82
  upload('rack.input' => '')
81
83
  assert_successful_non_upload
82
- end
83
84
 
84
- should "not work when there is no input" do
85
85
  upload('rack.input' => StringIO.new(''))
86
86
  assert_successful_non_upload
87
87
  end
@@ -196,9 +196,9 @@ class RawUploadTest < Test::Unit::TestCase
196
196
  end
197
197
  end
198
198
 
199
- context "with query parameters" do
199
+ context "with JSON parameters" do
200
200
  setup do
201
- upload('HTTP_X_QUERY_PARAMS' => JSON.generate({
201
+ upload('HTTP_X_JSON_PARAMS' => JSON.generate({
202
202
  :argument => 'value1',
203
203
  'argument with spaces' => 'value 2'
204
204
  }))
@@ -210,6 +210,43 @@ class RawUploadTest < Test::Unit::TestCase
210
210
  end
211
211
  end
212
212
 
213
+ context "with query parameters" do
214
+ setup do
215
+ upload('HTTP_X_PARAMS' => "arg=val1&ar+g=val2")
216
+ end
217
+
218
+ should "convert these into arguments" do
219
+ assert_equal last_request.POST['arg'], 'val1'
220
+ assert_equal last_request.POST['ar g'], 'val2'
221
+ end
222
+ end
223
+
224
+ context "with query parameters, deprecated style" do
225
+ setup do
226
+ json_params = JSON.generate({
227
+ :argument => 'value1',
228
+ 'argument with spaces' => 'value 2'
229
+ })
230
+ @mock_error_stream = obj = Object.new
231
+ stub(obj).puts
232
+ stub(obj).flush
233
+
234
+ upload({
235
+ 'HTTP_X_QUERY_PARAMS' => json_params,
236
+ 'rack.errors' => @mock_error_stream
237
+ })
238
+ end
239
+
240
+ should "convert these into arguments" do
241
+ assert_equal last_request.POST['argument'], 'value1'
242
+ assert_equal last_request.POST['argument with spaces'], 'value 2'
243
+ end
244
+
245
+ should "give a deprecation warning" do
246
+ assert_received(@mock_error_stream) {|subject| subject.puts(is_a(String)) }
247
+ end
248
+ end
249
+
213
250
  context "with filename" do
214
251
  setup do
215
252
  upload('HTTP_X_FILE_NAME' => @filename)
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-raw-upload
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 1
7
+ - 1
8
8
  - 0
9
- - 11
10
- version: 1.0.11
9
+ version: 1.1.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Pablo Brasero
@@ -15,17 +14,16 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-11-23 00:00:00 Z
17
+ date: 2012-04-24 00:00:00 +01:00
18
+ default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
24
  requirements:
26
25
  - - ">="
27
26
  - !ruby/object:Gem::Version
28
- hash: 3
29
27
  segments:
30
28
  - 0
31
29
  version: "0"
@@ -35,11 +33,9 @@ dependencies:
35
33
  name: rake
36
34
  prerelease: false
37
35
  requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
36
  requirements:
40
37
  - - ">="
41
38
  - !ruby/object:Gem::Version
42
- hash: 3
43
39
  segments:
44
40
  - 0
45
41
  version: "0"
@@ -49,11 +45,9 @@ dependencies:
49
45
  name: rack-test
50
46
  prerelease: false
51
47
  requirement: &id003 !ruby/object:Gem::Requirement
52
- none: false
53
48
  requirements:
54
49
  - - ">="
55
50
  - !ruby/object:Gem::Version
56
- hash: 3
57
51
  segments:
58
52
  - 0
59
53
  version: "0"
@@ -63,11 +57,9 @@ dependencies:
63
57
  name: shoulda
64
58
  prerelease: false
65
59
  requirement: &id004 !ruby/object:Gem::Requirement
66
- none: false
67
60
  requirements:
68
61
  - - ">="
69
62
  - !ruby/object:Gem::Version
70
- hash: 3
71
63
  segments:
72
64
  - 0
73
65
  version: "0"
@@ -85,6 +77,9 @@ extra_rdoc_files:
85
77
  files:
86
78
  - lib/rack/raw_upload.rb
87
79
  - lib/rack-raw-upload.rb
80
+ - test/apps/example/app.rb
81
+ - test/apps/example/lib/simple_app.rb
82
+ - test/apps/example/lib/tfl_countdown.rb
88
83
  - test/apps/undefined_conversion_error/app/controllers/application_controller.rb
89
84
  - test/apps/undefined_conversion_error/app/controllers/test_controller.rb
90
85
  - test/apps/undefined_conversion_error/app/helpers/application_helper.rb
@@ -109,6 +104,7 @@ files:
109
104
  - README.md
110
105
  - Gemfile
111
106
  - Gemfile.lock
107
+ has_rdoc: true
112
108
  homepage: https://github.com/newbamboo/rack-raw-upload
113
109
  licenses: []
114
110
 
@@ -120,31 +116,26 @@ rdoc_options:
120
116
  require_paths:
121
117
  - lib
122
118
  required_ruby_version: !ruby/object:Gem::Requirement
123
- none: false
124
119
  requirements:
125
120
  - - ">="
126
121
  - !ruby/object:Gem::Version
127
- hash: 3
128
122
  segments:
129
123
  - 0
130
124
  version: "0"
131
125
  required_rubygems_version: !ruby/object:Gem::Requirement
132
- none: false
133
126
  requirements:
134
127
  - - ">="
135
128
  - !ruby/object:Gem::Version
136
- hash: 3
137
129
  segments:
138
130
  - 0
139
131
  version: "0"
140
132
  requirements: []
141
133
 
142
134
  rubyforge_project:
143
- rubygems_version: 1.8.10
135
+ rubygems_version: 1.3.6
144
136
  signing_key:
145
137
  specification_version: 3
146
138
  summary: Rack Raw Upload middleware
147
139
  test_files:
148
140
  - test/apps/undefined_conversion_error/app/controllers/test_controller.rb
149
141
  - test/apps/undefined_conversion_error/test/test_helper.rb
150
- has_rdoc: