mynyml-rack-respond_to 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|