mongrel2 0.0.1
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.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/History.rdoc +4 -0
- data/Manifest.txt +66 -0
- data/README.rdoc +169 -0
- data/Rakefile +77 -0
- data/bin/m2sh.rb +600 -0
- data/data/mongrel2/bootstrap.html +25 -0
- data/data/mongrel2/config.sql +84 -0
- data/data/mongrel2/mimetypes.sql +855 -0
- data/examples/README.txt +6 -0
- data/examples/config.rb +54 -0
- data/examples/helloworld-handler.rb +31 -0
- data/examples/request-dumper.rb +45 -0
- data/examples/request-dumper.tmpl +71 -0
- data/examples/run +17 -0
- data/lib/mongrel2.rb +62 -0
- data/lib/mongrel2/config.rb +212 -0
- data/lib/mongrel2/config/directory.rb +78 -0
- data/lib/mongrel2/config/dsl.rb +206 -0
- data/lib/mongrel2/config/handler.rb +124 -0
- data/lib/mongrel2/config/host.rb +88 -0
- data/lib/mongrel2/config/log.rb +48 -0
- data/lib/mongrel2/config/mimetype.rb +15 -0
- data/lib/mongrel2/config/proxy.rb +15 -0
- data/lib/mongrel2/config/route.rb +51 -0
- data/lib/mongrel2/config/server.rb +58 -0
- data/lib/mongrel2/config/setting.rb +15 -0
- data/lib/mongrel2/config/statistic.rb +23 -0
- data/lib/mongrel2/connection.rb +212 -0
- data/lib/mongrel2/constants.rb +159 -0
- data/lib/mongrel2/control.rb +165 -0
- data/lib/mongrel2/exceptions.rb +59 -0
- data/lib/mongrel2/handler.rb +309 -0
- data/lib/mongrel2/httprequest.rb +51 -0
- data/lib/mongrel2/httpresponse.rb +187 -0
- data/lib/mongrel2/jsonrequest.rb +43 -0
- data/lib/mongrel2/logging.rb +241 -0
- data/lib/mongrel2/mixins.rb +143 -0
- data/lib/mongrel2/request.rb +148 -0
- data/lib/mongrel2/response.rb +74 -0
- data/lib/mongrel2/table.rb +216 -0
- data/lib/mongrel2/xmlrequest.rb +36 -0
- data/spec/lib/constants.rb +237 -0
- data/spec/lib/helpers.rb +246 -0
- data/spec/lib/matchers.rb +50 -0
- data/spec/mongrel2/config/directory_spec.rb +91 -0
- data/spec/mongrel2/config/dsl_spec.rb +218 -0
- data/spec/mongrel2/config/handler_spec.rb +118 -0
- data/spec/mongrel2/config/host_spec.rb +30 -0
- data/spec/mongrel2/config/log_spec.rb +95 -0
- data/spec/mongrel2/config/proxy_spec.rb +30 -0
- data/spec/mongrel2/config/route_spec.rb +83 -0
- data/spec/mongrel2/config/server_spec.rb +84 -0
- data/spec/mongrel2/config/setting_spec.rb +30 -0
- data/spec/mongrel2/config/statistic_spec.rb +30 -0
- data/spec/mongrel2/config_spec.rb +111 -0
- data/spec/mongrel2/connection_spec.rb +172 -0
- data/spec/mongrel2/constants_spec.rb +32 -0
- data/spec/mongrel2/control_spec.rb +192 -0
- data/spec/mongrel2/handler_spec.rb +261 -0
- data/spec/mongrel2/httpresponse_spec.rb +232 -0
- data/spec/mongrel2/logging_spec.rb +76 -0
- data/spec/mongrel2/mixins_spec.rb +62 -0
- data/spec/mongrel2/request_spec.rb +157 -0
- data/spec/mongrel2/response_spec.rb +81 -0
- data/spec/mongrel2/table_spec.rb +176 -0
- data/spec/mongrel2_spec.rb +34 -0
- metadata +294 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
require 'mongrel2/request' unless defined?( Mongrel2::Request )
|
6
|
+
require 'mongrel2/mixins'
|
7
|
+
|
8
|
+
|
9
|
+
# The Mongrel2 XML Request class. Instances of this class represent a request for an XML route from
|
10
|
+
# a Mongrel2 server.
|
11
|
+
class Mongrel2::XMLRequest < Mongrel2::Request
|
12
|
+
include Mongrel2::Loggable
|
13
|
+
|
14
|
+
register_request_type( self, :XML )
|
15
|
+
|
16
|
+
|
17
|
+
### Parse the body as JSON.
|
18
|
+
def initialize( sender_id, conn_id, path, headers, body, raw=nil )
|
19
|
+
super
|
20
|
+
self.log.debug "Parsing XML request body"
|
21
|
+
@data = Nokogiri::XML( body )
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
######
|
26
|
+
public
|
27
|
+
######
|
28
|
+
|
29
|
+
# The parsed request data (a Nokogiri::XML document)
|
30
|
+
attr_reader :data
|
31
|
+
|
32
|
+
|
33
|
+
end # class Mongrel2::XMLRequest
|
34
|
+
|
35
|
+
# vim: set nosta noet ts=4 sw=4:
|
36
|
+
|
@@ -0,0 +1,237 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'yajl'
|
5
|
+
require 'tnetstring'
|
6
|
+
|
7
|
+
require 'mongrel2' unless defined?( Mongrel2 )
|
8
|
+
|
9
|
+
|
10
|
+
### A collection of constants used in testing
|
11
|
+
module Mongrel2::TestConstants # :nodoc:all
|
12
|
+
|
13
|
+
include Mongrel2::Constants
|
14
|
+
|
15
|
+
unless defined?( TEST_HOST )
|
16
|
+
|
17
|
+
TEST_HOST = 'localhost'
|
18
|
+
TEST_PORT = 8118
|
19
|
+
|
20
|
+
# Rule 2: Every message to and from Mongrel2 has that Mongrel2 instances
|
21
|
+
# UUID as the very first thing.
|
22
|
+
TEST_UUID = 'BD17D85C-4730-4BF2-999D-9D2B2E0FCCF9'
|
23
|
+
|
24
|
+
# 0mq socket specifications for Handlers
|
25
|
+
TEST_SEND_SPEC = 'tcp://127.0.0.1:9998'
|
26
|
+
TEST_RECV_SPEC = 'tcp://127.0.0.1:9997'
|
27
|
+
|
28
|
+
# Rule 3: Mongrel2 sends requests with one number right after the
|
29
|
+
# servers UUID separated by a space. Handlers return a netstring with
|
30
|
+
# a list of numbers separated by spaces. The numbers indicate the
|
31
|
+
# connected browser the message is to/from.
|
32
|
+
TEST_ID = 8
|
33
|
+
|
34
|
+
#
|
35
|
+
# HTTP request constants
|
36
|
+
#
|
37
|
+
|
38
|
+
TEST_ROUTE = '/handler'
|
39
|
+
TEST_PATH = TEST_ROUTE
|
40
|
+
TEST_QUERY = 'thing=foom'
|
41
|
+
|
42
|
+
TEST_HEADERS = {
|
43
|
+
"x-forwarded-for" => "127.0.0.1",
|
44
|
+
"accept-language" => "en-US,en;q=0.8",
|
45
|
+
"accept-encoding" => "gzip,deflate,sdch",
|
46
|
+
"connection" => "keep-alive",
|
47
|
+
"accept-charset" => "UTF-8,*;q=0.5",
|
48
|
+
"accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
49
|
+
"user-agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) " +
|
50
|
+
"AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 " +
|
51
|
+
"Safari/535.1",
|
52
|
+
"host" => "localhost:3667",
|
53
|
+
"METHOD" => "GET",
|
54
|
+
"VERSION" => "HTTP/1.1",
|
55
|
+
}
|
56
|
+
|
57
|
+
TEST_BODY = ''
|
58
|
+
|
59
|
+
TEST_REQUEST_OPTS = {
|
60
|
+
:uuid => TEST_UUID,
|
61
|
+
:id => TEST_ID,
|
62
|
+
:path => TEST_PATH,
|
63
|
+
:body => TEST_BODY,
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
#
|
68
|
+
# JSON (JSSocket, etc.) request constants
|
69
|
+
#
|
70
|
+
|
71
|
+
TEST_JSON_PATH = '@directory'
|
72
|
+
|
73
|
+
TEST_JSON_HEADERS = {
|
74
|
+
'PATH' => TEST_JSON_PATH,
|
75
|
+
'x-forwarded-for' => "127.0.0.1",
|
76
|
+
'METHOD' => "JSON",
|
77
|
+
'PATTERN' => TEST_JSON_PATH,
|
78
|
+
}
|
79
|
+
TEST_JSON_BODY = { 'type' => 'msg', 'msg' => 'connect' }
|
80
|
+
|
81
|
+
TEST_JSON_REQUEST_OPTS = {
|
82
|
+
:uuid => TEST_UUID,
|
83
|
+
:id => TEST_ID,
|
84
|
+
:path => TEST_JSON_PATH,
|
85
|
+
:body => TEST_JSON_BODY,
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
#
|
90
|
+
# XML message request constants
|
91
|
+
#
|
92
|
+
|
93
|
+
TEST_XML_PATH = '<directory'
|
94
|
+
|
95
|
+
TEST_XML_HEADERS = {
|
96
|
+
'PATH' => TEST_XML_PATH,
|
97
|
+
'x-forwarded-for' => "127.0.0.1",
|
98
|
+
'METHOD' => "XML",
|
99
|
+
'PATTERN' => TEST_XML_PATH,
|
100
|
+
}
|
101
|
+
TEST_XML_BODY = '<directory><file name="foom.txt" /><file name="foom2.md" /></directory>'
|
102
|
+
|
103
|
+
TEST_XML_REQUEST_OPTS = {
|
104
|
+
:uuid => TEST_UUID,
|
105
|
+
:id => TEST_ID,
|
106
|
+
:path => TEST_XML_PATH,
|
107
|
+
:body => TEST_XML_BODY,
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
#
|
112
|
+
# HTTP constants
|
113
|
+
#
|
114
|
+
|
115
|
+
# Space
|
116
|
+
SP = '\\x20'
|
117
|
+
|
118
|
+
# Network EOL
|
119
|
+
CRLF = '\\r\\n'
|
120
|
+
|
121
|
+
# Pattern to match the contents of ETag and If-None-Match headers
|
122
|
+
ENTITY_TAG_PATTERN = %r{
|
123
|
+
(w/)? # Weak flag
|
124
|
+
" # Opaque-tag
|
125
|
+
([^"]+) # Quoted-string
|
126
|
+
" # Closing quote
|
127
|
+
}ix
|
128
|
+
|
129
|
+
# Separators = "(" | ")" | "<" | ">" | "@"
|
130
|
+
# | "," | ";" | ":" | "\" | <">
|
131
|
+
# | "/" | "[" | "]" | "?" | "="
|
132
|
+
# | "{" | "}" | SP | HT
|
133
|
+
SEPARATORS = Regexp.quote("(\")<>@,;:\\/[]?={} \t")
|
134
|
+
|
135
|
+
# token = 1*<any CHAR except CTLs or separators>
|
136
|
+
TOKEN = /[^#{SEPARATORS}[:cntrl:]]+/
|
137
|
+
|
138
|
+
# Borrow URI's pattern for matching absolute URIs
|
139
|
+
REQUEST_URI = URI::REL_URI_REF
|
140
|
+
|
141
|
+
# Canonical HTTP methods
|
142
|
+
REQUEST_METHOD = /OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT/
|
143
|
+
|
144
|
+
# Extension HTTP methods
|
145
|
+
# extension-method = token
|
146
|
+
EXTENSION_METHOD = TOKEN
|
147
|
+
|
148
|
+
# HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
|
149
|
+
HTTP_VERSION = %r{HTTP/(\d+\.\d+)}
|
150
|
+
|
151
|
+
# LWS = [CRLF] 1*( SP | HT )
|
152
|
+
LWS = /#{CRLF}[ \t]+/
|
153
|
+
|
154
|
+
# TEX = <any OCTET except CTLs, but including LWS>
|
155
|
+
TEXT = /[^[:cntrl:]]|#{LWS}/
|
156
|
+
|
157
|
+
# Reason-Phrase = *<TEXT, excluding CR, LF>
|
158
|
+
REASON_PHRASE = %r{[^[:cntrl:]]+}
|
159
|
+
|
160
|
+
# Pattern to match HTTP response lines
|
161
|
+
# Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
|
162
|
+
HTTP_RESPONSE_LINE = %r{
|
163
|
+
(?<http_version>#{HTTP_VERSION})
|
164
|
+
#{SP}
|
165
|
+
(?<status_code>\d{3})
|
166
|
+
#{SP}
|
167
|
+
(?<reason_phrase>#{REASON_PHRASE})
|
168
|
+
#{CRLF}
|
169
|
+
}x
|
170
|
+
|
171
|
+
# message-header = field-name ":" [ field-value ]
|
172
|
+
# field-name = token
|
173
|
+
# field-value = *( field-content | LWS )
|
174
|
+
# field-content = <the OCTETs making up the field-value
|
175
|
+
# and consisting of either *TEXT or combinations
|
176
|
+
# of token, separators, and quoted-string>
|
177
|
+
|
178
|
+
# Pattern to match a single header tuple, possibly split over multiple lines
|
179
|
+
HEADER_LINE = %r{
|
180
|
+
^
|
181
|
+
#{TOKEN}
|
182
|
+
:
|
183
|
+
(?:#{LWS}|#{TEXT})*
|
184
|
+
#{CRLF}
|
185
|
+
}mx
|
186
|
+
|
187
|
+
# entity-body = *OCTET
|
188
|
+
MESSAGE_BODY = /.*/
|
189
|
+
|
190
|
+
# Pattern to match an entire HTTP response
|
191
|
+
# Response = Status-Line ; Section 6.1
|
192
|
+
# *(( general-header ; Section 4.5
|
193
|
+
# | response-header ; Section 6.2
|
194
|
+
# | entity-header ) CRLF) ; Section 7.1
|
195
|
+
# CRLF
|
196
|
+
# [ message-body ] ; Section 7.2
|
197
|
+
HTTP_RESPONSE = %r{
|
198
|
+
^
|
199
|
+
(?<response_line>#{HTTP_RESPONSE_LINE})
|
200
|
+
(?<headers>#{HEADER_LINE}*)
|
201
|
+
#{CRLF}
|
202
|
+
(?<message_body>#{MESSAGE_BODY})
|
203
|
+
}x
|
204
|
+
|
205
|
+
# wkday = "Mon" | "Tue" | "Wed"
|
206
|
+
# | "Thu" | "Fri" | "Sat" | "Sun"
|
207
|
+
WKDAY = Regexp.union( %w[Mon Tue Wed Thu Fri Sat Sun] )
|
208
|
+
|
209
|
+
# month = "Jan" | "Feb" | "Mar" | "Apr"
|
210
|
+
# | "May" | "Jun" | "Jul" | "Aug"
|
211
|
+
# | "Sep" | "Oct" | "Nov" | "Dec"
|
212
|
+
MONTH = Regexp.union( %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec] )
|
213
|
+
|
214
|
+
# Match an RFC1123 "HTTP date"
|
215
|
+
# rfc1123-date = wkday "," SP date1 SP time SP "GMT"
|
216
|
+
# date1 = 2DIGIT SP month SP 4DIGIT
|
217
|
+
# ; day month year (e.g., 02 Jun 1982)
|
218
|
+
# time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
|
219
|
+
# ; 00:00:00 - 23:59:59
|
220
|
+
HTTP_DATE = %r{
|
221
|
+
#{WKDAY} , #{SP}
|
222
|
+
\d{2} #{SP}
|
223
|
+
#{MONTH} #{SP}
|
224
|
+
\d{4} #{SP}
|
225
|
+
\d{2} : \d{2} : \d{2} #{SP} GMT
|
226
|
+
}x
|
227
|
+
|
228
|
+
|
229
|
+
# Freeze all testing constants
|
230
|
+
constants.each do |cname|
|
231
|
+
const_get(cname).freeze
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
data/spec/lib/helpers.rb
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent
|
7
|
+
|
8
|
+
libdir = basedir + "lib"
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
|
11
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
12
|
+
}
|
13
|
+
|
14
|
+
# SimpleCov test coverage reporting; enable this using the :coverage rake task
|
15
|
+
if ENV['COVERAGE']
|
16
|
+
$stderr.puts "\n\n>>> Enabling coverage report.\n\n"
|
17
|
+
require 'simplecov'
|
18
|
+
SimpleCov.start do
|
19
|
+
add_filter 'spec'
|
20
|
+
add_group "Config Classes" do |file|
|
21
|
+
file.filename =~ %r{lib/mongrel2/config(\.rb|/.*)$}
|
22
|
+
end
|
23
|
+
add_group "Needing tests" do |file|
|
24
|
+
file.covered_percent < 90
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'configurability'
|
31
|
+
rescue LoadError => err
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'pathname'
|
35
|
+
require 'tmpdir'
|
36
|
+
|
37
|
+
require 'rspec'
|
38
|
+
require 'mongrel2'
|
39
|
+
require 'mongrel2/config'
|
40
|
+
|
41
|
+
require 'sequel'
|
42
|
+
require 'sequel/model'
|
43
|
+
|
44
|
+
require 'spec/lib/constants'
|
45
|
+
require 'spec/lib/matchers'
|
46
|
+
|
47
|
+
|
48
|
+
### RSpec helper functions.
|
49
|
+
module Mongrel2::SpecHelpers
|
50
|
+
include Mongrel2::TestConstants
|
51
|
+
|
52
|
+
class ArrayLogger
|
53
|
+
### Create a new ArrayLogger that will append content to +array+.
|
54
|
+
def initialize( array )
|
55
|
+
@array = array
|
56
|
+
end
|
57
|
+
|
58
|
+
### Write the specified +message+ to the array.
|
59
|
+
def write( message )
|
60
|
+
@array << message
|
61
|
+
end
|
62
|
+
|
63
|
+
### No-op -- this is here just so Logger doesn't complain
|
64
|
+
def close; end
|
65
|
+
|
66
|
+
end # class ArrayLogger
|
67
|
+
|
68
|
+
|
69
|
+
unless defined?( LEVEL )
|
70
|
+
LEVEL = {
|
71
|
+
:debug => Logger::DEBUG,
|
72
|
+
:info => Logger::INFO,
|
73
|
+
:warn => Logger::WARN,
|
74
|
+
:error => Logger::ERROR,
|
75
|
+
:fatal => Logger::FATAL,
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
###############
|
80
|
+
module_function
|
81
|
+
###############
|
82
|
+
|
83
|
+
### Make an easily-comparable version vector out of +ver+ and return it.
|
84
|
+
def vvec( ver )
|
85
|
+
return ver.split('.').collect {|char| char.to_i }.pack('N*')
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
### Reset the logging subsystem to its default state.
|
90
|
+
def reset_logging
|
91
|
+
Mongrel2.reset_logger
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
### Alter the output of the default log formatter to be pretty in SpecMate output
|
96
|
+
def setup_logging( level=Logger::FATAL )
|
97
|
+
|
98
|
+
# Turn symbol-style level config into Logger's expected Fixnum level
|
99
|
+
if Mongrel2::Logging::LOG_LEVELS.key?( level.to_s )
|
100
|
+
level = Mongrel2::Logging::LOG_LEVELS[ level.to_s ]
|
101
|
+
end
|
102
|
+
|
103
|
+
logger = Logger.new( $stderr )
|
104
|
+
Mongrel2.logger = logger
|
105
|
+
Mongrel2.logger.level = level
|
106
|
+
|
107
|
+
# Only do this when executing from a spec in TextMate
|
108
|
+
if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
|
109
|
+
Thread.current['logger-output'] = []
|
110
|
+
logdevice = ArrayLogger.new( Thread.current['logger-output'] )
|
111
|
+
Mongrel2.logger = Logger.new( logdevice )
|
112
|
+
# Mongrel2.logger.level = level
|
113
|
+
Mongrel2.logger.formatter = Mongrel2::Logging::HtmlFormatter.new( logger )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
### Set up a Mongrel2 configuration database in memory.
|
119
|
+
def setup_config_db( dbspec=':memory:' )
|
120
|
+
Mongrel2::Config.configure( :configdb => dbspec ) unless
|
121
|
+
Mongrel2::Config.db.uri[ %r{sqlite:/(.*)}, 1 ] == dbspec
|
122
|
+
Mongrel2::Config.init_database
|
123
|
+
Mongrel2::Config.db.tables.collect {|t| Mongrel2::Config.db[t] }.each( &:truncate )
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
### Normalize and fill in missing members for the given +opts+.
|
128
|
+
def normalize_headers( opts, defaults=TEST_HEADERS )
|
129
|
+
headers = defaults.merge( opts[:headers] || {} )
|
130
|
+
|
131
|
+
headers["PATH"] = opts[:path]
|
132
|
+
headers["URI"] = "#{opts[:path]}?#{opts[:query]}"
|
133
|
+
headers["QUERY"] = opts[:query]
|
134
|
+
headers["PATTERN"] = opts[:pattern] || opts[:path]
|
135
|
+
|
136
|
+
return headers
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
### Make a raw Mongrel2 request from the specified +opts+ and return it as a String.
|
141
|
+
def make_request( opts={} )
|
142
|
+
opts = TEST_REQUEST_OPTS.merge( opts )
|
143
|
+
headers = normalize_headers( opts )
|
144
|
+
|
145
|
+
headerstring = TNetstring.dump( Yajl::Encoder.encode(headers) )
|
146
|
+
bodystring = TNetstring.dump( opts[:body] || '' )
|
147
|
+
|
148
|
+
# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
|
149
|
+
return "%s %d %s %s%s" % [
|
150
|
+
opts[:uuid],
|
151
|
+
opts[:id],
|
152
|
+
opts[:path],
|
153
|
+
headerstring,
|
154
|
+
bodystring,
|
155
|
+
]
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
### Make a new-style (TNetstring headers) raw Mongrel2 request from the specified +opts+
|
160
|
+
### and return it as a String.
|
161
|
+
def make_tn_request( opts={} )
|
162
|
+
opts = TEST_REQUEST_OPTS.merge( opts )
|
163
|
+
headers = normalize_headers( opts )
|
164
|
+
|
165
|
+
headerstring = TNetstring.dump( headers )
|
166
|
+
bodystring = TNetstring.dump( opts[:body] || '' )
|
167
|
+
|
168
|
+
# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
|
169
|
+
return "%s %d %s %s%s" % [
|
170
|
+
opts[:uuid],
|
171
|
+
opts[:id],
|
172
|
+
opts[:path],
|
173
|
+
headerstring,
|
174
|
+
bodystring,
|
175
|
+
]
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
### Make a Mongrel2 request for a JSON route.
|
180
|
+
def make_json_request( opts={} )
|
181
|
+
opts = TEST_JSON_REQUEST_OPTS.merge( opts )
|
182
|
+
headers = normalize_headers( opts, TEST_JSON_HEADERS )
|
183
|
+
headers.delete( 'URI' ) # JSON requests don't have one
|
184
|
+
|
185
|
+
Mongrel2.log.debug "JSON request, headers = %p, opts = %p" % [ headers, opts ]
|
186
|
+
|
187
|
+
headerstring = TNetstring.dump( Yajl::Encoder.encode(headers) )
|
188
|
+
bodystring = TNetstring.dump( Yajl::Encoder.encode(opts[:body] || []) )
|
189
|
+
|
190
|
+
# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
|
191
|
+
return "%s %d %s %s%s" % [
|
192
|
+
opts[:uuid],
|
193
|
+
opts[:id],
|
194
|
+
opts[:path],
|
195
|
+
headerstring,
|
196
|
+
bodystring,
|
197
|
+
]
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
### Make a Mongrel2 request for an XML route.
|
202
|
+
def make_xml_request( opts={} )
|
203
|
+
opts = TEST_XML_REQUEST_OPTS.merge( opts )
|
204
|
+
headers = normalize_headers( opts, TEST_XML_HEADERS )
|
205
|
+
headers.delete( 'URI' ) # XML requests don't have one
|
206
|
+
|
207
|
+
Mongrel2.log.debug "XML request, headers = %p, opts = %p" % [ headers, opts ]
|
208
|
+
|
209
|
+
headerstring = TNetstring.dump( Yajl::Encoder.encode(headers) )
|
210
|
+
bodystring = TNetstring.dump( opts[:body] || "#{TEST_XML_PATH} />" )
|
211
|
+
|
212
|
+
# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
|
213
|
+
return "%s %d %s %s%s" % [
|
214
|
+
opts[:uuid],
|
215
|
+
opts[:id],
|
216
|
+
opts[:path],
|
217
|
+
headerstring,
|
218
|
+
bodystring,
|
219
|
+
]
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec )
|
226
|
+
|
227
|
+
if defined?( ::Amalgalite )
|
228
|
+
$stderr.puts ">>> Using Amalgalite #{Amalgalite::VERSION} for DB access."
|
229
|
+
else
|
230
|
+
$stderr.puts ">>> Using SQLite3 #{SQLite3::VERSION} for DB access."
|
231
|
+
end
|
232
|
+
|
233
|
+
### Mock with RSpec
|
234
|
+
RSpec.configure do |c|
|
235
|
+
include Mongrel2::TestConstants
|
236
|
+
|
237
|
+
c.mock_with :rspec
|
238
|
+
|
239
|
+
c.extend( Mongrel2::TestConstants )
|
240
|
+
c.include( Mongrel2::TestConstants )
|
241
|
+
c.include( Mongrel2::SpecHelpers )
|
242
|
+
c.include( Mongrel2::Matchers )
|
243
|
+
end
|
244
|
+
|
245
|
+
# vim: set nosta noet ts=4 sw=4:
|
246
|
+
|