Skip to content

Commit b127daf

Browse files
committed
Merge pull request #498 from karlfreeman/fix-options-headers
Fix options headers
2 parents 0a04ea6 + ad15b61 commit b127daf

File tree

3 files changed

+25
-20
lines changed

3 files changed

+25
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Next Release
77

88
* [#492](https://github.com/intridea/grape/pull/492): Don't allow to have nil value when a param is required and has a list of allowed values. - [@Antti](https://github.com/Antti)
99
* [#495](https://github.com/intridea/grape/pull/495): Fix `ParamsScope#params` for parameters nested inside arrays - [@asross](https://github.com/asross).
10+
* [#498](https://github.com/intridea/grape/pull/498): Dry up options and headers logic, allow headers to be passed to OPTIONS requests - [@karlfreeman](https://github.com/karlfreeman).
1011

1112
0.6.1
1213
=====

lib/grape/api.rb

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -514,10 +514,10 @@ def inherit_settings(other_stack)
514514

515515
def initialize
516516
@route_set = Rack::Mount::RouteSet.new
517+
add_head_not_allowed_methods_and_options_methods
517518
self.class.endpoints.each do |endpoint|
518519
endpoint.mount_in(@route_set)
519520
end
520-
add_head_not_allowed_methods
521521
@route_set.freeze
522522
end
523523

@@ -549,7 +549,7 @@ def cascade?
549549
# with a list of HTTP methods that can be called. Also add a route that
550550
# will return an HTTP 405 response for any HTTP method that the resource
551551
# cannot handle.
552-
def add_head_not_allowed_methods
552+
def add_head_not_allowed_methods_and_options_methods
553553
allowed_methods = Hash.new { |h, k| h[k] = [] }
554554
resources = self.class.endpoints.map do |endpoint|
555555
if endpoint.options[:app] && endpoint.options[:app].respond_to?(:endpoints)
@@ -559,27 +559,27 @@ def add_head_not_allowed_methods
559559
end
560560
end
561561
resources.flatten.each do |route|
562-
allowed_methods[route.route_compiled] << route.route_method
562+
allowed_methods[route.route_path] << route.route_method
563563
end
564-
allowed_methods.each do |path_info, methods|
565-
if methods.include?('GET') && !methods.include?("HEAD") && !self.class.settings[:do_not_route_head]
564+
allowed_methods.each do |path, methods|
565+
if methods.include?('GET') && !methods.include?('HEAD') && !self.class.settings[:do_not_route_head]
566566
methods = methods | ['HEAD']
567567
end
568-
allow_header = (["OPTIONS"] | methods).join(", ")
569-
unless methods.include?("OPTIONS") || self.class.settings[:do_not_route_options]
570-
@route_set.add_route(proc { [204, { 'Allow' => allow_header }, []] }, {
571-
path_info: path_info,
572-
request_method: "OPTIONS"
573-
})
568+
allow_header = (['OPTIONS'] | methods).join(', ')
569+
if methods.include?('OPTIONS') || !self.class.settings[:do_not_route_options]
570+
self.class.options(path, {}) {
571+
header 'Allow', allow_header
572+
status 204
573+
''
574+
}
574575
end
575576
not_allowed_methods = %w(GET PUT POST DELETE PATCH HEAD) - methods
576-
not_allowed_methods << "OPTIONS" if self.class.settings[:do_not_route_options]
577-
not_allowed_methods.each do |bad_method|
578-
@route_set.add_route(proc { [405, { 'Allow' => allow_header, 'Content-Type' => 'text/plain' }, []] }, {
579-
path_info: path_info,
580-
request_method: bad_method
581-
})
582-
end
577+
not_allowed_methods << 'OPTIONS' if self.class.settings[:do_not_route_options]
578+
self.class.route(not_allowed_methods, path) {
579+
header 'Allow', allow_header
580+
status 405
581+
''
582+
}
583583
end
584584
end
585585

spec/grape/api_spec.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,13 +473,15 @@ def subject.enable_root_route!
473473
last_response.body.should eql 'Created'
474474
end
475475

476-
it 'returns a 405 for an unsupported method' do
476+
it 'returns a 405 for an unsupported method with an X-Custom-Header' do
477+
subject.before { header 'X-Custom-Header', 'foo' }
477478
subject.get 'example' do
478479
"example"
479480
end
480481
put '/example'
481482
last_response.status.should eql 405
482483
last_response.body.should eql ''
484+
last_response.headers['X-Custom-Header'].should eql 'foo'
483485
end
484486

485487
specify '405 responses includes an Allow header specifying supported methods' do
@@ -504,14 +506,16 @@ def subject.enable_root_route!
504506
last_response.headers['Content-Type'].should eql 'text/plain'
505507
end
506508

507-
it 'adds an OPTIONS route that returns a 204 and an Allow header' do
509+
it 'adds an OPTIONS route that returns a 204, an Allow header and a X-Custom-Header' do
510+
subject.before { header 'X-Custom-Header', 'foo' }
508511
subject.get 'example' do
509512
"example"
510513
end
511514
options '/example'
512515
last_response.status.should eql 204
513516
last_response.body.should eql ''
514517
last_response.headers['Allow'].should eql 'OPTIONS, GET, HEAD'
518+
last_response.headers['X-Custom-Header'].should eql 'foo'
515519
end
516520

517521
it 'allows HEAD on a GET request' do

0 commit comments

Comments
 (0)