mynyml-rack-respond_to 0.9.6 → 0.9.7
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/README +1 -0
- data/Rakefile +2 -2
- data/TODO +0 -27
- data/lib/rack/respond_to.rb +55 -4
- data/rack-respond_to.gemspec +1 -1
- data/test/test_respond_to.rb +41 -0
- metadata +1 -1
data/README
CHANGED
@@ -11,6 +11,7 @@ preference (see http://github.com/mynyml/rack-accept-media-types).
|
|
11
11
|
|
12
12
|
* Based on familiar API (Rails)
|
13
13
|
* Cascades down priority list of accepted media types
|
14
|
+
* Handles wildcard media types
|
14
15
|
* Simple to use
|
15
16
|
* Simple code (~50 LOCs)
|
16
17
|
* Flexible (standalone use)
|
data/Rakefile
CHANGED
@@ -22,7 +22,7 @@ end
|
|
22
22
|
|
23
23
|
spec = Gem::Specification.new do |s|
|
24
24
|
s.name = 'rack-respond_to'
|
25
|
-
s.version = '0.9.
|
25
|
+
s.version = '0.9.7'
|
26
26
|
s.summary = "Rack middleware port of Rails's respond_to feature"
|
27
27
|
s.description = "Rack middleware port of Rails's respond_to feature"
|
28
28
|
s.author = "Martin Aumont"
|
@@ -60,7 +60,7 @@ end
|
|
60
60
|
desc "Generate rdoc documentation."
|
61
61
|
Rake::RDocTask.new("rdoc") { |rdoc|
|
62
62
|
rdoc.rdoc_dir = 'doc/rdoc'
|
63
|
-
rdoc.title = "
|
63
|
+
rdoc.title = "Rack::RespondTo"
|
64
64
|
rdoc.options << '--line-numbers' << '--inline-source'
|
65
65
|
rdoc.options << '--charset' << 'utf-8'
|
66
66
|
rdoc.rdoc_files.include('README')
|
data/TODO
CHANGED
@@ -1,27 +0,0 @@
|
|
1
|
-
o handle wildcard content-types
|
2
|
-
e.g. */* matches first format block
|
3
|
-
|
4
|
-
Rack::RespondTo.mime_type = '*/*'
|
5
|
-
|
6
|
-
body = respond_to do |format|
|
7
|
-
format.html { 'html' }
|
8
|
-
format.xml { 'xml' }
|
9
|
-
end
|
10
|
-
body #=> 'html'
|
11
|
-
|
12
|
-
body = respond_to do |format|
|
13
|
-
format.xml { 'xml' }
|
14
|
-
format.html { 'html' }
|
15
|
-
end
|
16
|
-
body #=> 'xml'
|
17
|
-
|
18
|
-
x cascade down accept types priority instead of only responding to prefered
|
19
|
-
type. e.g:
|
20
|
-
|
21
|
-
env['HTTP_ACCEPT'] #=> 'text/plain,text/html;q=0.9,application/xml;q=0.8'
|
22
|
-
|
23
|
-
body = respond_to do |format|
|
24
|
-
format.html { 'html' }
|
25
|
-
format.xml { 'xml' }
|
26
|
-
end
|
27
|
-
body #=> 'html'
|
data/lib/rack/respond_to.rb
CHANGED
@@ -97,6 +97,12 @@ module Rack
|
|
97
97
|
# cascade down the RespondTo.media_types list until it finds a match.
|
98
98
|
# Returns nil if there is no match.
|
99
99
|
#
|
100
|
+
# Wildcard media types (*/*, text/*, etc.) will trigger the first
|
101
|
+
# matching format definition, so order matters if you expect the Accept
|
102
|
+
# header to contain any (a nil Accept header, for instance, will be
|
103
|
+
# turned into '*/*' as per rfc2616-sec14.1). Simply define the 'default'
|
104
|
+
# handler first (usually html), and it will work like a charm.
|
105
|
+
#
|
100
106
|
# ===== Examples
|
101
107
|
#
|
102
108
|
# RespondTo.media_types = ['text/html', 'application/xml']
|
@@ -123,19 +129,64 @@ module Rack
|
|
123
129
|
# end
|
124
130
|
# #=> nil
|
125
131
|
#
|
132
|
+
# RespondTo.media_types = ['*/*']
|
133
|
+
#
|
134
|
+
# respond_to do |format|
|
135
|
+
# format.html { 'html' }
|
136
|
+
# format.xml { 'xml' }
|
137
|
+
# end
|
138
|
+
# #=> 'html'
|
139
|
+
#
|
140
|
+
# RespondTo.media_types = ['*/*']
|
141
|
+
#
|
142
|
+
# respond_to do |format|
|
143
|
+
# format.xml { 'xml' }
|
144
|
+
# format.html { 'html' }
|
145
|
+
# end
|
146
|
+
# #=> 'xml'
|
147
|
+
#
|
148
|
+
# RespondTo.media_types = ['text/*']
|
149
|
+
#
|
150
|
+
# respond_to do |format|
|
151
|
+
# format.xml { 'xml' } # application/xml (skip)
|
152
|
+
# format.html { 'html' } # text/html (match)
|
153
|
+
# format.txt { 'txt' }
|
154
|
+
# end
|
155
|
+
# #=> 'html'
|
156
|
+
#
|
126
157
|
def respond_to
|
127
158
|
format = Format.new
|
128
159
|
yield format
|
129
|
-
type = RespondTo.media_types
|
160
|
+
type, handler = Helpers.match(RespondTo.media_types, format)
|
130
161
|
RespondTo.selected_media_type = type
|
131
|
-
handler = format[type]
|
132
162
|
handler.nil? ? nil : handler.call
|
133
163
|
end
|
134
164
|
end
|
135
165
|
|
136
|
-
|
166
|
+
# Helper methods, kept in a seperate namespace to avoid pollution.
|
167
|
+
module Helpers #:nodoc:
|
168
|
+
extend self
|
169
|
+
|
170
|
+
# TODO refactor
|
171
|
+
def match(media_types, format)
|
172
|
+
selected = []
|
173
|
+
accepted_types = media_types.map {|type| type.gsub(/\*/,'.*') }
|
174
|
+
accepted_types.each do |at|
|
175
|
+
format.each do |ht, handler|
|
176
|
+
(selected = [ht, handler]) and break if ht.match(at)
|
177
|
+
end
|
178
|
+
break unless selected.empty?
|
179
|
+
end
|
180
|
+
selected
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# NOTE
|
185
|
+
# Array instead of hash because order matters (wildcard type matches first
|
186
|
+
# handler)
|
187
|
+
class Format < Array #:nodoc:
|
137
188
|
def method_missing(format, *args, &handler)
|
138
|
-
self[RespondTo::MediaType(format.to_s)
|
189
|
+
self << [RespondTo::MediaType(format.to_s), handler]
|
139
190
|
end
|
140
191
|
end
|
141
192
|
end
|
data/rack-respond_to.gemspec
CHANGED
data/test/test_respond_to.rb
CHANGED
@@ -126,4 +126,45 @@ class TestRespondTo < Test::Unit::TestCase
|
|
126
126
|
assert_equal 'txt', body
|
127
127
|
assert_equal 'text/plain', Rack::RespondTo.selected_media_type
|
128
128
|
end
|
129
|
+
|
130
|
+
## wildcard media types
|
131
|
+
|
132
|
+
test "wildcard type matches first handler" do
|
133
|
+
Rack::RespondTo.media_types = %w( */* )
|
134
|
+
|
135
|
+
body = App.respond_to do |format|
|
136
|
+
format.xml { 'xml' }
|
137
|
+
format.txt { 'txt' }
|
138
|
+
end
|
139
|
+
assert_equal 'xml', body
|
140
|
+
|
141
|
+
body = App.respond_to do |format|
|
142
|
+
format.txt { 'txt' }
|
143
|
+
format.xml { 'xml' }
|
144
|
+
end
|
145
|
+
assert_equal 'txt', body
|
146
|
+
end
|
147
|
+
|
148
|
+
test "wildcard subtype matches first handler for type" do
|
149
|
+
Rack::RespondTo.media_types = %w( text/* )
|
150
|
+
|
151
|
+
body = App.respond_to do |format|
|
152
|
+
format.xml { 'xml' }
|
153
|
+
format.txt { 'txt' }
|
154
|
+
format.htm { 'htm' }
|
155
|
+
end
|
156
|
+
assert_equal 'txt', body
|
157
|
+
|
158
|
+
body = App.respond_to do |format|
|
159
|
+
format.xml { 'xml' }
|
160
|
+
format.htm { 'htm' }
|
161
|
+
format.txt { 'txt' }
|
162
|
+
end
|
163
|
+
assert_equal 'htm', body
|
164
|
+
|
165
|
+
body = App.respond_to do |format|
|
166
|
+
format.xml { 'xml' }
|
167
|
+
end
|
168
|
+
assert_equal nil, body
|
169
|
+
end
|
129
170
|
end
|