merb-core 0.9.8 → 0.9.9

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.
Files changed (57) hide show
  1. data/CONTRIBUTORS +33 -0
  2. data/README +7 -3
  3. data/Rakefile +3 -3
  4. data/lib/merb-core.rb +165 -94
  5. data/lib/merb-core/bootloader.rb +469 -100
  6. data/lib/merb-core/config.rb +79 -3
  7. data/lib/merb-core/constants.rb +24 -2
  8. data/lib/merb-core/controller/abstract_controller.rb +172 -67
  9. data/lib/merb-core/controller/exceptions.rb +50 -6
  10. data/lib/merb-core/controller/merb_controller.rb +215 -108
  11. data/lib/merb-core/controller/mime.rb +36 -12
  12. data/lib/merb-core/controller/mixins/authentication.rb +52 -7
  13. data/lib/merb-core/controller/mixins/conditional_get.rb +14 -0
  14. data/lib/merb-core/controller/mixins/controller.rb +90 -58
  15. data/lib/merb-core/controller/mixins/render.rb +34 -10
  16. data/lib/merb-core/controller/mixins/responder.rb +40 -16
  17. data/lib/merb-core/controller/template.rb +37 -16
  18. data/lib/merb-core/core_ext/hash.rb +9 -0
  19. data/lib/merb-core/core_ext/kernel.rb +92 -41
  20. data/lib/merb-core/dispatch/dispatcher.rb +29 -45
  21. data/lib/merb-core/dispatch/request.rb +186 -82
  22. data/lib/merb-core/dispatch/router.rb +141 -53
  23. data/lib/merb-core/dispatch/router/behavior.rb +296 -139
  24. data/lib/merb-core/dispatch/router/resources.rb +51 -19
  25. data/lib/merb-core/dispatch/router/route.rb +76 -23
  26. data/lib/merb-core/dispatch/session.rb +80 -36
  27. data/lib/merb-core/dispatch/session/container.rb +31 -15
  28. data/lib/merb-core/dispatch/session/cookie.rb +51 -22
  29. data/lib/merb-core/dispatch/session/memcached.rb +10 -6
  30. data/lib/merb-core/dispatch/session/memory.rb +17 -5
  31. data/lib/merb-core/dispatch/session/store_container.rb +21 -9
  32. data/lib/merb-core/dispatch/worker.rb +16 -2
  33. data/lib/merb-core/gem_ext/erubis.rb +4 -0
  34. data/lib/merb-core/plugins.rb +13 -0
  35. data/lib/merb-core/rack.rb +1 -0
  36. data/lib/merb-core/rack/adapter.rb +1 -0
  37. data/lib/merb-core/rack/adapter/abstract.rb +95 -17
  38. data/lib/merb-core/rack/adapter/irb.rb +50 -5
  39. data/lib/merb-core/rack/application.rb +27 -5
  40. data/lib/merb-core/rack/handler/mongrel.rb +6 -6
  41. data/lib/merb-core/rack/helpers.rb +33 -0
  42. data/lib/merb-core/rack/middleware/conditional_get.rb +1 -1
  43. data/lib/merb-core/rack/middleware/path_prefix.rb +3 -3
  44. data/lib/merb-core/rack/middleware/static.rb +11 -7
  45. data/lib/merb-core/server.rb +134 -69
  46. data/lib/merb-core/tasks/gem_management.rb +153 -80
  47. data/lib/merb-core/tasks/merb_rake_helper.rb +12 -4
  48. data/lib/merb-core/tasks/stats.rake +1 -1
  49. data/lib/merb-core/test/helpers/mock_request_helper.rb +29 -22
  50. data/lib/merb-core/test/helpers/request_helper.rb +1 -1
  51. data/lib/merb-core/test/helpers/route_helper.rb +50 -4
  52. data/lib/merb-core/test/matchers/request_matchers.rb +2 -36
  53. data/lib/merb-core/test/matchers/view_matchers.rb +32 -22
  54. data/lib/merb-core/test/run_specs.rb +6 -5
  55. data/lib/merb-core/test/test_ext/rspec.rb +6 -19
  56. data/lib/merb-core/version.rb +1 -1
  57. metadata +5 -4
@@ -25,16 +25,26 @@ module Merb
25
25
  self.http_method_overrides = []
26
26
 
27
27
  # Initialize the request object.
28
- #
28
+ #
29
29
  # ==== Parameters
30
30
  # http_request<~params:~[], ~body:IO>::
31
31
  # An object like an HTTP Request.
32
+ #
33
+ # @api private
32
34
  def initialize(rack_env)
33
35
  @env = rack_env
34
36
  @body = rack_env['rack.input']
35
37
  @route_params = {}
36
38
  end
37
39
 
40
+ # Returns the controller object for initialization and dispatching the
41
+ # request.
42
+ #
43
+ # ==== Returns
44
+ # Class:: The controller class matching the routed request,
45
+ # e.g. Posts.
46
+ #
47
+ # @api private
38
48
  def controller
39
49
  unless params[:controller]
40
50
  raise ControllerExceptions::NotFound,
@@ -58,13 +68,15 @@ module Merb
58
68
  METHODS = %w{get post put delete head options}
59
69
 
60
70
  # ==== Returns
61
- # <Symbol>:: The name of the request method, e.g. :get.
71
+ # Symbol:: The name of the request method, e.g. :get.
62
72
  #
63
73
  # ==== Notes
64
74
  # If the method is post, then the blocks specified in
65
75
  # http_method_overrides will be checked for the masquerading method.
66
76
  # The block will get the controller yielded to it. The first matching workaround wins.
67
77
  # To disable this behavior, set http_method_overrides = []
78
+ #
79
+ # @api public
68
80
  def method
69
81
  @method ||= begin
70
82
  request_method = @env['REQUEST_METHOD'].downcase.to_sym
@@ -89,86 +101,83 @@ module Merb
89
101
  METHODS.each do |m|
90
102
  class_eval "def #{m}?() method == :#{m} end"
91
103
  end
92
-
104
+
105
+ # ==== Notes
93
106
  # Find route using requested URI and merges route
94
107
  # parameters (:action, :controller and named segments)
95
108
  # into request params hash.
109
+ #
110
+ # @api private
96
111
  def find_route!
97
112
  @route, @route_params = Merb::Router.route_for(self)
98
- params.merge! @route_params
113
+ params.merge! @route_params if @route_params.is_a?(Hash)
99
114
  end
100
115
 
116
+ # ==== Notes
101
117
  # Processes the return value of a deferred router block
102
118
  # and returns the current route params for the current
103
119
  # request evaluation
104
- # ---
105
- # @private
120
+ #
121
+ # @api private
106
122
  def _process_block_return(retval)
107
123
  # If the return value is an array, then it is a redirect
108
124
  # so we must set the request as a redirect and extract
109
125
  # the redirect params and return it as a hash so that the
110
126
  # dispatcher can handle it
111
- if retval.is_a?(Array)
112
- redirects!
113
- return { :url => retval[0], :status => retval[1] }
114
- end
127
+ matched! if retval.is_a?(Array)
115
128
  retval
116
129
  end
117
130
 
118
- # Sets the request as a redirect. This method is only really
119
- # used in the router to tell the request object how to handle
120
- # the route params. This will also set the request as matched.
121
- # ---
122
- # @private
123
- def redirects!
124
- @matched = true
125
- @redirects = true
126
- end
127
-
128
131
  # Sets the request as matched. This will abort evaluating any
129
132
  # further deferred procs.
130
- # ---
131
- # @private
133
+ #
134
+ # @api private
132
135
  def matched!
133
136
  @matched = true
134
137
  end
135
138
 
136
139
  # Checks whether or not the request has been matched to a route.
137
- # ---
138
- # @private
140
+ #
141
+ # @api private
139
142
  def matched?
140
143
  @matched
141
144
  end
142
-
143
- # Redirect status of route matched this request.
144
- #
145
- # ==== Returns
146
- # Integer::
147
- # The URL to redirect to if the route redirects
148
- def redirect_status
149
- @route_params[:status] if redirects?
150
- end
151
-
152
- # Returns redirect url of route matched this request.
153
- #
145
+
154
146
  # ==== Returns
155
- # <String>:: redirect url of route matched this request
156
- def redirect_url
157
- @route_params[:url] if redirects?
147
+ # (Array, Hash):: the route params for the matched route.
148
+ #
149
+ # ==== Notes
150
+ # If the response is an Array then it is considered a direct Rack response
151
+ # to be sent back as a response. Otherwise, the route_params is a Hash with
152
+ # routing data (controller, action, et al).
153
+ #
154
+ # @api private
155
+ def rack_response
156
+ @route_params
158
157
  end
159
-
160
- # Returns true if matched route does immediate redirection.
161
- #
158
+
159
+ # If @route_params is an Array, then it will be the rack response.
160
+ # In this case, the request is considered handled.
161
+ #
162
162
  # ==== Returns
163
- # <Boolean>:: if matched route does immediate redirection.
164
- def redirects?
165
- @redirects
163
+ # Boolean:: true if @route_params is an Array, false otherwise.
164
+ #
165
+ # @api private
166
+ def handled?
167
+ @route_params.is_a?(Array)
166
168
  end
167
169
 
170
+ # == Params
171
+ #
172
+ # Handles processing params from raw data and merging them together to get
173
+ # the final request params.
174
+
168
175
  private
169
176
 
170
177
  # ==== Returns
171
178
  # Hash:: Parameters passed from the URL like ?blah=hello.
179
+ #
180
+ # @api private
172
181
  def query_params
173
182
  @query_params ||= self.class.query_parse(query_string || '')
174
183
  end
@@ -178,6 +187,8 @@ module Merb
178
187
  #
179
188
  # ==== Returns
180
189
  # Hash:: The parameters passed in the body.
190
+ #
191
+ # @api private
181
192
  def body_params
182
193
  @body_params ||= begin
183
194
  if content_type && content_type.match(Merb::Const::FORM_URL_ENCODED_REGEXP) # or content_type.nil?
@@ -185,11 +196,13 @@ module Merb
185
196
  end
186
197
  end
187
198
  end
188
-
199
+
189
200
  # ==== Returns
190
201
  # Mash::
191
202
  # The parameters gathered from the query string and the request body,
192
203
  # with parameters in the body taking precedence.
204
+ #
205
+ # @api private
193
206
  def body_and_query_params
194
207
  # ^-- FIXME a better name for this method
195
208
  @body_and_query_params ||= begin
@@ -198,13 +211,15 @@ module Merb
198
211
  h.to_mash
199
212
  end
200
213
  end
201
-
214
+
202
215
  # ==== Raises
203
216
  # ControllerExceptions::MultiPartParseError::
204
217
  # Unable to parse the multipart form data.
205
218
  #
206
219
  # ==== Returns
207
220
  # Hash:: The parsed multipart parameters.
221
+ #
222
+ # @api private
208
223
  def multipart_params
209
224
  @multipart_params ||=
210
225
  begin
@@ -220,7 +235,7 @@ module Merb
220
235
  raise e
221
236
  end
222
237
  end
223
-
238
+
224
239
  # ==== Returns
225
240
  # Hash:: Parameters from body if this is a JSON request.
226
241
  #
@@ -229,6 +244,8 @@ module Merb
229
244
  # parameters hash. If it parses to anything else (such as an Array, or
230
245
  # if it inflates to an Object) it will be accessible via the inflated_object
231
246
  # parameter.
247
+ #
248
+ # @api private
232
249
  def json_params
233
250
  @json_params ||= begin
234
251
  if Merb::Const::JSON_MIME_TYPE_REGEXP.match(content_type)
@@ -237,9 +254,11 @@ module Merb
237
254
  end
238
255
  end
239
256
  end
240
-
257
+
241
258
  # ==== Returns
242
259
  # Hash:: Parameters from body if this is an XML request.
260
+ #
261
+ # @api private
243
262
  def xml_params
244
263
  @xml_params ||= begin
245
264
  if Merb::Const::XML_MIME_TYPE_REGEXP.match(content_type)
@@ -256,6 +275,8 @@ module Merb
256
275
  # ==== Notes
257
276
  # The order of precedence for the params is XML, JSON, multipart, body and
258
277
  # request string.
278
+ #
279
+ # @api public
259
280
  def params
260
281
  @params ||= begin
261
282
  h = body_and_query_params.merge(route_params)
@@ -266,6 +287,10 @@ module Merb
266
287
  end
267
288
  end
268
289
 
290
+ # ==== Returns
291
+ # String:: Returns the redirect message Base64 unencoded.
292
+ #
293
+ # @api public
269
294
  def message
270
295
  return {} unless params[:_message]
271
296
  begin
@@ -274,14 +299,19 @@ module Merb
274
299
  {}
275
300
  end
276
301
  end
277
-
302
+
303
+ # ==== Notes
278
304
  # Resets the params to a nil value.
305
+ #
306
+ # @api private
279
307
  def reset_params!
280
308
  @params = nil
281
309
  end
282
310
 
283
311
  # ==== Returns
284
312
  # String:: The raw post.
313
+ #
314
+ # @api private
285
315
  def raw_post
286
316
  @body.rewind if @body.respond_to?(:rewind)
287
317
  @raw_post ||= @body.read
@@ -289,6 +319,8 @@ module Merb
289
319
 
290
320
  # ==== Returns
291
321
  # Boolean:: If the request is an XML HTTP request.
322
+ #
323
+ # @api public
292
324
  def xml_http_request?
293
325
  not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil?
294
326
  end
@@ -297,17 +329,19 @@ module Merb
297
329
 
298
330
  # ==== Returns
299
331
  # String:: The remote IP address.
332
+ #
333
+ # @api public
300
334
  def remote_ip
301
335
  return @env['HTTP_CLIENT_IP'] if @env.include?('HTTP_CLIENT_IP')
302
-
336
+
303
337
  if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then
304
338
  remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip|
305
339
  ip =~ /^unknown$|^(127|10|172\.16|192\.168)\./i
306
340
  end
307
-
341
+
308
342
  return remote_ips.first.strip unless remote_ips.empty?
309
343
  end
310
-
344
+
311
345
  return @env[Merb::Const::REMOTE_ADDR]
312
346
  end
313
347
 
@@ -315,126 +349,168 @@ module Merb
315
349
  # String::
316
350
  # The protocol, i.e. either "https" or "http" depending on the
317
351
  # HTTPS header.
352
+ #
353
+ # @api public
318
354
  def protocol
319
355
  ssl? ? 'https' : 'http'
320
356
  end
321
357
 
322
358
  # ==== Returns
323
359
  # Boolean::: True if the request is an SSL request.
360
+ #
361
+ # @api public
324
362
  def ssl?
325
363
  @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
326
364
  end
327
365
 
328
366
  # ==== Returns
329
367
  # String:: The HTTP referer.
368
+ #
369
+ # @api public
330
370
  def referer
331
371
  @env['HTTP_REFERER']
332
372
  end
333
373
 
334
374
  # ==== Returns
335
375
  # String:: The full URI, including protocol and host
376
+ #
377
+ # @api public
336
378
  def full_uri
337
379
  protocol + "://" + host + uri
338
380
  end
339
381
 
340
382
  # ==== Returns
341
383
  # String:: The request URI.
384
+ #
385
+ # @api public
342
386
  def uri
343
387
  @env['REQUEST_PATH'] || @env['REQUEST_URI'] || path_info
344
388
  end
345
-
389
+
346
390
  # ==== Returns
347
391
  # String:: The HTTP user agent.
392
+ #
393
+ # @api public
348
394
  def user_agent
349
395
  @env['HTTP_USER_AGENT']
350
396
  end
351
-
397
+
352
398
  # ==== Returns
353
399
  # String:: The server name.
400
+ #
401
+ # @api public
354
402
  def server_name
355
403
  @env['SERVER_NAME']
356
404
  end
357
-
405
+
358
406
  # ==== Returns
359
407
  # String:: The accepted encodings.
408
+ #
409
+ # @api private
360
410
  def accept_encoding
361
411
  @env['HTTP_ACCEPT_ENCODING']
362
412
  end
363
-
413
+
364
414
  # ==== Returns
365
415
  # String:: The script name.
416
+ #
417
+ # @api public
366
418
  def script_name
367
419
  @env['SCRIPT_NAME']
368
420
  end
369
-
421
+
370
422
  # ==== Returns
371
423
  # String:: HTTP cache control.
424
+ #
425
+ # @api public
372
426
  def cache_control
373
427
  @env['HTTP_CACHE_CONTROL']
374
428
  end
375
-
429
+
376
430
  # ==== Returns
377
431
  # String:: The accepted language.
432
+ #
433
+ # @api public
378
434
  def accept_language
379
435
  @env['HTTP_ACCEPT_LANGUAGE']
380
436
  end
381
-
437
+
382
438
  # ==== Returns
383
439
  # String:: The server software.
440
+ #
441
+ # @api public
384
442
  def server_software
385
443
  @env['SERVER_SOFTWARE']
386
444
  end
387
-
445
+
388
446
  # ==== Returns
389
447
  # String:: Value of HTTP_KEEP_ALIVE.
448
+ #
449
+ # @api public
390
450
  def keep_alive
391
451
  @env['HTTP_KEEP_ALIVE']
392
452
  end
393
-
453
+
394
454
  # ==== Returns
395
455
  # String:: The accepted character sets.
456
+ #
457
+ # @api public
396
458
  def accept_charset
397
459
  @env['HTTP_ACCEPT_CHARSET']
398
460
  end
399
-
461
+
400
462
  # ==== Returns
401
463
  # String:: The HTTP version
464
+ #
465
+ # @api private
402
466
  def version
403
467
  @env['HTTP_VERSION']
404
468
  end
405
-
469
+
406
470
  # ==== Returns
407
471
  # String:: The gateway.
472
+ #
473
+ # @api public
408
474
  def gateway
409
475
  @env['GATEWAY_INTERFACE']
410
476
  end
411
-
477
+
412
478
  # ==== Returns
413
479
  # String:: The accepted response types. Defaults to "*/*".
480
+ #
481
+ # @api private
414
482
  def accept
415
483
  @env['HTTP_ACCEPT'].blank? ? "*/*" : @env['HTTP_ACCEPT']
416
484
  end
417
-
485
+
418
486
  # ==== Returns
419
487
  # String:: The HTTP connection.
488
+ #
489
+ # @api private
420
490
  def connection
421
491
  @env['HTTP_CONNECTION']
422
492
  end
423
-
493
+
424
494
  # ==== Returns
425
495
  # String:: The query string.
496
+ #
497
+ # @api private
426
498
  def query_string
427
499
  @env['QUERY_STRING']
428
500
  end
429
-
501
+
430
502
  # ==== Returns
431
503
  # String:: The request content type.
504
+ #
505
+ # @api private
432
506
  def content_type
433
507
  @env['CONTENT_TYPE']
434
508
  end
435
-
509
+
436
510
  # ==== Returns
437
511
  # Fixnum:: The request content length.
512
+ #
513
+ # @api public
438
514
  def content_length
439
515
  @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i
440
516
  end
@@ -443,6 +519,8 @@ module Merb
443
519
  # String::
444
520
  # The URI without the query string. Strips trailing "/" and reduces
445
521
  # duplicate "/" to a single "/".
522
+ #
523
+ # @api public
446
524
  def path
447
525
  path = (uri.empty? ? '/' : uri.split('?').first).squeeze("/")
448
526
  path = path[0..-2] if (path[-1] == ?/) && path.size > 1
@@ -451,18 +529,24 @@ module Merb
451
529
 
452
530
  # ==== Returns
453
531
  # String:: The path info.
532
+ #
533
+ # @api public
454
534
  def path_info
455
535
  @path_info ||= self.class.unescape(@env['PATH_INFO'])
456
536
  end
457
537
 
458
538
  # ==== Returns
459
539
  # Fixnum:: The server port.
540
+ #
541
+ # @api public
460
542
  def port
461
543
  @env['SERVER_PORT'].to_i
462
544
  end
463
545
 
464
546
  # ==== Returns
465
547
  # String:: The full hostname including the port.
548
+ #
549
+ # @api public
466
550
  def host
467
551
  @env['HTTP_X_FORWARDED_HOST'] || @env['HTTP_HOST']
468
552
  end
@@ -474,6 +558,8 @@ module Merb
474
558
  #
475
559
  # ==== Returns
476
560
  # Array:: All the subdomain parts of the host.
561
+ #
562
+ # @api public
477
563
  def subdomains(tld_length = 1)
478
564
  parts = host.split('.')
479
565
  parts[0..-(tld_length+2)]
@@ -486,18 +572,24 @@ module Merb
486
572
  #
487
573
  # ==== Returns
488
574
  # String:: The full domain name without the port number.
575
+ #
576
+ # @api public
489
577
  def domain(tld_length = 1)
490
578
  host.split('.').last(1 + tld_length).join('.').sub(/:\d+$/,'')
491
579
  end
492
-
580
+
493
581
  # ==== Returns
494
582
  # Value of If-None-Match request header.
583
+ #
584
+ # @api private
495
585
  def if_none_match
496
586
  @env[Merb::Const::HTTP_IF_NONE_MATCH]
497
587
  end
498
-
588
+
499
589
  # ==== Returns
500
590
  # Value of If-Modified-Since request header.
591
+ #
592
+ # @api private
501
593
  def if_modified_since
502
594
  if time = @env[Merb::Const::HTTP_IF_MODIFIED_SINCE]
503
595
  Time.rfc2822(time)
@@ -525,6 +617,8 @@ module Merb
525
617
  # # => "search[page]=10&search[word]=ruby"
526
618
  # params_to_query_string([ "ice-cream", "cake" ], "shopping_list")
527
619
  # # => "shopping_list[]=ice-cream&shopping_list[]=cake"
620
+ #
621
+ # @api private
528
622
  def params_to_query_string(value, prefix = nil)
529
623
  case value
530
624
  when Array
@@ -545,17 +639,21 @@ module Merb
545
639
  #
546
640
  # ==== returns
547
641
  # String:: The escaped string.
642
+ #
643
+ # @api private
548
644
  def escape(s)
549
645
  s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
550
646
  '%'+$1.unpack('H2'*$1.size).join('%').upcase
551
647
  }.tr(' ', '+')
552
648
  end
553
-
649
+
554
650
  # ==== Parameter
555
651
  # s<String>:: String to URL unescape.
556
652
  #
557
653
  # ==== returns
558
654
  # String:: The unescaped string.
655
+ #
656
+ # @api private
559
657
  def unescape(s)
560
658
  s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
561
659
  [$1.delete('%')].pack('H*')
@@ -573,6 +671,8 @@ module Merb
573
671
  # ==== Examples
574
672
  # query_parse("bar=nik&post[body]=heya")
575
673
  # # => { :bar => "nik", :post => { :body => "heya" } }
674
+ #
675
+ # @api private
576
676
  def query_parse(query_string, delimiter = '&;', preserve_order = false)
577
677
  query = preserve_order ? Dictionary.new : {}
578
678
  for pair in (query_string || '').split(/[#{delimiter}] */n)
@@ -586,13 +686,13 @@ module Merb
586
686
  end
587
687
  preserve_order ? query : query.to_mash
588
688
  end
589
-
689
+
590
690
  NAME_REGEX = /Content-Disposition:.* name="?([^\";]*)"?/ni.freeze
591
691
  CONTENT_TYPE_REGEX = /Content-Type: (.*)\r\n/ni.freeze
592
692
  FILENAME_REGEX = /Content-Disposition:.* filename="?([^\";]*)"?/ni.freeze
593
693
  CRLF = "\r\n".freeze
594
694
  EOL = CRLF
595
-
695
+
596
696
  # ==== Parameters
597
697
  # request<IO>:: The raw request.
598
698
  # boundary<String>:: The boundary string.
@@ -603,6 +703,8 @@ module Merb
603
703
  #
604
704
  # ==== Returns
605
705
  # Hash:: The parsed request.
706
+ #
707
+ # @api private
606
708
  def parse_multipart(request, boundary, content_length)
607
709
  boundary = "--#{boundary}"
608
710
  paramhsh = {}
@@ -633,19 +735,19 @@ module Merb
633
735
  filename = head[FILENAME_REGEX, 1]
634
736
  content_type = head[CONTENT_TYPE_REGEX, 1]
635
737
  name = head[NAME_REGEX, 1]
636
-
738
+
637
739
  if filename && !filename.empty?
638
740
  body = Tempfile.new(:Merb)
639
741
  body.binmode if defined? body.binmode
640
742
  end
641
743
  next
642
744
  end
643
-
745
+
644
746
  # Save the read body part.
645
747
  if head && (boundary_size+4 < buf.size)
646
748
  body << buf.slice!(0, buf.size - (boundary_size+4))
647
749
  end
648
-
750
+
649
751
  read_size = bufsize < content_length ? bufsize : content_length
650
752
  if( read_size > 0 )
651
753
  c = input.read(read_size)
@@ -654,15 +756,15 @@ module Merb
654
756
  content_length -= c.size
655
757
  end
656
758
  end
657
-
759
+
658
760
  # Save the rest.
659
761
  if i = buf.index(rx)
660
762
  body << buf.slice!(0, i)
661
763
  buf.slice!(0, boundary_size+2)
662
-
764
+
663
765
  content_length = -1 if $1 == "--"
664
766
  end
665
-
767
+
666
768
  if filename && !filename.empty?
667
769
  body.rewind
668
770
  data = {
@@ -679,7 +781,7 @@ module Merb
679
781
  }
680
782
  paramhsh
681
783
  end
682
-
784
+
683
785
  # Converts a query string snippet to a hash and adds it to existing
684
786
  # parameters.
685
787
  #
@@ -690,6 +792,8 @@ module Merb
690
792
  #
691
793
  # ==== Returns
692
794
  # Hash:: Normalized parameters
795
+ #
796
+ # @api private
693
797
  def normalize_params(parms, name, val=nil)
694
798
  name =~ %r([\[\]]*([^\[\]]+)\]*)
695
799
  key = $1 || ''
@@ -715,4 +819,4 @@ module Merb
715
819
  end
716
820
  end
717
821
  end
718
- end
822
+ end