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,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2' unless defined?( Mongrel2 )
|
4
|
+
require 'mongrel2/config' unless defined?( Mongrel2::Config )
|
5
|
+
|
6
|
+
# Mongrel2 Directory (Dir) configuration class
|
7
|
+
class Mongrel2::Config::Directory < Mongrel2::Config( :directory )
|
8
|
+
|
9
|
+
### As of Mongrel2/1.7.5:
|
10
|
+
# CREATE TABLE directory (id INTEGER PRIMARY KEY,
|
11
|
+
# base TEXT,
|
12
|
+
# index_file TEXT,
|
13
|
+
# default_ctype TEXT,
|
14
|
+
# cache_ttl INTEGER DEFAULT 0);
|
15
|
+
|
16
|
+
### Sequel validation callback: add errors if the record is invalid.
|
17
|
+
def validate
|
18
|
+
self.validate_base
|
19
|
+
self.validate_index_file
|
20
|
+
self.validate_default_ctype
|
21
|
+
self.validate_cache_ttl
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
#########
|
26
|
+
protected
|
27
|
+
#########
|
28
|
+
|
29
|
+
### Validate the 'base' directory which will be served.
|
30
|
+
def validate_base
|
31
|
+
if self.base
|
32
|
+
if self.base.start_with?( '/' )
|
33
|
+
errmsg = "[%p]: shouldn't start with '/'; that will fail when not in chroot." %
|
34
|
+
[ self.base ]
|
35
|
+
self.log.error( 'base ' + errmsg )
|
36
|
+
self.errors.add( :base, errmsg )
|
37
|
+
end
|
38
|
+
|
39
|
+
unless self.base.end_with?( '/' )
|
40
|
+
errmsg = "[%p]: must end with '/' or it won't work right." %
|
41
|
+
[ self.base ]
|
42
|
+
self.log.error( 'base ' + errmsg )
|
43
|
+
self.errors.add( :base, errmsg )
|
44
|
+
end
|
45
|
+
else
|
46
|
+
errmsg = "missing or nil"
|
47
|
+
self.log.error( 'base ' + errmsg )
|
48
|
+
self.errors.add( :base, errmsg )
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
### Validate the 'index_file' attribute.
|
54
|
+
def validate_index_file
|
55
|
+
self.validates_presence( :index_file, :message => "must not be nil" )
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
### Validate the index file attribute.
|
60
|
+
def validate_default_ctype
|
61
|
+
self.validates_presence( :default_ctype, :message => "must not be nil" )
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
### Validate the cache TTL if one is set.
|
66
|
+
def validate_cache_ttl
|
67
|
+
if self.cache_ttl && Integer( self.cache_ttl ) < 0
|
68
|
+
errmsg = "[%p]: not a positive Integer" % [ self.cache_ttl ]
|
69
|
+
self.log.error( 'cache_ttl' + errmsg )
|
70
|
+
self.errors.add( :cache_ttl, errmsg )
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
end # class Mongrel2::Config::Directory
|
78
|
+
|
@@ -0,0 +1,206 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2' unless defined?( Mongrel2 )
|
4
|
+
require 'mongrel2/config' unless defined?( Mongrel2::Config )
|
5
|
+
|
6
|
+
# Mongrel2 configuration DSL mixin
|
7
|
+
#
|
8
|
+
# == Example
|
9
|
+
#
|
10
|
+
# This is the mongrel2.org config re-expressed in the Ruby DSL:
|
11
|
+
#
|
12
|
+
# # the server to run them all
|
13
|
+
# server '2f62bd5-9e59-49cd-993c-3b6013c28f05' do
|
14
|
+
#
|
15
|
+
# access_log "/logs/access.log"
|
16
|
+
# error_log "/logs/error.log"
|
17
|
+
# chroot "./"
|
18
|
+
# pid_file "/run/mongrel2.pid"
|
19
|
+
# default_host "mongrel2.org"
|
20
|
+
# name "main"
|
21
|
+
# port 6767
|
22
|
+
#
|
23
|
+
# # your main host
|
24
|
+
# host "mongrel2.org" do
|
25
|
+
#
|
26
|
+
# # a sample of doing some handlers
|
27
|
+
# route '@chat', handler(
|
28
|
+
# 'tcp://127.0.0.1:9999',
|
29
|
+
# '54c6755b-9628-40a4-9a2d-cc82a816345e',
|
30
|
+
# 'tcp://127.0.0.1:9998'
|
31
|
+
# )
|
32
|
+
#
|
33
|
+
# route '/handlertest', handler(
|
34
|
+
# 'tcp://127.0.0.1:9997',
|
35
|
+
# '34f9ceee-cd52-4b7f-b197-88bf2f0ec378',
|
36
|
+
# 'tcp://127.0.0.1:9996'
|
37
|
+
# )
|
38
|
+
#
|
39
|
+
# # a sample proxy route
|
40
|
+
# web_app_proxy = proxy( '127.0.0.1', 8080 )
|
41
|
+
#
|
42
|
+
# route '/chat/', web_app_proxy
|
43
|
+
# route '/', web_app_proxy
|
44
|
+
#
|
45
|
+
# # here's a sample directory
|
46
|
+
# test_directory = directory(
|
47
|
+
# 'tests/',
|
48
|
+
# :index_file => 'index.html',
|
49
|
+
# :default_ctype => 'text/plain'
|
50
|
+
# )
|
51
|
+
#
|
52
|
+
# route '/tests/', test_directory
|
53
|
+
# route '/testsmulti/(.*.json)', test_directory
|
54
|
+
#
|
55
|
+
# chat_demo_dir = directory(
|
56
|
+
# 'examples/chat/static/',
|
57
|
+
# :index_file => 'index.html',
|
58
|
+
# :default_ctype => 'text/plain'
|
59
|
+
# )
|
60
|
+
#
|
61
|
+
# route '/chatdemo/', chat_demo_dir
|
62
|
+
# route '/static/', chat_demo_dir
|
63
|
+
#
|
64
|
+
# route '/mp3stream', handler(
|
65
|
+
# 'tcp://127.0.0.1:9995',
|
66
|
+
# '53f9f1d1-1116-4751-b6ff-4fbe3e43d142',
|
67
|
+
# 'tcp://127.0.0.1:9994'
|
68
|
+
# )
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# settings(
|
74
|
+
# "zeromq.threads" => 1,
|
75
|
+
# "upload.temp_store" => "/home/zedshaw/projects/mongrel2/tmp/upload.XXXXXX",
|
76
|
+
# "upload.temp_store_mode" => "0666"
|
77
|
+
# )
|
78
|
+
#
|
79
|
+
module Mongrel2::Config::DSL
|
80
|
+
|
81
|
+
|
82
|
+
# A decorator object that provides the DSL-ish interface to the various Config
|
83
|
+
# objects. It derives its interface on the fly from columns of the class it's
|
84
|
+
# created with and a DSLMethods mixin if the target class defines one.
|
85
|
+
class Adapter
|
86
|
+
include Mongrel2::Loggable
|
87
|
+
|
88
|
+
### Adapt the specified +target+ to use a declarative interface.
|
89
|
+
def initialize( targetclass, opts={} )
|
90
|
+
self.log.debug "Wrapping a %p" % [ targetclass ]
|
91
|
+
@targetclass = targetclass
|
92
|
+
@target = @targetclass.new( opts )
|
93
|
+
self.decorate_with_column_declaratives( @target )
|
94
|
+
self.decorate_with_custom_declaratives( @targetclass )
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
######
|
99
|
+
public
|
100
|
+
######
|
101
|
+
|
102
|
+
# The decorated object
|
103
|
+
attr_reader :target
|
104
|
+
|
105
|
+
|
106
|
+
### Backport the singleton_class method if there isn't one.
|
107
|
+
unless instance_methods.include?( :singleton_class )
|
108
|
+
def singleton_class
|
109
|
+
class << self; self; end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
### Add a declarative singleton method for the columns of the +adapted_object+.
|
114
|
+
def decorate_with_column_declaratives( adapted_object )
|
115
|
+
columns = adapted_object.columns
|
116
|
+
self.log.debug " decorating for columns: %s" % [ columns.map( &:to_s ).sort.join(', ') ]
|
117
|
+
|
118
|
+
columns.each do |colname|
|
119
|
+
|
120
|
+
# Create a method that will act as a writer if called with an
|
121
|
+
# argument, and a reader if not.
|
122
|
+
method_body = Proc.new do |*args|
|
123
|
+
if args.empty?
|
124
|
+
self.target.send( colname )
|
125
|
+
else
|
126
|
+
self.target.send( "#{colname}=", *args )
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Install the method
|
131
|
+
self.singleton_class.send( :define_method, colname, &method_body )
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
### Mix in methods defined by the "DSLMethods" mixin defined by the class
|
137
|
+
### of the object being adapted.
|
138
|
+
def decorate_with_custom_declaratives( objectclass )
|
139
|
+
return unless objectclass.const_defined?( :DSLMethods )
|
140
|
+
self.singleton_class.send( :include, objectclass.const_get(:DSLMethods) )
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
end # class Adapter
|
145
|
+
|
146
|
+
|
147
|
+
### Create a Mongrel2::Config::Server with the specified +uuid+, evaluate
|
148
|
+
### the block (if given) within its context, and return it.
|
149
|
+
def server( uuid, &block )
|
150
|
+
Mongrel2::Config.init_database
|
151
|
+
|
152
|
+
Mongrel2.log.debug "Server [%s] (block: %p)" % [ uuid, block ]
|
153
|
+
adapter = Adapter.new( Mongrel2::Config::Server, :uuid => uuid )
|
154
|
+
adapter.instance_eval( &block ) if block
|
155
|
+
return adapter.target
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
### Set the value of one of the 'Tweakable Expert Settings'
|
160
|
+
def setting( key, val )
|
161
|
+
Mongrel2::Config.init_database
|
162
|
+
return Mongrel2::Config::Setting.create( :key => key, :value => val )
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
### Set some 'Tweakable Expert Settings' en masse
|
167
|
+
def settings( hash )
|
168
|
+
result = []
|
169
|
+
|
170
|
+
Mongrel2::Config.db.transaction do
|
171
|
+
hash.each do |key, val|
|
172
|
+
result << setting( key, val )
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
return result
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
### Set up a mimetype mapping between files with the given +extension+ and +mimetype+.
|
181
|
+
def mimetype( extension, mimetype )
|
182
|
+
Mongrel2::Config.init_database
|
183
|
+
|
184
|
+
type = Mongrel2::Config::Mimetype.find_or_create( :extension => extension )
|
185
|
+
type.mimetype = mimetype
|
186
|
+
type.save
|
187
|
+
|
188
|
+
return type
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
### Set some mimetypes en masse.
|
193
|
+
def mimetypes( hash )
|
194
|
+
result = []
|
195
|
+
|
196
|
+
Mongrel2::Config.db.transaction do
|
197
|
+
hash.each do |ext, mimetype|
|
198
|
+
result << mimetype( ext, mimetype )
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
return result
|
203
|
+
end
|
204
|
+
|
205
|
+
end # module Mongrel2::Config::DSL
|
206
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2' unless defined?( Mongrel2 )
|
4
|
+
require 'mongrel2/config' unless defined?( Mongrel2::Config )
|
5
|
+
|
6
|
+
# Mongrel2 Handler configuration class
|
7
|
+
class Mongrel2::Config::Handler < Mongrel2::Config( :handler )
|
8
|
+
|
9
|
+
### As of Mongrel2/1.7.5:
|
10
|
+
# CREATE TABLE handler (id INTEGER PRIMARY KEY,
|
11
|
+
# send_spec TEXT,
|
12
|
+
# send_ident TEXT,
|
13
|
+
# recv_spec TEXT,
|
14
|
+
# recv_ident TEXT,
|
15
|
+
# raw_payload INTEGER DEFAULT 0,
|
16
|
+
# protocol TEXT DEFAULT 'json');
|
17
|
+
|
18
|
+
|
19
|
+
# The list of 0mq transports Mongrel2 can use; "You need to use the
|
20
|
+
# ZeroMQ syntax for configuring them, but this means with one
|
21
|
+
# configuration format you can use handlers that are using UDP, TCP,
|
22
|
+
# Unix, or PGM transports." Note that I'm assuming by 'udp' Zed means
|
23
|
+
# 'epgm', as I can't find any udp 0mq transport.
|
24
|
+
VALID_SPEC_SCHEMES = %w[epgm tcp ipc pgm]
|
25
|
+
|
26
|
+
# The list of valid protocols
|
27
|
+
#--
|
28
|
+
# handler.h: typedef enum { HANDLER_PROTO_JSON, HANDLER_PROTO_TNET } handler_protocol_t;
|
29
|
+
VALID_PROTOCOLS = %w[json tnetstring]
|
30
|
+
|
31
|
+
|
32
|
+
##
|
33
|
+
# :method: by_send_ident( uuid )
|
34
|
+
#
|
35
|
+
# Look up a Handler by its send_ident, which should be a +uuid+ or similar String.
|
36
|
+
def_dataset_method( :by_send_ident ) do |ident|
|
37
|
+
filter( :send_ident => ident )
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
### Validate the object prior to saving it.
|
42
|
+
def validate
|
43
|
+
self.validate_idents
|
44
|
+
self.validate_specs
|
45
|
+
self.validate_protocol
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
#########
|
50
|
+
protected
|
51
|
+
#########
|
52
|
+
|
53
|
+
### Turn nil recv_ident values into the empty string before validating.
|
54
|
+
def before_validation
|
55
|
+
self.recv_ident ||= ''
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
### Validate the send_ident and recv_ident
|
60
|
+
### --
|
61
|
+
### :FIXME: I'm not sure if this is actually necessary, but it seems like
|
62
|
+
### the ident should at least be UUID-like like the server ident.
|
63
|
+
def validate_idents
|
64
|
+
unless self.send_ident =~ /^\w[\w\-]+$/
|
65
|
+
errmsg = "[%p]: invalid sender identity (should be UUID-like)" % [ self.send_ident ]
|
66
|
+
self.log.error( 'send_ident: ' + errmsg )
|
67
|
+
self.errors.add( :send_ident, errmsg )
|
68
|
+
end
|
69
|
+
|
70
|
+
unless self.recv_ident == '' || self.send_ident =~ /^\w[\w\-]+$/
|
71
|
+
errmsg = "[%p]: invalid receiver identity (should be empty string or UUID-like)" %
|
72
|
+
[ self.recv_ident ]
|
73
|
+
self.log.error( 'send_ident: ' + errmsg )
|
74
|
+
self.errors.add( :send_ident, errmsg )
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
### Validate the send_spec and recv_spec.
|
80
|
+
def validate_specs
|
81
|
+
if err = check_0mq_spec( self.send_spec )
|
82
|
+
errmsg = "[%p]: %s" % [ self.send_spec, err ]
|
83
|
+
self.log.error( 'send_spec: ' + errmsg )
|
84
|
+
self.errors.add( :recv_spec, errmsg )
|
85
|
+
end
|
86
|
+
|
87
|
+
if err = check_0mq_spec( self.recv_spec )
|
88
|
+
errmsg = "[%p]: %s" % [ self.recv_spec, err ]
|
89
|
+
self.log.error( 'recv_spec: ' + errmsg )
|
90
|
+
self.errors.add( :recv_spec, errmsg )
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
### Validate the handler's protocol.
|
96
|
+
def validate_protocol
|
97
|
+
return unless self.protocol # nil == default
|
98
|
+
unless VALID_PROTOCOLS.include?( self.protocol )
|
99
|
+
errmsg = "[%p]: invalid" % [ self.protocol ]
|
100
|
+
self.log.error( 'protocol: ' + errmsg )
|
101
|
+
self.errors.add( :protocol, errmsg )
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
#######
|
108
|
+
private
|
109
|
+
#######
|
110
|
+
|
111
|
+
### Returns +true+ if +url+ is a valid 0mq transport specification.
|
112
|
+
def check_0mq_spec( url )
|
113
|
+
return "must not be nil" unless url
|
114
|
+
|
115
|
+
u = URI( url )
|
116
|
+
return "invalid 0mq transport #{u.scheme}" unless VALID_SPEC_SCHEMES.include?( u.scheme )
|
117
|
+
|
118
|
+
return nil
|
119
|
+
rescue URI::InvalidURIError
|
120
|
+
return 'not a URI; should be something like "tcp://127.0.0.1:9998"'
|
121
|
+
end
|
122
|
+
|
123
|
+
end # class Mongrel2::Config::Handler
|
124
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2' unless defined?( Mongrel2 )
|
4
|
+
require 'mongrel2/config' unless defined?( Mongrel2::Config )
|
5
|
+
|
6
|
+
# Mongrel2 Host configuration class
|
7
|
+
class Mongrel2::Config::Host < Mongrel2::Config( :host )
|
8
|
+
|
9
|
+
### As of Mongrel2/1.7.5:
|
10
|
+
# CREATE TABLE host (id INTEGER PRIMARY KEY,
|
11
|
+
# server_id INTEGER,
|
12
|
+
# maintenance BOOLEAN DEFAULT 0,
|
13
|
+
# name TEXT,
|
14
|
+
# matching TEXT);
|
15
|
+
|
16
|
+
one_to_many :routes
|
17
|
+
many_to_one :server
|
18
|
+
|
19
|
+
### DSL methods for the Server context besides those automatically-generated from its
|
20
|
+
### columns.
|
21
|
+
module DSLMethods
|
22
|
+
|
23
|
+
### Add a Mongrel2::Config::Route to the Host object.
|
24
|
+
def route( path, target, opts={} )
|
25
|
+
self.target.save
|
26
|
+
Mongrel2.log.debug "Route %s -> %p [%p]" % [ path, target, opts ]
|
27
|
+
|
28
|
+
args = { :path => path, :target => target }
|
29
|
+
args.merge!( opts )
|
30
|
+
route = Mongrel2::Config::Route.new( args )
|
31
|
+
|
32
|
+
self.target.add_route( route )
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# These are route _arguments_, so they need to be declared in Host's scope rather
|
37
|
+
# than Route's.
|
38
|
+
|
39
|
+
### Create a new Mongrel2::Config::Directory object for the specified +base+ and
|
40
|
+
### return it.
|
41
|
+
def directory( base, index_file, default_ctype='text/plain', opts={} )
|
42
|
+
opts.merge!( :base => base, :index_file => index_file, :default_ctype => default_ctype )
|
43
|
+
return Mongrel2::Config::Directory.create( opts )
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
### Create a new Mongrel2::Config::Proxy object for the specified +addr+ and
|
48
|
+
### +port+ and return it.
|
49
|
+
def proxy( addr, port=80 )
|
50
|
+
return Mongrel2::Config::Proxy.create( :addr => addr, :port => port )
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
### Create a new Mongrel2::Config::Handler object with the specified +send_spec+,
|
55
|
+
### +send_ident+, +recv_spec+, +recv_ident+, and +options+ and return it.
|
56
|
+
def handler( send_spec, send_ident, recv_spec=nil, recv_ident='', options={} )
|
57
|
+
# Shift the opts hash over if the other optional args were omitted
|
58
|
+
if recv_spec.is_a?( Hash )
|
59
|
+
options = recv_spec
|
60
|
+
recv_spec = nil
|
61
|
+
elsif recv_ident.is_a?( Hash )
|
62
|
+
options = recv_ident
|
63
|
+
recv_ident = ''
|
64
|
+
end
|
65
|
+
|
66
|
+
# Default to one port below the request spec
|
67
|
+
unless recv_spec
|
68
|
+
port = send_spec[ /:(\d+)$/, 1 ] or
|
69
|
+
"Can't guess default port for a send_spec without one (%p)" % [ send_spec ]
|
70
|
+
recv_spec = URI( send_spec )
|
71
|
+
recv_spec.port = port.to_i - 1
|
72
|
+
end
|
73
|
+
|
74
|
+
options.merge!(
|
75
|
+
:send_spec => send_spec.to_s,
|
76
|
+
:send_ident => send_ident,
|
77
|
+
:recv_spec => recv_spec.to_s,
|
78
|
+
:recv_ident => recv_ident
|
79
|
+
)
|
80
|
+
|
81
|
+
Mongrel2.log.debug "Creating handler with options: %p" % [ options ]
|
82
|
+
return Mongrel2::Config::Handler.create( options )
|
83
|
+
end
|
84
|
+
|
85
|
+
end # module DSLMethods
|
86
|
+
|
87
|
+
end # class Mongrel2::Config::Host
|
88
|
+
|