strelka 0.0.1pre4 → 0.0.1.pre129
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +1 -1
- data/IDEAS.rdoc +62 -0
- data/Manifest.txt +38 -7
- data/README.rdoc +124 -5
- data/Rakefile +22 -6
- data/bin/leash +102 -157
- data/contrib/hoetemplate/.autotest.erb +23 -0
- data/contrib/hoetemplate/History.rdoc.erb +4 -0
- data/contrib/hoetemplate/Manifest.txt.erb +8 -0
- data/contrib/hoetemplate/README.rdoc.erb +17 -0
- data/contrib/hoetemplate/Rakefile.erb +24 -0
- data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
- data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
- data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
- data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
- data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
- data/data/strelka/apps/hello-world +30 -0
- data/lib/strelka/app/defaultrouter.rb +49 -30
- data/lib/strelka/app/errors.rb +121 -0
- data/lib/strelka/app/exclusiverouter.rb +40 -0
- data/lib/strelka/app/filters.rb +18 -7
- data/lib/strelka/app/negotiation.rb +122 -0
- data/lib/strelka/app/parameters.rb +171 -14
- data/lib/strelka/app/paramvalidator.rb +751 -0
- data/lib/strelka/app/plugins.rb +66 -46
- data/lib/strelka/app/restresources.rb +499 -0
- data/lib/strelka/app/router.rb +73 -0
- data/lib/strelka/app/routing.rb +140 -18
- data/lib/strelka/app/templating.rb +12 -3
- data/lib/strelka/app.rb +174 -24
- data/lib/strelka/constants.rb +0 -20
- data/lib/strelka/exceptions.rb +29 -0
- data/lib/strelka/httprequest/acceptparams.rb +377 -0
- data/lib/strelka/httprequest/negotiation.rb +257 -0
- data/lib/strelka/httprequest.rb +155 -7
- data/lib/strelka/httpresponse/negotiation.rb +579 -0
- data/lib/strelka/httpresponse.rb +140 -0
- data/lib/strelka/logging.rb +4 -1
- data/lib/strelka/mixins.rb +53 -0
- data/lib/strelka.rb +22 -1
- data/spec/data/error.tmpl +1 -0
- data/spec/lib/constants.rb +0 -1
- data/spec/lib/helpers.rb +21 -0
- data/spec/strelka/app/defaultrouter_spec.rb +41 -35
- data/spec/strelka/app/errors_spec.rb +212 -0
- data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
- data/spec/strelka/app/filters_spec.rb +196 -0
- data/spec/strelka/app/negotiation_spec.rb +73 -0
- data/spec/strelka/app/parameters_spec.rb +149 -0
- data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
- data/spec/strelka/app/plugins_spec.rb +26 -19
- data/spec/strelka/app/restresources_spec.rb +393 -0
- data/spec/strelka/app/router_spec.rb +63 -0
- data/spec/strelka/app/routing_spec.rb +183 -9
- data/spec/strelka/app/templating_spec.rb +1 -2
- data/spec/strelka/app_spec.rb +265 -32
- data/spec/strelka/exceptions_spec.rb +53 -0
- data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
- data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
- data/spec/strelka/httprequest_spec.rb +204 -14
- data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
- data/spec/strelka/httpresponse_spec.rb +114 -0
- data/spec/strelka/mixins_spec.rb +99 -0
- data.tar.gz.sig +1 -0
- metadata +175 -79
- metadata.gz.sig +2 -0
- data/IDEAS.textile +0 -174
- data/data/strelka/apps/strelka-admin +0 -65
- data/data/strelka/apps/strelka-setup +0 -26
- data/data/strelka/bootstrap-config.rb +0 -34
- data/data/strelka/templates/admin/console.tmpl +0 -21
- data/data/strelka/templates/layout.tmpl +0 -30
- data/lib/strelka/process.rb +0 -19
@@ -0,0 +1,377 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'strelka/mixins'
|
4
|
+
require 'strelka/httprequest'
|
5
|
+
|
6
|
+
class Strelka::HTTPRequest
|
7
|
+
|
8
|
+
# A parser for request Accept, Accept-encoding, Accept-charset, and Accept-language
|
9
|
+
# header values. They provide weighted and wildcard comparisions between two values
|
10
|
+
# of the same field.
|
11
|
+
#
|
12
|
+
# require 'strelka/httprequest/acceptparam'
|
13
|
+
# mediatype = Strelka::HTTPRequest::AcceptParam.parse_mediatype( "text/html;q=0.9;level=2" )
|
14
|
+
#
|
15
|
+
# ap.type #=> 'text'
|
16
|
+
# ap.subtype #=> 'html'
|
17
|
+
# ap.qvalue #=> 0.9
|
18
|
+
# ap =~ 'text/*' #=> true
|
19
|
+
#
|
20
|
+
# language = Strelka::HTTPRequest::AcceptParam.parse_language( "en-gb" )
|
21
|
+
#
|
22
|
+
# ap.type #=> :en
|
23
|
+
# ap.subtype #=> :gb
|
24
|
+
# ap.qvalue #=> 1.0
|
25
|
+
# ap =~ 'en' #=> true
|
26
|
+
#
|
27
|
+
# encoding = Strelka::HTTPRequest::AcceptParam.parse_encoding( "compress; q=0.7" )
|
28
|
+
#
|
29
|
+
# ap.type #=> :compress
|
30
|
+
# ap.subtype #=> nil
|
31
|
+
# ap.qvalue #=> 0.7
|
32
|
+
# ap =~ 'compress' #=> true
|
33
|
+
#
|
34
|
+
# charset = Strelka::HTTPRequest::AcceptParam.parse_charset( "koi8-r" )
|
35
|
+
#
|
36
|
+
# ap.type #=> 'koi8-r'
|
37
|
+
# ap.subtype #=> nil
|
38
|
+
# ap.qvalue #=> 1.0
|
39
|
+
# ap =~ 'koi8-r' #=> true
|
40
|
+
#
|
41
|
+
# == Authors
|
42
|
+
#
|
43
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
44
|
+
# * Mahlon E. Smith <mahlon@martini.nu>
|
45
|
+
#
|
46
|
+
class AcceptParam
|
47
|
+
include Comparable,
|
48
|
+
Strelka::Loggable,
|
49
|
+
Strelka::AbstractClass
|
50
|
+
|
51
|
+
|
52
|
+
# The default quality value (weight) if none is specified
|
53
|
+
Q_DEFAULT = 1.0
|
54
|
+
|
55
|
+
# The maximum quality value
|
56
|
+
Q_MAX = Q_DEFAULT
|
57
|
+
|
58
|
+
|
59
|
+
#################################################################
|
60
|
+
### I N S T A N C E M E T H O D S
|
61
|
+
#################################################################
|
62
|
+
|
63
|
+
### Create a new Strelka::HTTPRequest::AcceptParam with the given media
|
64
|
+
### +range+, quality value (+qval+), and extensions
|
65
|
+
def initialize( type, subtype='*', qval=Q_DEFAULT, *extensions )
|
66
|
+
type = nil if type == '*'
|
67
|
+
subtype = nil if subtype == '*'
|
68
|
+
|
69
|
+
@type = type
|
70
|
+
@subtype = subtype
|
71
|
+
@qvalue = normalize_qvalue( qval )
|
72
|
+
@extensions = extensions.flatten
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
######
|
77
|
+
public
|
78
|
+
######
|
79
|
+
|
80
|
+
pure_virtual :to_s
|
81
|
+
|
82
|
+
|
83
|
+
# The 'type' part of the media range
|
84
|
+
attr_reader :type
|
85
|
+
|
86
|
+
# The 'subtype' part of the media range
|
87
|
+
attr_reader :subtype
|
88
|
+
|
89
|
+
# The weight of the param
|
90
|
+
attr_reader :qvalue
|
91
|
+
|
92
|
+
# An array of any accept-extensions specified with the parameter
|
93
|
+
attr_reader :extensions
|
94
|
+
|
95
|
+
|
96
|
+
### Match operator -- returns true if +other+ matches the receiving
|
97
|
+
### AcceptParam.
|
98
|
+
def =~( other )
|
99
|
+
unless other.is_a?( self.class )
|
100
|
+
other = self.class.parse( other.to_s ) rescue nil
|
101
|
+
return false unless other
|
102
|
+
end
|
103
|
+
|
104
|
+
# */* returns true in either side of the comparison.
|
105
|
+
# ASSUMPTION: There will never be a case when a type is wildcarded
|
106
|
+
# and the subtype is specific. (e.g., */xml)
|
107
|
+
# We gave up trying to read RFC 2045.
|
108
|
+
return true if other.type.nil? || self.type.nil?
|
109
|
+
|
110
|
+
# text/html =~ text/html
|
111
|
+
# text/* =~ text/html
|
112
|
+
# text/html =~ text/*
|
113
|
+
if other.type == self.type
|
114
|
+
return true if other.subtype.nil? || self.subtype.nil?
|
115
|
+
return true if other.subtype == self.subtype
|
116
|
+
end
|
117
|
+
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
### Return a human-readable version of the object
|
123
|
+
def inspect
|
124
|
+
return "#<%s:0x%07x '%s/%s' q=%0.3f %p>" % [
|
125
|
+
self.class.name,
|
126
|
+
self.object_id * 2,
|
127
|
+
self.type || '*',
|
128
|
+
self.subtype || '*',
|
129
|
+
self.qvalue,
|
130
|
+
self.extensions,
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
### The weighting or "qvalue" of the parameter in the form "q=<value>"
|
136
|
+
def qvaluestring
|
137
|
+
# 3 digit precision, trim excess zeros
|
138
|
+
return sprintf( "q=%0.3f", self.qvalue ).gsub(/0{1,2}$/, '')
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
### Return a String containing any extensions for this parameter, joined
|
143
|
+
### with ';'
|
144
|
+
def extension_strings
|
145
|
+
return nil if self.extensions.empty?
|
146
|
+
return self.extensions.compact.join('; ')
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
### Comparable interface. Sort parameters by weight: Returns -1 if +other+
|
151
|
+
### is less specific than the receiver, 0 if +other+ is as specific as
|
152
|
+
### the receiver, and +1 if +other+ is more specific than the receiver.
|
153
|
+
def <=>( other )
|
154
|
+
|
155
|
+
if rval = (other.qvalue <=> @qvalue).nonzero?
|
156
|
+
return rval
|
157
|
+
end
|
158
|
+
|
159
|
+
if self.type.nil?
|
160
|
+
return 1 if ! other.type.nil?
|
161
|
+
elsif other.type.nil?
|
162
|
+
return -1
|
163
|
+
end
|
164
|
+
|
165
|
+
if self.subtype.nil?
|
166
|
+
return 1 if ! other.subtype.nil?
|
167
|
+
elsif other.subtype.nil?
|
168
|
+
return -1
|
169
|
+
end
|
170
|
+
|
171
|
+
if rval = (self.extensions.length <=> other.extensions.length).nonzero?
|
172
|
+
return rval
|
173
|
+
end
|
174
|
+
|
175
|
+
return self.to_s <=> other.to_s
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
#######
|
180
|
+
private
|
181
|
+
#######
|
182
|
+
|
183
|
+
### Given an input +qvalue+, return the Float equivalent.
|
184
|
+
def normalize_qvalue( qvalue )
|
185
|
+
return Q_DEFAULT unless qvalue
|
186
|
+
qvalue = Float( qvalue.to_s.sub(/q=/, '') ) unless qvalue.is_a?( Float )
|
187
|
+
|
188
|
+
if qvalue > Q_MAX
|
189
|
+
self.log.warn "Squishing invalid qvalue %p to %0.1f" %
|
190
|
+
[ qvalue, Q_DEFAULT ]
|
191
|
+
return Q_DEFAULT
|
192
|
+
end
|
193
|
+
|
194
|
+
return qvalue
|
195
|
+
end
|
196
|
+
|
197
|
+
end # class AcceptParam
|
198
|
+
|
199
|
+
|
200
|
+
# A mediatype parameter such as one you'd find in an Accept header.
|
201
|
+
class MediaType < Strelka::HTTPRequest::AcceptParam
|
202
|
+
|
203
|
+
### Parse the given +accept_param+ as a mediatype and return a
|
204
|
+
### Strelka::HTTPRequest::MediaType object for it.
|
205
|
+
def self::parse( accept_param )
|
206
|
+
raise ArgumentError, "Bad Accept param: no media-range in %p" % [accept_param] unless
|
207
|
+
accept_param.include?( '/' )
|
208
|
+
media_range, *stuff = accept_param.split( /\s*;\s*/ )
|
209
|
+
type, subtype = media_range.downcase.split( '/', 2 )
|
210
|
+
qval, opts = stuff.partition {|par| par =~ /^q\s*=/ }
|
211
|
+
|
212
|
+
return new( type, subtype, qval.first, *opts )
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
### The mediatype of the parameter, consisting of the type and subtype
|
217
|
+
### separated by '/'.
|
218
|
+
def mediatype
|
219
|
+
return "%s/%s" % [ self.type || '*', self.subtype || '*' ]
|
220
|
+
end
|
221
|
+
alias_method :mimetype, :mediatype
|
222
|
+
alias_method :content_type, :mediatype
|
223
|
+
|
224
|
+
|
225
|
+
### Return the parameter as a String suitable for inclusion in an Accept
|
226
|
+
### HTTP header
|
227
|
+
def to_s
|
228
|
+
return [
|
229
|
+
self.mediatype,
|
230
|
+
self.qvaluestring,
|
231
|
+
self.extension_strings
|
232
|
+
].compact.join(';')
|
233
|
+
end
|
234
|
+
|
235
|
+
end # class MediaType
|
236
|
+
|
237
|
+
|
238
|
+
# A natural language specification parameter, such as one you'd find in an
|
239
|
+
# Accept-Language header.
|
240
|
+
class Language < Strelka::HTTPRequest::AcceptParam
|
241
|
+
|
242
|
+
### Parse the given +accept_param+ as a language range and return a
|
243
|
+
### Strelka::HTTPRequest::Language object for it.
|
244
|
+
def self::parse( accept_param )
|
245
|
+
language_range, *stuff = accept_param.split( /\s*;\s*/ )
|
246
|
+
type, subtype = language_range.downcase.split( '-', 2 )
|
247
|
+
qval, opts = stuff.partition {|par| par =~ /^q\s*=/ }
|
248
|
+
|
249
|
+
return new( type, subtype, qval.first, *opts )
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
######
|
254
|
+
public
|
255
|
+
######
|
256
|
+
|
257
|
+
alias_method :primary_tag, :type
|
258
|
+
alias_method :subtag, :subtype
|
259
|
+
|
260
|
+
### Return the language range of the parameter as a String.
|
261
|
+
def language_range
|
262
|
+
return [ self.primary_tag, self.subtag ].compact.join( '-' )
|
263
|
+
end
|
264
|
+
|
265
|
+
### Return the parameter as a String suitable for inclusion in an
|
266
|
+
### Accept-language header.
|
267
|
+
def to_s
|
268
|
+
return [
|
269
|
+
self.language_range,
|
270
|
+
self.qvaluestring,
|
271
|
+
self.extension_strings,
|
272
|
+
].compact.join( ';' )
|
273
|
+
end
|
274
|
+
|
275
|
+
end # class Language
|
276
|
+
|
277
|
+
|
278
|
+
# A content encoding parameter, such as one you'd find in an Accept-Encoding header.
|
279
|
+
class Encoding < Strelka::HTTPRequest::AcceptParam
|
280
|
+
|
281
|
+
### Parse the given +accept_param+ as a content coding and return a
|
282
|
+
### Strelka::HTTPRequest::Encoding object for it.
|
283
|
+
def self::parse( accept_param )
|
284
|
+
content_coding, *stuff = accept_param.split( /\s*;\s*/ )
|
285
|
+
qval, opts = stuff.partition {|par| par =~ /^q\s*=/ }
|
286
|
+
|
287
|
+
return new( content_coding, nil, qval.first, *opts )
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
######
|
292
|
+
public
|
293
|
+
######
|
294
|
+
|
295
|
+
alias_method :content_coding, :type
|
296
|
+
|
297
|
+
|
298
|
+
### Return the parameter as a String suitable for inclusion in an
|
299
|
+
### Accept-language header.
|
300
|
+
def to_s
|
301
|
+
return [
|
302
|
+
self.content_coding,
|
303
|
+
self.qvaluestring,
|
304
|
+
self.extension_strings,
|
305
|
+
].compact.join( ';' )
|
306
|
+
end
|
307
|
+
|
308
|
+
end # class Encoding
|
309
|
+
|
310
|
+
|
311
|
+
# A content character-set parameter, such as one you'd find in an Accept-Charset header.
|
312
|
+
class Charset < Strelka::HTTPRequest::AcceptParam
|
313
|
+
|
314
|
+
### Parse the given +accept_param+ as a charset and return a
|
315
|
+
### Strelka::HTTPRequest::Charset object for it.
|
316
|
+
def self::parse( accept_param )
|
317
|
+
charset, *stuff = accept_param.split( /\s*;\s*/ )
|
318
|
+
qval, opts = stuff.partition {|par| par =~ /^q\s*=/ }
|
319
|
+
|
320
|
+
return new( charset, nil, qval.first, *opts )
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
######
|
325
|
+
public
|
326
|
+
######
|
327
|
+
|
328
|
+
alias_method :name, :type
|
329
|
+
|
330
|
+
|
331
|
+
### Return the parameter as a String suitable for inclusion in an
|
332
|
+
### Accept-language header.
|
333
|
+
def to_s
|
334
|
+
return [
|
335
|
+
self.name,
|
336
|
+
self.qvaluestring,
|
337
|
+
self.extension_strings,
|
338
|
+
].compact.join( ';' )
|
339
|
+
end
|
340
|
+
|
341
|
+
|
342
|
+
### Return the Ruby Encoding object that is associated with the parameter's charset.
|
343
|
+
def encoding_object
|
344
|
+
return ::Encoding.find( self.name )
|
345
|
+
rescue ArgumentError => err
|
346
|
+
self.log.warn( err.message )
|
347
|
+
# self.log.debug( err.backtrace.join($/) )
|
348
|
+
return nil
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
### Match operator -- returns true if +other+ matches the receiving
|
353
|
+
### AcceptParam.
|
354
|
+
def =~( other )
|
355
|
+
unless other.is_a?( self.class )
|
356
|
+
other = self.class.parse( other.to_s ) rescue nil
|
357
|
+
return false unless other
|
358
|
+
end
|
359
|
+
|
360
|
+
# The special value "*", if present in the Accept-Charset field,
|
361
|
+
# matches every character set (including ISO-8859-1) which is not
|
362
|
+
# mentioned elsewhere in the Accept-Charset field.
|
363
|
+
return true if other.name.nil? || self.name.nil?
|
364
|
+
|
365
|
+
# Same downcased names or different names for the same encoding should match
|
366
|
+
return true if other.name.downcase == self.name.downcase ||
|
367
|
+
other.encoding_object == self.encoding_object
|
368
|
+
|
369
|
+
return false
|
370
|
+
end
|
371
|
+
|
372
|
+
end # class Charset
|
373
|
+
|
374
|
+
|
375
|
+
end # class Strelka::HTTPRequest
|
376
|
+
|
377
|
+
# vim: set nosta noet ts=4 sw=4:
|
@@ -0,0 +1,257 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'strelka/constants'
|
4
|
+
require 'strelka/httprequest' unless defined?( Strelka::HTTPRequest )
|
5
|
+
require 'strelka/httprequest/acceptparams'
|
6
|
+
|
7
|
+
|
8
|
+
# The mixin that adds methods to Strelka::HTTPRequest for content-negotiation.
|
9
|
+
#
|
10
|
+
# request.accepts?( 'application/json' )
|
11
|
+
# request.explicitly_accepts?( 'application/xml+rdf' )
|
12
|
+
# request.accepts_charset?( Encoding::UTF_8 )
|
13
|
+
# request.accepts_charset?( 'iso-8859-15' )
|
14
|
+
# request.accepts_encoding?( 'compress' )
|
15
|
+
# request.accepts_language?( 'en' )
|
16
|
+
# request.explicitly_accepts_language?( 'en' )
|
17
|
+
# request.explicitly_accepts_language?( 'en-gb' )
|
18
|
+
#
|
19
|
+
module Strelka::HTTPRequest::Negotiation
|
20
|
+
include Strelka::Constants
|
21
|
+
|
22
|
+
### Extension callback -- add instance variables to extended objects.
|
23
|
+
def initialize( * )
|
24
|
+
super
|
25
|
+
@accepted_mediatypes = nil
|
26
|
+
@accepted_charsets = nil
|
27
|
+
@accepted_encodings = nil
|
28
|
+
@accepted_languages = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
### Fetch the value of the given +header+, split apart the values, and parse
|
33
|
+
### each one using the specified +paramclass+. If no values are parsed from
|
34
|
+
### the header, and a block is given, the block is called and its return value
|
35
|
+
### is appended to the empty Array before returning it.
|
36
|
+
def parse_negotiation_header( header, paramclass )
|
37
|
+
self.log.debug "Parsing %s header into %p objects" % [ header, paramclass ]
|
38
|
+
rval = []
|
39
|
+
headerval = self.headers[ header ]
|
40
|
+
self.log.debug " raw header value: %p" % [ headerval ]
|
41
|
+
|
42
|
+
# Handle the case where there's more than one of the header in question by
|
43
|
+
# forcing everything to an Array
|
44
|
+
Array( headerval ).compact.flatten.each do |paramstr|
|
45
|
+
paramstr.split( /\s*,\s*/ ).each do |param|
|
46
|
+
self.log.debug " parsing param: %p" % [ param ]
|
47
|
+
rval << paramclass.parse( param )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if rval.empty? && block_given?
|
52
|
+
self.log.debug " no parsed values; calling the fallback block"
|
53
|
+
rval << yield
|
54
|
+
end
|
55
|
+
|
56
|
+
return rval.flatten
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
#
|
61
|
+
# :section: Mediatype negotiation
|
62
|
+
#
|
63
|
+
|
64
|
+
### Return an Array of Strelka::HTTPRequest::MediaType objects for each
|
65
|
+
### type in the 'Accept' header.
|
66
|
+
def accepted_mediatypes
|
67
|
+
@accepted_mediatypes ||= self.parse_accept_header
|
68
|
+
return @accepted_mediatypes
|
69
|
+
end
|
70
|
+
alias_method :accepted_types, :accepted_mediatypes
|
71
|
+
|
72
|
+
|
73
|
+
### Returns boolean true/false if the requestor can handle the given
|
74
|
+
### +content_type+.
|
75
|
+
def accepts?( content_type )
|
76
|
+
self.log.debug "Checking to see if request accepts %p" % [ content_type ]
|
77
|
+
atype = self.accepted_types.find {|type| type =~ content_type }
|
78
|
+
self.log.debug " find returned: %p" % [ atype ]
|
79
|
+
return atype ? true : false
|
80
|
+
end
|
81
|
+
alias_method :accept?, :accepts?
|
82
|
+
|
83
|
+
|
84
|
+
### Returns boolean true/false if the requestor can handle the given
|
85
|
+
### +content_type+, not including mime wildcards.
|
86
|
+
def explicitly_accepts?( content_type )
|
87
|
+
non_wildcard_types = self.accepted_types.reject {|param| param.subtype.nil? }
|
88
|
+
return non_wildcard_types.find {|type| type =~ content_type } ? true : false
|
89
|
+
end
|
90
|
+
alias_method :explicitly_accept?, :explicitly_accepts?
|
91
|
+
|
92
|
+
|
93
|
+
### Parse the receiver's 'Accept' header and return it as an Array of
|
94
|
+
### Strelka::HTTPRequest::MediaType objects.
|
95
|
+
def parse_accept_header
|
96
|
+
return self.parse_negotiation_header( :accept, Strelka::HTTPRequest::MediaType ) do
|
97
|
+
Strelka::HTTPRequest::MediaType.new( '*', '*' )
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
#
|
103
|
+
# :section: Charset negotiation
|
104
|
+
#
|
105
|
+
|
106
|
+
### Return an Array of Strelka::HTTPRequest::Charset objects for each
|
107
|
+
### type in the 'Accept-Charset' header.
|
108
|
+
def accepted_charsets
|
109
|
+
@accepted_charsets ||= self.parse_accept_charset_header
|
110
|
+
return @accepted_charsets
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
### Returns boolean true/false if the requestor can handle the given
|
115
|
+
### +charset+.
|
116
|
+
def accepts_charset?( charset )
|
117
|
+
self.log.debug "Checking to see if request accepts charset: %p" % [ charset ]
|
118
|
+
aset = self.accepted_charsets.find {|cs| cs =~ charset }
|
119
|
+
self.log.debug " find returned: %p" % [ aset ]
|
120
|
+
return aset ? true : false
|
121
|
+
end
|
122
|
+
alias_method :accept_charset?, :accepts_charset?
|
123
|
+
|
124
|
+
|
125
|
+
### Returns boolean true/false if the requestor can handle the given
|
126
|
+
### +charset+, not including the wildcard tag if present.
|
127
|
+
def explicitly_accepts_charset?( charset )
|
128
|
+
non_wildcard_charsets = self.accepted_charsets.reject {|param| param.charset.nil? }
|
129
|
+
return non_wildcard_charsets.find {|cs| cs =~ charset } ? true : false
|
130
|
+
end
|
131
|
+
alias_method :explicitly_accept_charset?, :explicitly_accepts_charset?
|
132
|
+
|
133
|
+
|
134
|
+
### Parse the receiver's 'Accept-Charset' header and return it as an Array of
|
135
|
+
### Strelka::HTTPRequest::Charset objects.
|
136
|
+
def parse_accept_charset_header
|
137
|
+
return self.parse_negotiation_header( :accept_charset, Strelka::HTTPRequest::Charset ) do
|
138
|
+
Strelka::HTTPRequest::Charset.new( '*' )
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
#
|
144
|
+
# :section: Encoding negotiation
|
145
|
+
#
|
146
|
+
|
147
|
+
### Return an Array of Strelka::HTTPRequest::Encoding objects for each
|
148
|
+
### type in the 'Accept-Encoding' header.
|
149
|
+
def accepted_encodings
|
150
|
+
@accepted_encodings ||= self.parse_accept_encoding_header
|
151
|
+
return @accepted_encodings
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
### Returns boolean true/false if the requestor can handle the given
|
156
|
+
### +encoding+.
|
157
|
+
def accepts_encoding?( encoding )
|
158
|
+
self.log.debug "Checking to see if request accepts encoding: %p" % [ encoding ]
|
159
|
+
return true if self.accepted_encodings.empty?
|
160
|
+
found_encoding = self.accepted_encodings.find {|enc| enc =~ encoding }
|
161
|
+
self.log.debug " find returned: %p" % [ found_encoding ]
|
162
|
+
|
163
|
+
# If there was no match, then it's not accepted, unless it's the 'identity'
|
164
|
+
# encoding, which is accepted unless it's disabled.
|
165
|
+
return encoding == 'identity' if !found_encoding
|
166
|
+
|
167
|
+
return found_encoding.qvalue.nonzero?
|
168
|
+
end
|
169
|
+
alias_method :accept_encoding?, :accepts_encoding?
|
170
|
+
|
171
|
+
|
172
|
+
### Returns boolean true/false if the requestor can handle the given
|
173
|
+
### +encoding+, not including the wildcard encoding if present.
|
174
|
+
def explicitly_accepts_encoding?( encoding )
|
175
|
+
non_wildcard_encodings = self.accepted_encodings.reject {|enc| enc.content_coding.nil? }
|
176
|
+
found_encoding = non_wildcard_encodings.find {|enc| enc =~ encoding } or
|
177
|
+
return false
|
178
|
+
return found_encoding.qvalue.nonzero?
|
179
|
+
end
|
180
|
+
alias_method :explicitly_accept_encoding?, :explicitly_accepts_encoding?
|
181
|
+
|
182
|
+
|
183
|
+
### Parse the receiver's 'Accept-Encoding' header and return it as an Array of
|
184
|
+
### Strelka::HTTPRequest::Encoding objects.
|
185
|
+
def parse_accept_encoding_header
|
186
|
+
return self.parse_negotiation_header( :accept_encoding, Strelka::HTTPRequest::Encoding ) do
|
187
|
+
# If the Accept-Encoding field-value is empty, then only the "identity"
|
188
|
+
# encoding is acceptable.
|
189
|
+
if self.headers.include?( :accept_encoding )
|
190
|
+
self.log.debug "Empty accept-encoding header: identity-only"
|
191
|
+
[ Strelka::HTTPRequest::Encoding.new('identity') ]
|
192
|
+
|
193
|
+
# I have no idea how this is different than an empty accept-encoding header
|
194
|
+
# for any practical case, but RFC2616 says:
|
195
|
+
# If no Accept-Encoding field is present in a request, the server MAY
|
196
|
+
# assume that the client will accept any content coding. In this
|
197
|
+
# case, if "identity" is one of the available content-codings, then
|
198
|
+
# the server SHOULD use the "identity" content-coding, unless it has
|
199
|
+
# additional information that a different content-coding is meaningful
|
200
|
+
# to the client.
|
201
|
+
else
|
202
|
+
self.log.debug "No accept-encoding header: identity + any encoding"
|
203
|
+
[
|
204
|
+
Strelka::HTTPRequest::Encoding.new( 'identity' ),
|
205
|
+
Strelka::HTTPRequest::Encoding.new( '*', nil, 0.9 )
|
206
|
+
]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
#
|
214
|
+
# :section: Language negotiation
|
215
|
+
#
|
216
|
+
|
217
|
+
### Return an Array of Strelka::HTTPRequest::Language objects for each
|
218
|
+
### type in the 'Accept-Language' header.
|
219
|
+
def accepted_languages
|
220
|
+
@accepted_languages ||= self.parse_accept_language_header
|
221
|
+
return @accepted_languages
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
### Returns boolean true/false if the requestor can handle the given
|
226
|
+
### +language+.
|
227
|
+
def accepts_language?( language )
|
228
|
+
self.log.debug "Checking to see if request accepts language: %p" % [ language ]
|
229
|
+
found_language = self.accepted_languages.find {|langcode| langcode =~ language }
|
230
|
+
self.log.debug " find returned: %p" % [ found_language ]
|
231
|
+
return found_language && found_language.qvalue.nonzero?
|
232
|
+
end
|
233
|
+
alias_method :accept_language?, :accepts_language?
|
234
|
+
|
235
|
+
|
236
|
+
### Returns boolean true/false if the requestor can handle the given
|
237
|
+
### +language+, not including the wildcard language if present.
|
238
|
+
def explicitly_accepts_language?( language )
|
239
|
+
non_wildcard_languages = self.accepted_languages.reject {|enc| enc.content_coding.nil? }
|
240
|
+
found_language = non_wildcard_languages.find {|enc| enc =~ language }
|
241
|
+
return found_language.qvalue.nonzero?
|
242
|
+
end
|
243
|
+
alias_method :explicitly_accept_language?, :explicitly_accepts_language?
|
244
|
+
|
245
|
+
|
246
|
+
### Parse the receiver's 'Accept-Language' header and return it as an Array of
|
247
|
+
### Strelka::HTTPRequest::Language objects.
|
248
|
+
def parse_accept_language_header
|
249
|
+
return self.parse_negotiation_header( :accept_language, Strelka::HTTPRequest::Language ) do
|
250
|
+
Strelka::HTTPRequest::Language.new( '*' )
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
end # module RequestMethods
|
256
|
+
|
257
|
+
|