actionpack 4.1.16 → 4.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +163 -690
  3. data/README.rdoc +7 -2
  4. data/lib/abstract_controller/base.rb +16 -6
  5. data/lib/abstract_controller/callbacks.rb +28 -51
  6. data/lib/abstract_controller/helpers.rb +0 -3
  7. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  8. data/lib/abstract_controller/rendering.rb +1 -7
  9. data/lib/abstract_controller/url_for.rb +1 -1
  10. data/lib/action_controller.rb +1 -0
  11. data/lib/action_controller/base.rb +2 -1
  12. data/lib/action_controller/caching.rb +1 -1
  13. data/lib/action_controller/caching/fragments.rb +7 -1
  14. data/lib/action_controller/log_subscriber.rb +26 -25
  15. data/lib/action_controller/metal.rb +11 -7
  16. data/lib/action_controller/metal/conditional_get.rb +31 -6
  17. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  18. data/lib/action_controller/metal/force_ssl.rb +1 -1
  19. data/lib/action_controller/metal/head.rb +2 -0
  20. data/lib/action_controller/metal/http_authentication.rb +3 -15
  21. data/lib/action_controller/metal/instrumentation.rb +4 -7
  22. data/lib/action_controller/metal/live.rb +57 -6
  23. data/lib/action_controller/metal/mime_responds.rb +17 -227
  24. data/lib/action_controller/metal/redirecting.rb +14 -8
  25. data/lib/action_controller/metal/renderers.rb +19 -3
  26. data/lib/action_controller/metal/rendering.rb +2 -6
  27. data/lib/action_controller/metal/request_forgery_protection.rb +75 -7
  28. data/lib/action_controller/metal/streaming.rb +1 -1
  29. data/lib/action_controller/metal/strong_parameters.rb +111 -11
  30. data/lib/action_controller/metal/url_for.rb +11 -12
  31. data/lib/action_controller/model_naming.rb +1 -1
  32. data/lib/action_controller/railtie.rb +4 -0
  33. data/lib/action_controller/test_case.rb +87 -75
  34. data/lib/action_dispatch/http/cache.rb +1 -1
  35. data/lib/action_dispatch/http/filter_parameters.rb +2 -2
  36. data/lib/action_dispatch/http/headers.rb +43 -9
  37. data/lib/action_dispatch/http/mime_negotiation.rb +10 -4
  38. data/lib/action_dispatch/http/mime_type.rb +2 -16
  39. data/lib/action_dispatch/http/parameter_filter.rb +1 -1
  40. data/lib/action_dispatch/http/parameters.rb +11 -26
  41. data/lib/action_dispatch/http/request.rb +30 -10
  42. data/lib/action_dispatch/http/response.rb +52 -17
  43. data/lib/action_dispatch/http/upload.rb +3 -8
  44. data/lib/action_dispatch/http/url.rb +87 -70
  45. data/lib/action_dispatch/journey/formatter.rb +18 -17
  46. data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
  47. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
  48. data/lib/action_dispatch/journey/gtg/transition_table.rb +18 -26
  49. data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
  50. data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
  51. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
  52. data/lib/action_dispatch/journey/nodes/node.rb +4 -0
  53. data/lib/action_dispatch/journey/parser.rb +52 -60
  54. data/lib/action_dispatch/journey/parser.y +11 -10
  55. data/lib/action_dispatch/journey/path/pattern.rb +16 -19
  56. data/lib/action_dispatch/journey/route.rb +3 -18
  57. data/lib/action_dispatch/journey/router.rb +34 -65
  58. data/lib/action_dispatch/journey/router/strexp.rb +9 -6
  59. data/lib/action_dispatch/journey/routes.rb +0 -4
  60. data/lib/action_dispatch/journey/visitors.rb +81 -92
  61. data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
  62. data/lib/action_dispatch/middleware/cookies.rb +27 -31
  63. data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -3
  64. data/lib/action_dispatch/middleware/exception_wrapper.rb +19 -17
  65. data/lib/action_dispatch/middleware/flash.rb +7 -4
  66. data/lib/action_dispatch/middleware/public_exceptions.rb +13 -8
  67. data/lib/action_dispatch/middleware/remote_ip.rb +3 -3
  68. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  69. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -1
  70. data/lib/action_dispatch/middleware/show_exceptions.rb +1 -0
  71. data/lib/action_dispatch/middleware/static.rb +22 -23
  72. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +22 -18
  73. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +36 -8
  74. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +2 -8
  75. data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +0 -0
  76. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  77. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
  78. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -24
  79. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +0 -1
  80. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +119 -63
  81. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  82. data/lib/action_dispatch/routing/inspector.rb +4 -11
  83. data/lib/action_dispatch/routing/mapper.rb +399 -278
  84. data/lib/action_dispatch/routing/polymorphic_routes.rb +190 -78
  85. data/lib/action_dispatch/routing/redirection.rb +10 -12
  86. data/lib/action_dispatch/routing/route_set.rb +224 -177
  87. data/lib/action_dispatch/routing/url_for.rb +9 -4
  88. data/lib/action_dispatch/testing/assertions.rb +11 -7
  89. data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
  90. data/lib/action_dispatch/testing/assertions/response.rb +2 -7
  91. data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
  92. data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
  93. data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
  94. data/lib/action_dispatch/testing/integration.rb +15 -18
  95. data/lib/action_dispatch/testing/test_request.rb +1 -1
  96. data/lib/action_dispatch/testing/test_response.rb +5 -1
  97. data/lib/action_pack/gem_version.rb +3 -3
  98. metadata +57 -15
  99. data/lib/action_controller/metal/responder.rb +0 -297
@@ -23,25 +23,24 @@ module ActionController
23
23
  include AbstractController::UrlFor
24
24
 
25
25
  def url_options
26
- @_url_options ||= super.reverse_merge(
26
+ @_url_options ||= {
27
27
  :host => request.host,
28
28
  :port => request.optional_port,
29
29
  :protocol => request.protocol,
30
- :_recall => request.symbolized_path_parameters
31
- ).freeze
30
+ :_recall => request.path_parameters
31
+ }.merge!(super).freeze
32
32
 
33
- if (same_origin = _routes.equal?(env["action_dispatch.routes"])) ||
33
+ if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) ||
34
34
  (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
35
- (original_script_name = env['ORIGINAL_SCRIPT_NAME'])
35
+ (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze])
36
36
 
37
- @_url_options.dup.tap do |options|
38
- if original_script_name
39
- options[:original_script_name] = original_script_name
40
- else
41
- options[:script_name] = same_origin ? request.script_name.dup : script_name
42
- end
43
- options.freeze
37
+ options = @_url_options.dup
38
+ if original_script_name
39
+ options[:original_script_name] = original_script_name
40
+ else
41
+ options[:script_name] = same_origin ? request.script_name.dup : script_name
44
42
  end
43
+ options.freeze
45
44
  else
46
45
  @_url_options
47
46
  end
@@ -6,7 +6,7 @@ module ActionController
6
6
  end
7
7
 
8
8
  def model_name_from_record_or_class(record_or_class)
9
- (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name
9
+ convert_to_model(record_or_class).model_name
10
10
  end
11
11
  end
12
12
  end
@@ -23,6 +23,10 @@ module ActionController
23
23
  options = app.config.action_controller
24
24
 
25
25
  ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
26
+ if app.config.action_controller[:always_permitted_parameters]
27
+ ActionController::Parameters.always_permitted_parameters =
28
+ app.config.action_controller.delete(:always_permitted_parameters)
29
+ end
26
30
  ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
27
31
  (Rails.env.test? || Rails.env.development?) ? :log : false
28
32
  end
@@ -3,6 +3,8 @@ require 'active_support/core_ext/object/to_query'
3
3
  require 'active_support/core_ext/module/anonymous'
4
4
  require 'active_support/core_ext/hash/keys'
5
5
 
6
+ require 'rails-dom-testing'
7
+
6
8
  module ActionController
7
9
  module TemplateAssertions
8
10
  extend ActiveSupport::Concern
@@ -12,13 +14,16 @@ module ActionController
12
14
  teardown :teardown_subscriptions
13
15
  end
14
16
 
17
+ RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
18
+
15
19
  def setup_subscriptions
16
- @_partials = Hash.new(0)
17
- @_templates = Hash.new(0)
18
- @_layouts = Hash.new(0)
19
- @_files = Hash.new(0)
20
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
21
+ instance_variable_set("@_#{instance_variable}", Hash.new(0))
22
+ end
23
+
24
+ @_subscribers = []
20
25
 
21
- ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
26
+ @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
22
27
  path = payload[:layout]
23
28
  if path
24
29
  @_layouts[path] += 1
@@ -28,42 +33,43 @@ module ActionController
28
33
  end
29
34
  end
30
35
 
31
- ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
32
- path = payload[:virtual_path]
33
- next unless path
34
- partial = path =~ /^.*\/_[^\/]*$/
36
+ @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
37
+ if virtual_path = payload[:virtual_path]
38
+ partial = virtual_path =~ /^.*\/_[^\/]*$/
35
39
 
36
- if partial
37
- @_partials[path] += 1
38
- @_partials[path.split("/").last] += 1
39
- end
40
-
41
- @_templates[path] += 1
42
- end
43
-
44
- ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
45
- next if payload[:virtual_path] # files don't have virtual path
40
+ if partial
41
+ @_partials[virtual_path] += 1
42
+ @_partials[virtual_path.split("/").last] += 1
43
+ end
46
44
 
47
- path = payload[:identifier]
48
- if path
49
- @_files[path] += 1
50
- @_files[path.split("/").last] += 1
45
+ @_templates[virtual_path] += 1
46
+ else
47
+ path = payload[:identifier]
48
+ if path
49
+ @_files[path] += 1
50
+ @_files[path.split("/").last] += 1
51
+ end
51
52
  end
52
53
  end
53
54
  end
54
55
 
55
56
  def teardown_subscriptions
56
- ActiveSupport::Notifications.unsubscribe("render_template.action_view")
57
- ActiveSupport::Notifications.unsubscribe("!render_template.action_view")
57
+ @_subscribers.each do |subscriber|
58
+ ActiveSupport::Notifications.unsubscribe(subscriber)
59
+ end
58
60
  end
59
61
 
60
62
  def process(*args)
61
- @_partials = Hash.new(0)
62
- @_templates = Hash.new(0)
63
- @_layouts = Hash.new(0)
63
+ reset_template_assertion
64
64
  super
65
65
  end
66
66
 
67
+ def reset_template_assertion
68
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
69
+ instance_variable_get("@_#{instance_variable}").clear
70
+ end
71
+ end
72
+
67
73
  # Asserts that the request was rendered with the appropriate template file or partials.
68
74
  #
69
75
  # # assert that the "new" view template was rendered
@@ -87,6 +93,13 @@ module ActionController
87
93
  # # assert that no partials were rendered
88
94
  # assert_template partial: false
89
95
  #
96
+ # # assert that a file was rendered
97
+ # assert_template file: "README.rdoc"
98
+ #
99
+ # # assert that no file was rendered
100
+ # assert_template file: nil
101
+ # assert_template file: false
102
+ #
90
103
  # In a view test case, you can also assert that specific locals are passed
91
104
  # to partials:
92
105
  #
@@ -136,6 +149,8 @@ module ActionController
136
149
 
137
150
  if options[:file]
138
151
  assert_includes @_files.keys, options[:file]
152
+ elsif options.key?(:file)
153
+ assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
139
154
  end
140
155
 
141
156
  if expected_partial = options[:partial]
@@ -197,7 +212,7 @@ module ActionController
197
212
  value = value.dup
198
213
  end
199
214
 
200
- if extra_keys.include?(key.to_sym)
215
+ if extra_keys.include?(key)
201
216
  non_path_parameters[key] = value
202
217
  else
203
218
  if value.is_a?(Array)
@@ -206,7 +221,7 @@ module ActionController
206
221
  value = value.to_param
207
222
  end
208
223
 
209
- path_parameters[key.to_s] = value
224
+ path_parameters[key] = value
210
225
  end
211
226
  end
212
227
 
@@ -231,7 +246,6 @@ module ActionController
231
246
  @formats = nil
232
247
  @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
233
248
  @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
234
- @symbolized_path_params = nil
235
249
  @method = @request_method = nil
236
250
  @fullpath = @ip = @remote_ip = @protocol = nil
237
251
  @env['action_dispatch.request.query_parameters'] = {}
@@ -430,6 +444,7 @@ module ActionController
430
444
  extend ActiveSupport::Concern
431
445
  include ActionDispatch::TestProcess
432
446
  include ActiveSupport::Testing::ConstantLookup
447
+ include Rails::Dom::Testing::Assertions
433
448
 
434
449
  attr_reader :response, :request
435
450
 
@@ -453,7 +468,6 @@ module ActionController
453
468
  end
454
469
 
455
470
  def controller_class=(new_class)
456
- prepare_controller_class(new_class) if new_class
457
471
  self._controller_class = new_class
458
472
  end
459
473
 
@@ -470,11 +484,6 @@ module ActionController
470
484
  Class === constant && constant < ActionController::Metal
471
485
  end
472
486
  end
473
-
474
- def prepare_controller_class(new_class)
475
- new_class.send :include, ActionController::TestCase::RaiseActionExceptions
476
- end
477
-
478
487
  end
479
488
 
480
489
  # Simulate a GET request with the given parameters.
@@ -486,8 +495,8 @@ module ActionController
486
495
  # - +session+: A hash of parameters to store in the session. This may be +nil+.
487
496
  # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
488
497
  #
489
- # You can also simulate POST, PATCH, PUT, DELETE, HEAD, and OPTIONS requests with
490
- # +post+, +patch+, +put+, +delete+, +head+, and +options+.
498
+ # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
499
+ # +post+, +patch+, +put+, +delete+, and +head+.
491
500
  #
492
501
  # Note that the request method is not verified. The different methods are
493
502
  # available to make the tests more expressive.
@@ -548,6 +557,31 @@ module ActionController
548
557
  end
549
558
  end
550
559
 
560
+ # Simulate a HTTP request to +action+ by specifying request method,
561
+ # parameters and set/volley the response.
562
+ #
563
+ # - +action+: The controller action to call.
564
+ # - +http_method+: Request method used to send the http request. Possible values
565
+ # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+.
566
+ # - +parameters+: The HTTP parameters. This may be +nil+, a hash, or a
567
+ # string that is appropriately encoded (+application/x-www-form-urlencoded+
568
+ # or +multipart/form-data+).
569
+ # - +session+: A hash of parameters to store in the session. This may be +nil+.
570
+ # - +flash+: A hash of parameters to store in the flash. This may be +nil+.
571
+ #
572
+ # Example calling +create+ action and sending two params:
573
+ #
574
+ # process :create, 'POST', user: { name: 'Gaurish Sharma', email: 'user@example.com' }
575
+ #
576
+ # Example sending parameters, +nil+ session and setting a flash message:
577
+ #
578
+ # process :view, 'GET', { id: 7 }, nil, { notice: 'This is flash message' }
579
+ #
580
+ # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests
581
+ # prefer using #get, #post, #patch, #put, #delete and #head methods
582
+ # respectively which will make tests more expressive.
583
+ #
584
+ # Note that the request method is not verified.
551
585
  def process(action, http_method = 'GET', *args)
552
586
  check_required_ivars
553
587
 
@@ -556,6 +590,7 @@ module ActionController
556
590
  end
557
591
 
558
592
  parameters, session, flash = args
593
+ parameters ||= {}
559
594
 
560
595
  # Ensure that numbers and symbols passed as params are converted to
561
596
  # proper params, as is the case when engaging rack.
@@ -565,7 +600,6 @@ module ActionController
565
600
 
566
601
  unless @controller.respond_to?(:recycle!)
567
602
  @controller.extend(Testing::Functional)
568
- @controller.class.class_eval { include Testing }
569
603
  end
570
604
 
571
605
  @request.recycle!
@@ -574,7 +608,6 @@ module ActionController
574
608
 
575
609
  @request.env['REQUEST_METHOD'] = http_method
576
610
 
577
- parameters ||= {}
578
611
  controller_class_name = @controller.class.anonymous? ?
579
612
  "anonymous" :
580
613
  @controller.class.controller_path
@@ -602,8 +635,11 @@ module ActionController
602
635
  @response.prepare!
603
636
 
604
637
  @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
605
- @request.session['flash'] = @request.flash.to_session_value
606
- @request.session.delete('flash') if @request.session['flash'].blank?
638
+
639
+ if flash_value = @request.flash.to_session_value
640
+ @request.session['flash'] = flash_value
641
+ end
642
+
607
643
  @response
608
644
  end
609
645
 
@@ -651,6 +687,11 @@ module ActionController
651
687
  end
652
688
 
653
689
  private
690
+
691
+ def document_root_element
692
+ html_document.root
693
+ end
694
+
654
695
  def check_required_ivars
655
696
  # Sanity check for required instance variables so we can give an
656
697
  # understandable error message.
@@ -665,12 +706,11 @@ module ActionController
665
706
  unless @request.env["PATH_INFO"]
666
707
  options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
667
708
  options.update(
668
- :only_path => true,
669
709
  :action => action,
670
710
  :relative_url_root => nil,
671
- :_recall => @request.symbolized_path_parameters)
711
+ :_recall => @request.path_parameters)
672
712
 
673
- url, query_string = @routes.url_for(options).split("?", 2)
713
+ url, query_string = @routes.path_for(options).split("?", 2)
674
714
 
675
715
  @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
676
716
  @request.env["PATH_INFO"] = url
@@ -679,39 +719,11 @@ module ActionController
679
719
  end
680
720
 
681
721
  def html_format?(parameters)
682
- return true unless parameters.is_a?(Hash)
722
+ return true unless parameters.key?(:format)
683
723
  Mime.fetch(parameters[:format]) { Mime['html'] }.html?
684
724
  end
685
725
  end
686
726
 
687
- # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
688
- # (skipping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
689
- # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
690
- # than 0.0.0.0.
691
- #
692
- # The exception is stored in the exception accessor for further inspection.
693
- module RaiseActionExceptions
694
- def self.included(base) #:nodoc:
695
- unless base.method_defined?(:exception) && base.method_defined?(:exception=)
696
- base.class_eval do
697
- attr_accessor :exception
698
- protected :exception, :exception=
699
- end
700
- end
701
- end
702
-
703
- protected
704
- def rescue_action_without_handler(e)
705
- self.exception = e
706
-
707
- if request.remote_addr == "0.0.0.0"
708
- raise(e)
709
- else
710
- super(e)
711
- end
712
- end
713
- end
714
-
715
727
  include Behavior
716
728
  end
717
729
  end
@@ -92,7 +92,7 @@ module ActionDispatch
92
92
  LAST_MODIFIED = "Last-Modified".freeze
93
93
  ETAG = "ETag".freeze
94
94
  CACHE_CONTROL = "Cache-Control".freeze
95
- SPECIAL_KEYS = %w[extras no-cache max-age public must-revalidate]
95
+ SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate])
96
96
 
97
97
  def cache_control_segments
98
98
  if cache_control = self[CACHE_CONTROL]
@@ -6,8 +6,8 @@ module ActionDispatch
6
6
  module Http
7
7
  # Allows you to specify sensitive parameters which will be replaced from
8
8
  # the request log by looking in the query string of the request and all
9
- # subhashes of the params hash to filter. If a block is given, each key and
10
- # value of the params hash and all subhashes is passed to it, the value
9
+ # sub-hashes of the params hash to filter. If a block is given, each key and
10
+ # value of the params hash and all sub-hashes is passed to it, the value
11
11
  # or key can be replaced using String#replace or similar method.
12
12
  #
13
13
  # env["action_dispatch.parameter_filter"] = [:password]
@@ -1,27 +1,47 @@
1
1
  module ActionDispatch
2
2
  module Http
3
+ # Provides access to the request's HTTP headers from the environment.
4
+ #
5
+ # env = { "CONTENT_TYPE" => "text/plain" }
6
+ # headers = ActionDispatch::Http::Headers.new(env)
7
+ # headers["Content-Type"] # => "text/plain"
3
8
  class Headers
4
- CGI_VARIABLES = %w(
5
- CONTENT_TYPE CONTENT_LENGTH
6
- HTTPS AUTH_TYPE GATEWAY_INTERFACE
7
- PATH_INFO PATH_TRANSLATED QUERY_STRING
8
- REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER
9
- REQUEST_METHOD SCRIPT_NAME
10
- SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE
11
- )
9
+ CGI_VARIABLES = Set.new(%W[
10
+ AUTH_TYPE
11
+ CONTENT_LENGTH
12
+ CONTENT_TYPE
13
+ GATEWAY_INTERFACE
14
+ HTTPS
15
+ PATH_INFO
16
+ PATH_TRANSLATED
17
+ QUERY_STRING
18
+ REMOTE_ADDR
19
+ REMOTE_HOST
20
+ REMOTE_IDENT
21
+ REMOTE_USER
22
+ REQUEST_METHOD
23
+ SCRIPT_NAME
24
+ SERVER_NAME
25
+ SERVER_PORT
26
+ SERVER_PROTOCOL
27
+ SERVER_SOFTWARE
28
+ ]).freeze
29
+
12
30
  HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
13
31
 
14
32
  include Enumerable
15
33
  attr_reader :env
16
34
 
17
- def initialize(env = {})
35
+ def initialize(env = {}) # :nodoc:
18
36
  @env = env
19
37
  end
20
38
 
39
+ # Returns the value for the given key mapped to @env.
21
40
  def [](key)
22
41
  @env[env_name(key)]
23
42
  end
24
43
 
44
+ # Sets the given value for the key mapped to @env.
25
45
  def []=(key, value)
26
46
  @env[env_name(key)] = value
27
47
  end
@@ -31,6 +51,13 @@ module ActionDispatch
31
51
  end
32
52
  alias :include? :key?
33
53
 
54
+ # Returns the value for the given key mapped to @env.
55
+ #
56
+ # If the key is not found and an optional code block is not provided,
57
+ # raises a <tt>KeyError</tt> exception.
58
+ #
59
+ # If the code block is provided, then it will be run and
60
+ # its result returned.
34
61
  def fetch(key, *args, &block)
35
62
  @env.fetch env_name(key), *args, &block
36
63
  end
@@ -39,12 +66,17 @@ module ActionDispatch
39
66
  @env.each(&block)
40
67
  end
41
68
 
69
+ # Returns a new Http::Headers instance containing the contents of
70
+ # <tt>headers_or_env</tt> and the original instance.
42
71
  def merge(headers_or_env)
43
72
  headers = Http::Headers.new(env.dup)
44
73
  headers.merge!(headers_or_env)
45
74
  headers
46
75
  end
47
76
 
77
+ # Adds the contents of <tt>headers_or_env</tt> to original instance
78
+ # entries; duplicate keys are overwritten with the values from
79
+ # <tt>headers_or_env</tt>.
48
80
  def merge!(headers_or_env)
49
81
  headers_or_env.each do |key, value|
50
82
  self[env_name(key)] = value
@@ -52,6 +84,8 @@ module ActionDispatch
52
84
  end
53
85
 
54
86
  private
87
+ # Converts a HTTP header name to an environment variable name if it is
88
+ # not contained within the headers hash.
55
89
  def env_name(key)
56
90
  key = key.to_s
57
91
  if key =~ HTTP_HEADER