tap-http 0.3.1 → 0.3.2

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/History CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.3.2 / 2009-02-23
2
+
3
+ Bug fix in handling of multipart/form data.
4
+
5
+ * parse_rack_request now parses overloaded params
6
+
1
7
  == 0.3.1 / 2009-02-19
2
8
 
3
9
  Improved handling of multipart/form data.
@@ -41,7 +41,7 @@ class CaptureController < Tap::Controller
41
41
  # Echos back redirected HTTP requests formatted as YAML.
42
42
  def echo
43
43
  response['Content-Type'] = "text/plain"
44
- YAML.dump(config)
44
+ YAML.dump(parse_request)
45
45
  end
46
46
 
47
47
  protected
@@ -49,6 +49,17 @@ class CaptureController < Tap::Controller
49
49
  # helper to parse the request into a request hash for
50
50
  # use by a Tap::Http::Submit task
51
51
  def parse_request(keep_content=true) # :nodoc:
52
+
53
+ # perform the actions of Rack::Request::POST, but capturing
54
+ # overloaded parameter names
55
+ env = request.env
56
+ env["rack.request.form_input"] = env["rack.input"]
57
+ unless env["rack.request.form_hash"] = Tap::Http::Utils.parse_multipart(env)
58
+ env["rack.request.form_vars"] = env["rack.input"].read
59
+ env["rack.request.form_hash"] = Rack::Utils.parse_query(env["rack.request.form_vars"])
60
+ env["rack.input"].rewind if env["rack.input"].respond_to?(:rewind)
61
+ end
62
+
52
63
  config = {}
53
64
  parse_rack_request(request, keep_content).each_pair do |key, value|
54
65
  config[key.to_s] = value
@@ -1,6 +1,7 @@
1
1
  autoload(:WEBrick, 'webrick')
2
2
  autoload(:Zlib, 'zlib')
3
3
  autoload(:StringIO, 'stringio')
4
+ require 'rack'
4
5
 
5
6
  module Tap
6
7
  module Http
@@ -137,10 +138,11 @@ module Tap
137
138
  request.params.each_pair do |key, value|
138
139
  params[key] = each_member(value) do |obj|
139
140
  if obj.kind_of?(Hash)
140
- file = {'Content-Type' => value[:type], 'Filename' => value[:filename]}
141
- file['Content'] = value[:tempfile].read if keep_content
141
+ file = {'Content-Type' => obj[:type], 'Filename' => obj[:filename]}
142
+ file['Content'] = obj[:tempfile].read if keep_content
142
143
  file
143
- else value
144
+ else
145
+ obj
144
146
  end
145
147
  end
146
148
  end
@@ -207,6 +209,99 @@ module Tap
207
209
  def inflate(str)
208
210
  Zlib::GzipReader.new( StringIO.new( str ) ).read
209
211
  end
212
+
213
+ EOL = Rack::Utils::Multipart::EOL
214
+ # Lifted from Rack::Utils::Multipart, and modified to collect
215
+ # overloaded params and params with names suffixed by '[]' as
216
+ # arrays.
217
+ def parse_multipart(env)
218
+ unless env['CONTENT_TYPE'] =~
219
+ %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
220
+ nil
221
+ else
222
+ boundary = "--#{$1}"
223
+
224
+ params = {}
225
+ buf = ""
226
+ content_length = env['CONTENT_LENGTH'].to_i
227
+ input = env['rack.input']
228
+
229
+ boundary_size = boundary.size + EOL.size
230
+ bufsize = 16384
231
+
232
+ content_length -= boundary_size
233
+
234
+ status = input.read(boundary_size)
235
+ raise EOFError, "bad content body" unless status == boundary + EOL
236
+
237
+ rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/
238
+
239
+ loop {
240
+ head = nil
241
+ body = ''
242
+ filename = content_type = name = nil
243
+
244
+ until head && buf =~ rx
245
+ if !head && i = buf.index("\r\n\r\n")
246
+ head = buf.slice!(0, i+2) # First \r\n
247
+ buf.slice!(0, 2) # Second \r\n
248
+
249
+ filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
250
+ content_type = head[/Content-Type: (.*)\r\n/ni, 1]
251
+ name = head[/Content-Disposition:.* name="?([^\";]*)"?/ni, 1]
252
+
253
+ if filename
254
+ body = Tempfile.new("RackMultipart")
255
+ body.binmode if body.respond_to?(:binmode)
256
+ end
257
+
258
+ next
259
+ end
260
+
261
+ # Save the read body part.
262
+ if head && (boundary_size+4 < buf.size)
263
+ body << buf.slice!(0, buf.size - (boundary_size+4))
264
+ end
265
+
266
+ c = input.read(bufsize < content_length ? bufsize : content_length)
267
+ raise EOFError, "bad content body" if c.nil? || c.empty?
268
+ buf << c
269
+ content_length -= c.size
270
+ end
271
+
272
+ # Save the rest.
273
+ if i = buf.index(rx)
274
+ body << buf.slice!(0, i)
275
+ buf.slice!(0, boundary_size+2)
276
+
277
+ content_length = -1 if $1 == "--"
278
+ end
279
+
280
+ if filename
281
+ body.rewind
282
+ data = {:filename => filename, :type => content_type,
283
+ :name => name, :tempfile => body, :head => head}
284
+ else
285
+ data = body
286
+ end
287
+
288
+ if name
289
+ case current = params[name]
290
+ when nil
291
+ params[name] = (name =~ /\[\]\z/ ? [data] : data)
292
+ when Array
293
+ params[name] << data
294
+ else
295
+ params[name] = [current, data]
296
+ end
297
+ end
298
+
299
+ break if buf.empty? || content_length == -1
300
+ }
301
+
302
+ params
303
+ end
304
+ end
210
305
  end
211
306
  end
212
307
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tap-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Chiang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-19 00:00:00 -07:00
12
+ date: 2009-02-23 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.12.0
23
+ version: 0.12.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rack