strelka 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -3
- data/History.rdoc +19 -0
- data/Rakefile +6 -5
- data/lib/strelka.rb +2 -2
- data/lib/strelka/app.rb +8 -21
- data/lib/strelka/app/auth.rb +1 -1
- data/lib/strelka/app/restresources.rb +72 -20
- data/lib/strelka/app/sessions.rb +6 -4
- data/lib/strelka/authprovider.rb +1 -1
- data/lib/strelka/cookie.rb +2 -1
- data/lib/strelka/httprequest.rb +47 -43
- data/lib/strelka/httprequest/acceptparams.rb +3 -3
- data/lib/strelka/httprequest/negotiation.rb +4 -0
- data/lib/strelka/mixins.rb +27 -28
- data/lib/strelka/multipartparser.rb +1 -3
- data/lib/strelka/plugins.rb +1 -2
- data/lib/strelka/router.rb +2 -2
- data/lib/strelka/session.rb +3 -2
- data/lib/strelka/session/db.rb +1 -0
- data/spec/strelka/app/auth_spec.rb +48 -48
- data/spec/strelka/app/filters_spec.rb +8 -8
- data/spec/strelka/app/parameters_spec.rb +1 -1
- data/spec/strelka/app/restresources_spec.rb +69 -35
- data/spec/strelka/app/routing_spec.rb +1 -1
- data/spec/strelka/app/templating_spec.rb +1 -1
- data/spec/strelka/authprovider/basic_spec.rb +1 -1
- data/spec/strelka/authprovider/hostaccess_spec.rb +3 -3
- data/spec/strelka/cookie_spec.rb +6 -5
- data/spec/strelka/cookieset_spec.rb +1 -1
- data/spec/strelka/discovery_spec.rb +2 -2
- data/spec/strelka/httprequest/acceptparams_spec.rb +16 -16
- data/spec/strelka/httprequest/negotiation_spec.rb +73 -67
- data/spec/strelka/httprequest/session_spec.rb +2 -2
- data/spec/strelka/httprequest_spec.rb +38 -6
- data/spec/strelka/httpresponse/session_spec.rb +3 -3
- data/spec/strelka/mixins_spec.rb +3 -3
- data/spec/strelka/multipartparser_spec.rb +2 -2
- data/spec/strelka/paramvalidator_spec.rb +22 -22
- data/spec/strelka/plugins_spec.rb +1 -1
- data/spec/strelka/session/default_spec.rb +4 -4
- data/spec/strelka/websocketserver/routing_spec.rb +1 -1
- metadata +29 -15
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0b5c7ba99043fe79888689e95d555001a5ea70f
|
4
|
+
data.tar.gz: 2f113c4c3820c8b8fbf607dccc3e70e312899c55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e164cf5a1ad00a8093263ff9138f2a87d64998ac3f9154fb323237a922bf78c88f4f54f70d282c1847c642ae3ec1eec3d32ec6b0a9bc5ad43a55d3a1b950cd36
|
7
|
+
data.tar.gz: f141b866194eb71af3344a09f1b9ecfee65a1d8f6a48c989166e57a6e1024698b4aed3beb7fd642b9a284d4f422d21c760cf7b02588e5e50e264f984c2080ea9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
data/History.rdoc
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
== v0.8.0 [2014-02-05] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Make malformed headers and data consistently error with 400 status rather than
|
4
|
+
ignored by default.
|
5
|
+
|
6
|
+
- Fix PUT/POST routes in restresources to be more REST-y; i.e., POST
|
7
|
+
for non-idempotent methods, PUT for idempotent ones.
|
8
|
+
- Make Strelka::Cookie raise on malformed cookies
|
9
|
+
- Fix some API docs for sessions
|
10
|
+
- Remove config keys that moved to Discovery
|
11
|
+
- Restore access to request parameters from the authentication plugin.
|
12
|
+
- Merge improvements to the AbstractClass mixin from elsewhere.
|
13
|
+
- Fix use of deprecated RSpec syntax.
|
14
|
+
- Don't modify the original request URI object when calling
|
15
|
+
HttpRequest#base_uri.
|
16
|
+
- Add a convenience method for fetching a default app instance to
|
17
|
+
Strelka::App
|
18
|
+
|
19
|
+
|
1
20
|
== v0.7.0 [2013-10-21] Michael Granger <ged@FaerieMUD.org>
|
2
21
|
|
3
22
|
- Make response filters always receive a response even if the handler
|
data/Rakefile
CHANGED
@@ -23,20 +23,21 @@ hoespec = Hoe.spec 'strelka' do
|
|
23
23
|
self.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
|
24
24
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
25
25
|
|
26
|
-
self.dependency 'configurability', '~> 2.
|
26
|
+
self.dependency 'configurability', '~> 2.1'
|
27
27
|
self.dependency 'foreman', '~> 0.62'
|
28
28
|
self.dependency 'highline', '~> 1.6'
|
29
29
|
self.dependency 'inversion', '~> 0.12'
|
30
|
-
self.dependency 'loggability', '~> 0.
|
31
|
-
self.dependency 'mongrel2', '~> 0.
|
32
|
-
self.dependency 'pluggability', '~> 0.
|
30
|
+
self.dependency 'loggability', '~> 0.9'
|
31
|
+
self.dependency 'mongrel2', '~> 0.41'
|
32
|
+
self.dependency 'pluggability', '~> 0.4'
|
33
33
|
self.dependency 'sysexits', '~> 1.1'
|
34
34
|
self.dependency 'trollop', '~> 2.0'
|
35
35
|
self.dependency 'uuidtools', '~> 2.1'
|
36
|
-
self.dependency 'safe_yaml', '~> 0
|
36
|
+
self.dependency 'safe_yaml', '~> 1.0'
|
37
37
|
|
38
38
|
self.dependency 'hoe-deveiate', '~> 0.3', :developer
|
39
39
|
self.dependency 'hoe-bundler', '~> 1.2', :developer
|
40
|
+
self.dependency 'rspec', '~> 2.99.0.beta1', :developer
|
40
41
|
self.dependency 'simplecov', '~> 0.7', :developer
|
41
42
|
self.dependency 'rdoc-generator-fivefish', '~> 0.2', :developer
|
42
43
|
|
data/lib/strelka.rb
CHANGED
@@ -24,10 +24,10 @@ module Strelka
|
|
24
24
|
log_as :strelka
|
25
25
|
|
26
26
|
# Library version constant
|
27
|
-
VERSION = '0.
|
27
|
+
VERSION = '0.8.0'
|
28
28
|
|
29
29
|
# Version-control revision constant
|
30
|
-
REVISION = %q$Revision:
|
30
|
+
REVISION = %q$Revision: 140055f6ee81 $
|
31
31
|
|
32
32
|
require 'strelka/constants'
|
33
33
|
require 'strelka/exceptions'
|
data/lib/strelka/app.rb
CHANGED
@@ -30,19 +30,9 @@ class Strelka::App < Mongrel2::Handler
|
|
30
30
|
config_key :app
|
31
31
|
|
32
32
|
|
33
|
-
# Glob for matching Strelka apps relative to a gem's data directory
|
34
|
-
APP_GLOB_PATTERN = '{apps,handlers}/**/*'
|
35
|
-
APP_GLOB_PATTERN.freeze
|
36
|
-
|
37
|
-
# The glob for matching data directories relative to the PWD
|
38
|
-
LOCAL_DATA_DIRS = 'data/*'
|
39
|
-
LOCAL_DATA_DIRS.freeze
|
40
|
-
|
41
33
|
# Default config
|
42
34
|
CONFIG_DEFAULTS = {
|
43
35
|
devmode: false,
|
44
|
-
app_glob_pattern: APP_GLOB_PATTERN,
|
45
|
-
local_data_dirs: LOCAL_DATA_DIRS,
|
46
36
|
}.freeze
|
47
37
|
|
48
38
|
|
@@ -51,8 +41,6 @@ class Strelka::App < Mongrel2::Handler
|
|
51
41
|
@default_type = nil
|
52
42
|
@loading_file = nil
|
53
43
|
@subclasses = Hash.new {|h,k| h[k] = [] }
|
54
|
-
@app_glob_pattern = APP_GLOB_PATTERN
|
55
|
-
@local_data_dirs = LOCAL_DATA_DIRS
|
56
44
|
|
57
45
|
|
58
46
|
##
|
@@ -64,15 +52,6 @@ class Strelka::App < Mongrel2::Handler
|
|
64
52
|
# 'Developer mode' flag.
|
65
53
|
singleton_attr_writer :devmode
|
66
54
|
|
67
|
-
##
|
68
|
-
# The glob(3) pattern for matching Apps during discovery
|
69
|
-
singleton_attr_accessor :app_glob_pattern
|
70
|
-
|
71
|
-
##
|
72
|
-
# The glob(3) pattern for matching local data directories during discovery. Local
|
73
|
-
# data directories are evaluated relative to the CWD.
|
74
|
-
singleton_attr_accessor :local_data_dirs
|
75
|
-
|
76
55
|
|
77
56
|
### Returns +true+ if the application has been configured to run in 'developer mode'.
|
78
57
|
### Developer mode is mostly informational by default (it just makes logging more
|
@@ -121,6 +100,14 @@ class Strelka::App < Mongrel2::Handler
|
|
121
100
|
end
|
122
101
|
|
123
102
|
|
103
|
+
### Return an instance of the App configured for the handler in the currently-loaded
|
104
|
+
### Mongrel2 config that corresponds to the #default_appid.
|
105
|
+
def self::default_app_instance
|
106
|
+
appid = self.default_appid
|
107
|
+
return self.app_instance_for( appid )
|
108
|
+
end
|
109
|
+
|
110
|
+
|
124
111
|
#
|
125
112
|
# :section: Application declarative methods
|
126
113
|
#
|
data/lib/strelka/app/auth.rb
CHANGED
@@ -235,7 +235,7 @@ module Strelka::App::Auth
|
|
235
235
|
|
236
236
|
# Plugins API -- Set up load order
|
237
237
|
run_outside :routing, :restresources
|
238
|
-
run_inside :templating, :errors, :sessions
|
238
|
+
run_inside :templating, :errors, :sessions, :parameters
|
239
239
|
|
240
240
|
|
241
241
|
# The name of the default plugin to use for authentication
|
@@ -33,6 +33,7 @@ require 'strelka/app' unless defined?( Strelka::App )
|
|
33
33
|
# get 'customers'
|
34
34
|
# get 'customers/:id'
|
35
35
|
# post 'customers'
|
36
|
+
# post 'customers/:id'
|
36
37
|
# put 'customers'
|
37
38
|
# put 'customers/:id'
|
38
39
|
# delete 'customers'
|
@@ -176,9 +177,10 @@ module Strelka::App::RestResources
|
|
176
177
|
else
|
177
178
|
self.add_collection_create_handler( route, rsrcobj, options )
|
178
179
|
self.add_update_handler( route, rsrcobj, options )
|
179
|
-
self.
|
180
|
-
self.
|
180
|
+
self.add_collection_replace_handler( route, rsrcobj, options )
|
181
|
+
self.add_replace_handler( route, rsrcobj, options )
|
181
182
|
self.add_collection_deletion_handler( route, rsrcobj, options )
|
183
|
+
self.add_delete_handler( route, rsrcobj, options )
|
182
184
|
end
|
183
185
|
|
184
186
|
# Add any composite resources based on the +rsrcobj+'s associations
|
@@ -302,13 +304,13 @@ module Strelka::App::RestResources
|
|
302
304
|
[ rsrcobj, route ]
|
303
305
|
|
304
306
|
self.add_route( :POST, route, options ) do |req|
|
305
|
-
add_resource_params( req, rsrcobj )
|
307
|
+
add_resource_params( req.params, rsrcobj )
|
306
308
|
finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join(", ") ) unless
|
307
309
|
req.params.okay?
|
308
310
|
|
309
311
|
resource = rsrcobj.new( req.params.valid )
|
310
312
|
|
311
|
-
# Save it in a transaction, erroring if any
|
313
|
+
# Save it in a transaction, erroring if any validations fail
|
312
314
|
begin
|
313
315
|
resource.save
|
314
316
|
rescue Sequel::ValidationFailed => err
|
@@ -333,15 +335,15 @@ module Strelka::App::RestResources
|
|
333
335
|
|
334
336
|
|
335
337
|
### Add a handler method for updating an instance of +rsrcobj+.
|
336
|
-
###
|
338
|
+
### POST /resources/{id}
|
337
339
|
def add_update_handler( route_prefix, rsrcobj, options )
|
338
340
|
pkey = rsrcobj.primary_key
|
339
341
|
route = "#{route_prefix}/:#{pkey}"
|
340
342
|
|
341
|
-
self.log.debug "Creating handler for
|
343
|
+
self.log.debug "Creating handler for updating a single %p resource: POST %s" %
|
342
344
|
[ rsrcobj, route ]
|
343
|
-
self.add_route( :
|
344
|
-
add_resource_params( req, rsrcobj )
|
345
|
+
self.add_route( :POST, route, options ) do |req|
|
346
|
+
add_resource_params( req.params, rsrcobj )
|
345
347
|
finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join(", ") ) unless
|
346
348
|
req.params.okay?
|
347
349
|
|
@@ -365,31 +367,81 @@ module Strelka::App::RestResources
|
|
365
367
|
return res
|
366
368
|
end
|
367
369
|
|
370
|
+
self.resource_verbs[ route_prefix ] << :POST
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
### Add a handler method for replacing an instance of +rsrcobj+.
|
375
|
+
### PUT /resources/{id}
|
376
|
+
def add_replace_handler( route_prefix, rsrcobj, options )
|
377
|
+
pkey = rsrcobj.primary_key
|
378
|
+
route = "#{route_prefix}/:#{pkey}"
|
379
|
+
|
380
|
+
self.log.debug "Creating handler for replacing %p a resource: PUT %s" %
|
381
|
+
[ rsrcobj, route ]
|
382
|
+
self.add_route( :PUT, route, options ) do |req|
|
383
|
+
add_resource_params( req.params, rsrcobj )
|
384
|
+
finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join(", ") ) unless
|
385
|
+
req.params.okay?
|
386
|
+
|
387
|
+
id = req.params[ pkey ]
|
388
|
+
resource = rsrcobj[ id ] or
|
389
|
+
finish_with( HTTP::NOT_FOUND, "no such %s [%p]" % [ rsrcobj.name, id ] )
|
390
|
+
|
391
|
+
newvals = req.params.valid
|
392
|
+
self.log.debug "Replacing %p: %p" % [ resource, newvals ]
|
393
|
+
|
394
|
+
begin
|
395
|
+
resource.values.clear
|
396
|
+
resource[ pkey ] = newvals.delete( pkey.to_sym )
|
397
|
+
resource.set( newvals )
|
398
|
+
resource.save
|
399
|
+
rescue Sequel::Error => err
|
400
|
+
finish_with( HTTP::BAD_REQUEST, err.message )
|
401
|
+
end
|
402
|
+
|
403
|
+
res = req.response
|
404
|
+
res.status = HTTP::NO_CONTENT
|
405
|
+
|
406
|
+
return res
|
407
|
+
end
|
408
|
+
|
368
409
|
self.resource_verbs[ route_prefix ] << :PUT
|
369
410
|
end
|
370
411
|
|
371
412
|
|
372
413
|
### Add a handler method for replacing all instances of +rsrcobj+ collection.
|
373
414
|
### PUT /resources
|
374
|
-
def
|
415
|
+
def add_collection_replace_handler( route, rsrcobj, options )
|
375
416
|
pkey = rsrcobj.primary_key
|
376
|
-
self.log.debug "Creating handler for
|
417
|
+
self.log.debug "Creating handler for replacing all %p resources: PUT %s" %
|
377
418
|
[ rsrcobj, route ]
|
378
419
|
|
379
420
|
self.add_route( :PUT, route, options ) do |req|
|
380
|
-
add_resource_params( req, rsrcobj )
|
381
|
-
finish_with( HTTP::BAD_REQUEST, req.params.error_messages.join(", ") ) unless
|
382
|
-
req.params.okay?
|
383
421
|
|
384
|
-
|
385
|
-
|
386
|
-
|
422
|
+
# Make a validator that can be reused to validate each resource's attributes
|
423
|
+
validator = self.class.paramvalidator.dup
|
424
|
+
add_resource_params( validator, rsrcobj )
|
425
|
+
body = req.parse_body
|
426
|
+
body = [ body ] unless body.is_a?( Array )
|
427
|
+
|
428
|
+
# Create resource objects out of the incoming data
|
429
|
+
new_resources = []
|
430
|
+
body.each do |attributes|
|
431
|
+
validator.validate( attributes )
|
432
|
+
finish_with( HTTP::BAD_REQUEST, validator.error_messages.join(", ") ) unless
|
433
|
+
validator.okay?
|
434
|
+
|
435
|
+
new_resources << rsrcobj.new( validator.valid )
|
436
|
+
end
|
437
|
+
self.log.debug "Replacing %p collection with new values: %p" %
|
438
|
+
[ rsrcobj, new_resources ]
|
387
439
|
|
388
440
|
# Save it in a transaction, erroring if any of 'em fail validations
|
389
441
|
begin
|
390
442
|
rsrcobj.db.transaction do
|
391
443
|
rsrcobj.truncate
|
392
|
-
|
444
|
+
new_resources.each( &:save )
|
393
445
|
end
|
394
446
|
rescue Sequel::ValidationFailed => err
|
395
447
|
finish_with( HTTP::BAD_REQUEST, err.message )
|
@@ -632,14 +684,14 @@ module Strelka::App::RestResources
|
|
632
684
|
#######
|
633
685
|
|
634
686
|
### Add parameter validations for the given +columns+ of the specified resource object +rsrcobj+
|
635
|
-
### to the specified +
|
636
|
-
def add_resource_params(
|
687
|
+
### to the specified parameter +validator+.
|
688
|
+
def add_resource_params( validator, rsrcobj, *columns )
|
637
689
|
columns = rsrcobj.allowed_columns || rsrcobj.columns if columns.empty?
|
638
690
|
|
639
691
|
columns.each do |col|
|
640
692
|
config = rsrcobj.db_schema[ col ] or
|
641
693
|
raise ArgumentError, "no such column %p for %p" % [ col, rsrcobj ]
|
642
|
-
|
694
|
+
validator.add( col, config[:type] ) unless validator.param_names.include?( col.to_s )
|
643
695
|
end
|
644
696
|
|
645
697
|
end
|
data/lib/strelka/app/sessions.rb
CHANGED
@@ -58,7 +58,8 @@ require 'strelka/httpresponse/session'
|
|
58
58
|
# == Configuration
|
59
59
|
#
|
60
60
|
# To specify which Session class to use with your application, add a
|
61
|
-
# ':sessions' section with at least the '
|
61
|
+
# ':sessions' section with at least the 'session_class' key to your
|
62
|
+
# config.yml:
|
62
63
|
#
|
63
64
|
# # Use the default session class, but change the name of the cookie
|
64
65
|
# # it uses
|
@@ -77,9 +78,10 @@ require 'strelka/httpresponse/session'
|
|
77
78
|
# connect: "postgres://pg.example.com/db01"
|
78
79
|
# table_name: sessions
|
79
80
|
#
|
80
|
-
# The +
|
81
|
-
# for more information about how this works), and the
|
82
|
-
# is passed to the session class's ::configure method
|
81
|
+
# The +session_class+ value will be used to look up the class (see
|
82
|
+
# Strelka::Session for more information about how this works), and the
|
83
|
+
# +options+ section is passed to the session class's ::configure method
|
84
|
+
# (if it has one).
|
83
85
|
#
|
84
86
|
module Strelka::App::Sessions
|
85
87
|
extend Strelka::Plugin,
|
data/lib/strelka/authprovider.rb
CHANGED
@@ -30,9 +30,9 @@ require 'strelka/mixins'
|
|
30
30
|
class Strelka::AuthProvider
|
31
31
|
extend Loggability,
|
32
32
|
Pluggability,
|
33
|
+
Strelka::AbstractClass,
|
33
34
|
Strelka::Delegation
|
34
35
|
include Strelka::Constants,
|
35
|
-
Strelka::AbstractClass,
|
36
36
|
Strelka::ResponseHelpers
|
37
37
|
|
38
38
|
# Loggability API -- set up logging under the 'strelka' log host
|
data/lib/strelka/cookie.rb
CHANGED
@@ -75,7 +75,8 @@ class Strelka::Cookie
|
|
75
75
|
# cookie-string = cookie-pair *( ";" SP cookie-pair )
|
76
76
|
header.split( /;\x20/ ).each do |cookie_pair|
|
77
77
|
# self.log.debug " parsing cookie-pair: %p" % [ cookie_pair ]
|
78
|
-
|
78
|
+
match = cookie_pair.match( COOKIE_PAIR ) or
|
79
|
+
raise Strelka::ParseError, "malformed cookie pair: %p" % [ cookie_pair ]
|
79
80
|
|
80
81
|
# self.log.debug " matched cookie: %p" % [ match ]
|
81
82
|
name = match[:cookie_name].untaint
|
data/lib/strelka/httprequest.rb
CHANGED
@@ -144,11 +144,11 @@ class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
|
144
144
|
when :GET, :HEAD
|
145
145
|
value = self.parse_query_args
|
146
146
|
when :POST, :PUT
|
147
|
-
value = self.
|
147
|
+
value = self.parse_body
|
148
148
|
when :TRACE
|
149
149
|
self.log.debug "No parameters for a TRACE request."
|
150
150
|
else
|
151
|
-
value = self.
|
151
|
+
value = self.parse_body if self.content_type
|
152
152
|
end
|
153
153
|
|
154
154
|
value = Hash.new( value ) unless value.is_a?( Hash )
|
@@ -156,56 +156,26 @@ class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
|
156
156
|
end
|
157
157
|
|
158
158
|
return @params
|
159
|
-
|
160
|
-
|
159
|
+
rescue => err
|
160
|
+
self.log.error "%p while parsing the request body: %s" % [ err.class, err.message ]
|
161
|
+
self.log.debug " %s" % [ err.backtrace.join("\n ") ]
|
161
162
|
|
162
|
-
|
163
|
-
### it if necessary.
|
164
|
-
def cookies
|
165
|
-
@cookies = Strelka::CookieSet.parse( self ) unless @cookies
|
166
|
-
return @cookies
|
167
|
-
end
|
168
|
-
|
169
|
-
|
170
|
-
### A convenience method for redirecting a request to another URI.
|
171
|
-
def redirect( uri, perm=false )
|
172
|
-
code = perm ? HTTP::MOVED_PERMANENTLY : HTTP::MOVED_TEMPORARILY
|
173
|
-
finish_with( code, "redirect from #{self.uri.path} to #{uri}", :location => uri )
|
174
|
-
end
|
175
|
-
|
176
|
-
|
177
|
-
#########
|
178
|
-
protected
|
179
|
-
#########
|
180
|
-
|
181
|
-
### Return a Hash of request query arguments.
|
182
|
-
### ?arg1=yes&arg2=no&arg3 #=> {'arg1' => 'yes', 'arg2' => 'no', 'arg3' => nil}
|
183
|
-
def parse_query_args
|
184
|
-
return {} if self.uri.query.nil?
|
185
|
-
query_args = begin
|
186
|
-
URI.decode_www_form( self.uri.query )
|
187
|
-
rescue => err
|
188
|
-
self.log.error "%p while parsing query %p: %s" %
|
189
|
-
[ err.class, self.uri.query, err.message ]
|
190
|
-
{}
|
191
|
-
end
|
192
|
-
|
193
|
-
return merge_query_args( query_args )
|
163
|
+
finish_with( HTTP::BAD_REQUEST, "Malformed request body or missing content type." )
|
194
164
|
end
|
195
165
|
|
196
166
|
|
197
167
|
# multipart/form-data: http://tools.ietf.org/html/rfc2388
|
198
168
|
# Content-disposition header: http://tools.ietf.org/html/rfc2183
|
199
169
|
|
200
|
-
###
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
170
|
+
### Parse the request body if it's a representation of a complex data
|
171
|
+
### structure.
|
172
|
+
def parse_body
|
173
|
+
mimetype = self.content_type or
|
174
|
+
raise ArgumentError, "Malformed request (no content type?)"
|
205
175
|
|
206
176
|
self.body.rewind
|
207
177
|
|
208
|
-
case
|
178
|
+
case mimetype.split( ';' ).first
|
209
179
|
when 'application/x-www-form-urlencoded'
|
210
180
|
return merge_query_args( URI.decode_www_form(self.body.read) )
|
211
181
|
when 'application/json', 'text/javascript'
|
@@ -222,12 +192,46 @@ class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
|
222
192
|
parser = Strelka::MultipartParser.new( self.body, boundary )
|
223
193
|
return parser.parse
|
224
194
|
else
|
225
|
-
self.log.debug "
|
195
|
+
self.log.debug "don't know how to parse a %p request" % [ self.content_type ]
|
226
196
|
return {}
|
227
197
|
end
|
228
198
|
end
|
229
199
|
|
230
200
|
|
201
|
+
### Fetch any cookies that accompanied the request as a Strelka::CookieSet, creating
|
202
|
+
### it if necessary.
|
203
|
+
def cookies
|
204
|
+
@cookies = Strelka::CookieSet.parse( self ) unless @cookies
|
205
|
+
return @cookies
|
206
|
+
rescue => err
|
207
|
+
self.log.error "%p while parsing cookies: %s" % [ err.class, err.message ]
|
208
|
+
self.log.debug " %s" % [ err.backtrace.join("\n ") ]
|
209
|
+
|
210
|
+
finish_with( HTTP::BAD_REQUEST, "Malformed cookie header." )
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
### A convenience method for redirecting a request to another URI.
|
215
|
+
def redirect( uri, perm=false )
|
216
|
+
code = perm ? HTTP::MOVED_PERMANENTLY : HTTP::MOVED_TEMPORARILY
|
217
|
+
finish_with( code, "redirect from #{self.uri.path} to #{uri}", :location => uri )
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
#########
|
222
|
+
protected
|
223
|
+
#########
|
224
|
+
|
225
|
+
### Return a Hash of request query arguments.
|
226
|
+
### ?arg1=yes&arg2=no&arg3 #=> {'arg1' => 'yes', 'arg2' => 'no', 'arg3' => nil}
|
227
|
+
def parse_query_args
|
228
|
+
return {} if self.uri.query.nil?
|
229
|
+
|
230
|
+
query_args = URI.decode_www_form( self.uri.query )
|
231
|
+
return merge_query_args( query_args )
|
232
|
+
end
|
233
|
+
|
234
|
+
|
231
235
|
#######
|
232
236
|
private
|
233
237
|
#######
|