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
data/lib/strelka/httprequest.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'yajl'
|
4
|
+
require 'yaml'
|
3
5
|
require 'uri'
|
4
6
|
|
5
7
|
require 'mongrel2/httprequest'
|
6
8
|
require 'strelka' unless defined?( Strelka )
|
9
|
+
require 'strelka/httpresponse'
|
7
10
|
|
8
11
|
# An HTTP request class.
|
9
12
|
class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
@@ -14,11 +17,23 @@ class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
|
14
17
|
register_request_type( self, *HTTP::RFC2616_VERBS )
|
15
18
|
|
16
19
|
|
20
|
+
### Override the type of response returned by this request type.
|
21
|
+
def self::response_class
|
22
|
+
return Strelka::HTTPResponse
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#################################################################
|
27
|
+
### I N S T A N C E M E T H O D S
|
28
|
+
#################################################################
|
29
|
+
|
17
30
|
### Initialize some additional stuff for Strelka requests.
|
18
31
|
def initialize( * ) # :notnew:
|
19
32
|
super
|
20
|
-
@uri
|
21
|
-
@verb
|
33
|
+
@uri = nil
|
34
|
+
@verb = self.headers[:method].to_sym
|
35
|
+
@params = nil
|
36
|
+
@notes = Hash.new( &method(:autovivify) )
|
22
37
|
end
|
23
38
|
|
24
39
|
|
@@ -29,24 +44,157 @@ class Strelka::HTTPRequest < Mongrel2::HTTPRequest
|
|
29
44
|
# The HTTP verb of the request (as a Symbol)
|
30
45
|
attr_accessor :verb
|
31
46
|
|
47
|
+
# The parameters hash parsed from the request
|
48
|
+
attr_writer :params
|
49
|
+
|
50
|
+
# A Hash that plugins can use to pass data amongst themselves. The missing-key
|
51
|
+
# callback is set to auto-create nested sub-hashes.
|
52
|
+
attr_reader :notes
|
53
|
+
|
32
54
|
|
33
55
|
### Return a URI object parsed from the URI of the request.
|
56
|
+
###
|
57
|
+
### # "GET /user/1/profile HTTP/1.1"
|
58
|
+
### request.uri
|
59
|
+
### # => #<URI::HTTP:0x007fe34d16b2e0 URL:http://localhost:8080/user/1/profile>
|
34
60
|
def uri
|
35
|
-
|
61
|
+
unless @uri
|
62
|
+
# :TODO: Make this detect https scheme once I figure out how to
|
63
|
+
# detect it.
|
64
|
+
uri = "http://%s%s" % [
|
65
|
+
self.headers.host,
|
66
|
+
self.headers.uri
|
67
|
+
]
|
68
|
+
@uri = URI( uri )
|
69
|
+
end
|
70
|
+
|
71
|
+
return @uri
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
### Return a URI object for the base of the app being run. This is the #uri with the
|
76
|
+
### #app_path and any query string removed.
|
77
|
+
###
|
78
|
+
### # For a handler with a route of '/user', for the request:
|
79
|
+
### # "GET /user/1/profile HTTP/1.1"
|
80
|
+
### request.base_uri
|
81
|
+
### # => #<URI::HTTP:0x007fe34d16b2e0 URL:http://localhost:8080/user>
|
82
|
+
def base_uri
|
83
|
+
rval = self.uri
|
84
|
+
rval.path = self.route
|
85
|
+
rval.query = nil
|
86
|
+
return rval
|
36
87
|
end
|
37
88
|
|
38
89
|
|
39
90
|
### Return the portion of the Request's path that was routed by Mongrel2. This and the
|
40
91
|
### #app_path make up the #path.
|
41
|
-
|
92
|
+
###
|
93
|
+
### # For a handler with a route of '/user', for the request:
|
94
|
+
### # "GET /user/1/profile HTTP/1.1"
|
95
|
+
### request.route
|
96
|
+
### # => "/user"
|
97
|
+
def route
|
42
98
|
return self.headers.pattern
|
43
99
|
end
|
100
|
+
alias_method :pattern, :route
|
44
101
|
|
45
102
|
|
46
|
-
### Return the portion of the Request's path relative to the
|
47
|
-
###
|
103
|
+
### Return the portion of the Request's path relative to the request's #route.
|
104
|
+
###
|
105
|
+
### # For a handler with a route of '/user', for the request:
|
106
|
+
### # "GET /user/1/profile HTTP/1.1"
|
107
|
+
### request.app_path
|
108
|
+
### # => "/1/profile"
|
48
109
|
def app_path
|
49
|
-
|
110
|
+
rval = self.uri.path.dup
|
111
|
+
rval.slice!( 0, self.route.length )
|
112
|
+
return rval
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
### Parse the request parameters and return them as a Hash. For GET requests, these are
|
117
|
+
### take from the query arguments, and for POST requests, from the
|
118
|
+
###
|
119
|
+
### # For a handler with a route of '/user', for the request:
|
120
|
+
### # "GET /user/1/profile?checkbox=1&checkbox=2&text=foo HTTP/1.1"
|
121
|
+
### # r.params
|
122
|
+
### # => {"checkbox"=>["1", "2"], "text"=>"foo"}
|
123
|
+
def params
|
124
|
+
unless @params
|
125
|
+
case self.verb
|
126
|
+
when :GET, :HEAD
|
127
|
+
@params = self.parse_query_args
|
128
|
+
when :POST, :PUT
|
129
|
+
@params = self.parse_form_data
|
130
|
+
else
|
131
|
+
self.log.debug "No parameters for a %s request." % [ self.verb ]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
return @params
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
#########
|
140
|
+
protected
|
141
|
+
#########
|
142
|
+
|
143
|
+
### Return a Hash of request query arguments.
|
144
|
+
### ?arg1=yes&arg2=no&arg3 #=> {'arg1' => 'yes', 'arg2' => 'no', 'arg3' => nil}
|
145
|
+
def parse_query_args
|
146
|
+
return {} if self.uri.query.nil?
|
147
|
+
return merge_query_args( URI.decode_www_form(self.uri.query) )
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
### Return a Hash of request form data.
|
152
|
+
def parse_form_data
|
153
|
+
case self.headers.content_type
|
154
|
+
when 'application/x-www-form-urlencoded'
|
155
|
+
return merge_query_args( URI.decode_www_form(self.body) )
|
156
|
+
when 'application/json', 'text/javascript'
|
157
|
+
return Yajl.load( self.body )
|
158
|
+
when 'text/x-yaml', 'application/x-yaml'
|
159
|
+
return YAML.load( self.body )
|
160
|
+
when 'multipart/form-data'
|
161
|
+
raise NotImplementedError, "%p doesn't handle multipart form data yet" %
|
162
|
+
[ self.class ]
|
163
|
+
else
|
164
|
+
raise Strelka::Error, "don't know how to handle %p form data" %
|
165
|
+
[ self.headers.content_type ]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
#######
|
171
|
+
private
|
172
|
+
#######
|
173
|
+
|
174
|
+
### Return the given +enum+ containing query arguments (such as those returned from
|
175
|
+
### URI.decode_www_form) as a Hash, combining multiple values for the same key
|
176
|
+
### into an Array.
|
177
|
+
def merge_query_args( enum )
|
178
|
+
return enum.inject({}) do |hash,(key,val)|
|
179
|
+
|
180
|
+
# If there's already a value in the Hash, turn it into an array if
|
181
|
+
# it's not already, and append the new value
|
182
|
+
if hash.key?( key )
|
183
|
+
hash[ key ] = [ hash[key] ] unless hash[ key ].is_a?( Array )
|
184
|
+
hash[ key ] << val
|
185
|
+
else
|
186
|
+
hash[ key ] = val
|
187
|
+
end
|
188
|
+
|
189
|
+
hash
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
### Create and return a Hash that will auto-vivify any values it is missing with
|
195
|
+
### another auto-vivifying Hash.
|
196
|
+
def autovivify( hash, key )
|
197
|
+
hash[ key ] = Hash.new( &method(:autovivify) )
|
50
198
|
end
|
51
199
|
|
52
200
|
end # class Strelka::HTTPRequest
|