merb-core 0.9.13 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -3
- data/lib/merb-core.rb +84 -41
- data/lib/merb-core/bootloader.rb +71 -60
- data/lib/merb-core/config.rb +31 -17
- data/lib/merb-core/controller/abstract_controller.rb +35 -35
- data/lib/merb-core/controller/exceptions.rb +14 -9
- data/lib/merb-core/controller/merb_controller.rb +22 -20
- data/lib/merb-core/controller/mime.rb +5 -5
- data/lib/merb-core/controller/mixins/authentication.rb +11 -8
- data/lib/merb-core/controller/mixins/conditional_get.rb +7 -7
- data/lib/merb-core/controller/mixins/controller.rb +15 -15
- data/lib/merb-core/controller/mixins/render.rb +16 -16
- data/lib/merb-core/controller/mixins/responder.rb +23 -23
- data/lib/merb-core/controller/template.rb +17 -17
- data/lib/merb-core/core_ext/hash.rb +2 -2
- data/lib/merb-core/core_ext/kernel.rb +19 -18
- data/lib/merb-core/dispatch/cookies.rb +13 -0
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +12 -1
- data/lib/merb-core/dispatch/dispatcher.rb +6 -5
- data/lib/merb-core/dispatch/request.rb +56 -52
- data/lib/merb-core/dispatch/request_parsers.rb +7 -7
- data/lib/merb-core/dispatch/router.rb +14 -14
- data/lib/merb-core/dispatch/router/behavior.rb +31 -31
- data/lib/merb-core/dispatch/router/cached_proc.rb +13 -1
- data/lib/merb-core/dispatch/router/resources.rb +9 -9
- data/lib/merb-core/dispatch/router/route.rb +60 -7
- data/lib/merb-core/dispatch/session.rb +21 -15
- data/lib/merb-core/dispatch/session/container.rb +10 -8
- data/lib/merb-core/dispatch/session/cookie.rb +12 -11
- data/lib/merb-core/dispatch/session/memcached.rb +4 -2
- data/lib/merb-core/dispatch/session/memory.rb +8 -6
- data/lib/merb-core/dispatch/session/store_container.rb +6 -5
- data/lib/merb-core/dispatch/worker.rb +28 -10
- data/lib/merb-core/gem_ext/erubis.rb +4 -2
- data/lib/merb-core/logger.rb +3 -22
- data/lib/merb-core/plugins.rb +5 -5
- data/lib/merb-core/rack.rb +1 -1
- data/lib/merb-core/rack/adapter.rb +5 -1
- data/lib/merb-core/rack/adapter/abstract.rb +15 -10
- data/lib/merb-core/rack/adapter/ebb.rb +4 -2
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -1
- data/lib/merb-core/rack/adapter/fcgi.rb +3 -1
- data/lib/merb-core/rack/adapter/irb.rb +10 -1
- data/lib/merb-core/rack/adapter/mongrel.rb +5 -2
- data/lib/merb-core/rack/adapter/runner.rb +3 -1
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +2 -1
- data/lib/merb-core/rack/adapter/thin.rb +4 -1
- data/lib/merb-core/rack/adapter/thin_turbo.rb +1 -0
- data/lib/merb-core/rack/adapter/webrick.rb +8 -34
- data/lib/merb-core/rack/application.rb +2 -2
- data/lib/merb-core/rack/handler/mongrel.rb +7 -0
- data/lib/merb-core/rack/helpers.rb +1 -1
- data/lib/merb-core/rack/middleware.rb +7 -1
- data/lib/merb-core/rack/middleware/conditional_get.rb +3 -0
- data/lib/merb-core/rack/middleware/content_length.rb +2 -0
- data/lib/merb-core/rack/middleware/path_prefix.rb +4 -0
- data/lib/merb-core/rack/middleware/profiler.rb +3 -1
- data/lib/merb-core/rack/middleware/static.rb +7 -1
- data/lib/merb-core/rack/middleware/tracer.rb +1 -0
- data/lib/merb-core/rack/stream_wrapper.rb +35 -30
- data/lib/merb-core/server.rb +17 -16
- data/lib/merb-core/tasks/gem_management.rb +1 -1
- data/lib/merb-core/tasks/merb.rb +3 -1
- data/lib/merb-core/tasks/merb_rake_helper.rb +1 -1
- data/lib/merb-core/test.rb +8 -8
- data/lib/merb-core/test/helpers.rb +1 -1
- data/lib/merb-core/test/helpers/cookie_jar.rb +16 -2
- data/lib/merb-core/test/helpers/mock_request_helper.rb +13 -13
- data/lib/merb-core/test/helpers/request_helper.rb +1 -1
- data/lib/merb-core/test/helpers/route_helper.rb +2 -2
- data/lib/merb-core/test/matchers.rb +3 -3
- data/lib/merb-core/test/matchers/request_matchers.rb +1 -1
- data/lib/merb-core/test/run_spec.rb +1 -1
- data/lib/merb-core/test/tasks/spectasks.rb +1 -1
- data/lib/merb-core/test/test_ext/hpricot.rb +1 -1
- data/lib/merb-core/test/test_ext/rspec.rb +2 -2
- data/lib/merb-core/test/test_ext/string.rb +1 -1
- data/lib/merb-core/version.rb +1 -1
- metadata +8 -22
- data/lib/merb-core/test/matchers/view_matchers.rb +0 -231
- data/lib/merb-core/test/webrat.rb +0 -37
- data/lib/merb-core/vendor/nokogiri/css.rb +0 -6
- data/lib/merb-core/vendor/nokogiri/css/generated_parser.rb +0 -653
- data/lib/merb-core/vendor/nokogiri/css/generated_tokenizer.rb +0 -159
- data/lib/merb-core/vendor/nokogiri/css/node.rb +0 -95
- data/lib/merb-core/vendor/nokogiri/css/parser.rb +0 -24
- data/lib/merb-core/vendor/nokogiri/css/parser.y +0 -198
- data/lib/merb-core/vendor/nokogiri/css/tokenizer.rb +0 -9
- data/lib/merb-core/vendor/nokogiri/css/tokenizer.rex +0 -63
- data/lib/merb-core/vendor/nokogiri/css/xpath_visitor.rb +0 -159
@@ -11,7 +11,7 @@ module Merb
|
|
11
11
|
# ==== Returns
|
12
12
|
# <Array>:: A rack response of [status<Integer>, headers<Hash>, body<String, Stream>]
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# :api: private
|
15
15
|
def call(env)
|
16
16
|
begin
|
17
17
|
rack_response = ::Merb::Dispatcher.handle(Merb::Request.new(env))
|
@@ -39,7 +39,7 @@ module Merb
|
|
39
39
|
# Boolean::
|
40
40
|
# True if the request should be deferred.
|
41
41
|
#
|
42
|
-
#
|
42
|
+
# :api: private
|
43
43
|
def deferred?(env)
|
44
44
|
path = env[Merb::Const::PATH_INFO] ? env[Merb::Const::PATH_INFO].chomp(Merb::Const::SLASH) : Merb::Const::EMPTY_STRING
|
45
45
|
if path =~ Merb.deferred_actions
|
@@ -31,6 +31,8 @@ module Merb
|
|
31
31
|
# :Host<String>::
|
32
32
|
# The hostname on which the app should run. Defaults to "0.0.0.0"
|
33
33
|
# :Port<Fixnum>:: The port for the app. Defaults to 8080.
|
34
|
+
#
|
35
|
+
# :api: plugin
|
34
36
|
def self.run(app, options={})
|
35
37
|
@server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
|
36
38
|
options[:Port] || 8080)
|
@@ -39,12 +41,15 @@ module Merb
|
|
39
41
|
@server.run.join
|
40
42
|
end
|
41
43
|
|
44
|
+
# :api: private
|
42
45
|
def self.stop(block = true)
|
43
46
|
@server.stop
|
44
47
|
end
|
45
48
|
|
46
49
|
# ==== Parameters
|
47
50
|
# app<Merb::Rack::Application>:: The app that Mongrel should handle.
|
51
|
+
#
|
52
|
+
# :api: plugin
|
48
53
|
def initialize(app)
|
49
54
|
@app = app
|
50
55
|
end
|
@@ -52,6 +57,8 @@ module Merb
|
|
52
57
|
# ==== Parameters
|
53
58
|
# request<Merb::Request>:: The HTTP request to handle.
|
54
59
|
# response<HTTPResponse>:: The response object to write response to.
|
60
|
+
#
|
61
|
+
# :api: plugin
|
55
62
|
def process(request, response)
|
56
63
|
env = {}.replace(request.params)
|
57
64
|
env.delete Merb::Const::HTTP_CONTENT_TYPE
|
@@ -2,14 +2,20 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
class Middleware
|
4
4
|
|
5
|
+
# @overridable
|
6
|
+
# :api: plugin
|
5
7
|
def initialize(app)
|
6
8
|
@app = app
|
7
9
|
end
|
8
|
-
|
10
|
+
|
11
|
+
# @overridable
|
12
|
+
# :api: plugin
|
9
13
|
def deferred?(env)
|
10
14
|
@app.deferred?(env)
|
11
15
|
end
|
12
16
|
|
17
|
+
# @overridable
|
18
|
+
# :api: plugin
|
13
19
|
def call(env)
|
14
20
|
@app.call(env)
|
15
21
|
end
|
@@ -2,6 +2,8 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
|
4
4
|
class ConditionalGet < Merb::Rack::Middleware
|
5
|
+
|
6
|
+
# :api: plugin
|
5
7
|
def call(env)
|
6
8
|
status, headers, body = @app.call(env)
|
7
9
|
|
@@ -16,6 +18,7 @@ module Merb
|
|
16
18
|
end
|
17
19
|
|
18
20
|
private
|
21
|
+
# :api: private
|
19
22
|
def document_not_modified?(env, headers)
|
20
23
|
if etag = headers[Merb::Const::ETAG]
|
21
24
|
etag == env[Merb::Const::HTTP_IF_NONE_MATCH]
|
@@ -2,21 +2,25 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
class PathPrefix < Merb::Rack::Middleware
|
4
4
|
|
5
|
+
# :api: private
|
5
6
|
def initialize(app, path_prefix = nil)
|
6
7
|
super(app)
|
7
8
|
@path_prefix = /^#{Regexp.escape(path_prefix)}/
|
8
9
|
end
|
9
10
|
|
11
|
+
# :api: plugin
|
10
12
|
def deferred?(env)
|
11
13
|
strip_path_prefix(env)
|
12
14
|
@app.deferred?(env)
|
13
15
|
end
|
14
16
|
|
17
|
+
# :api: plugin
|
15
18
|
def call(env)
|
16
19
|
strip_path_prefix(env)
|
17
20
|
@app.call(env)
|
18
21
|
end
|
19
22
|
|
23
|
+
# :api: private
|
20
24
|
def strip_path_prefix(env)
|
21
25
|
['PATH_INFO', 'REQUEST_URI'].each do |path_key|
|
22
26
|
if env[path_key] =~ @path_prefix
|
@@ -2,11 +2,13 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
class Profiler < Merb::Rack::Middleware
|
4
4
|
|
5
|
+
# :api: private
|
5
6
|
def initialize(app, min=1, iter=1)
|
6
7
|
super(app)
|
7
8
|
@min, @iter = min, iter
|
8
9
|
end
|
9
10
|
|
11
|
+
# :api: plugin
|
10
12
|
def call(env)
|
11
13
|
__profile__("profile_output", @min, @iter) do
|
12
14
|
@app.call(env)
|
@@ -16,4 +18,4 @@ module Merb
|
|
16
18
|
|
17
19
|
end
|
18
20
|
end
|
19
|
-
end
|
21
|
+
end
|
@@ -2,11 +2,13 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
class Static < Merb::Rack::Middleware
|
4
4
|
|
5
|
+
# :api: private
|
5
6
|
def initialize(app,directory)
|
6
7
|
super(app)
|
7
8
|
@static_server = ::Rack::File.new(directory)
|
8
9
|
end
|
9
10
|
|
11
|
+
# :api: plugin
|
10
12
|
def call(env)
|
11
13
|
path = if env[Merb::Const::PATH_INFO]
|
12
14
|
env[Merb::Const::PATH_INFO].chomp(Merb::Const::SLASH)
|
@@ -27,11 +29,13 @@ module Merb
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
|
-
|
32
|
+
# ==== Parameters
|
31
33
|
# path<String>:: The path to the file relative to the server root.
|
32
34
|
#
|
33
35
|
# ==== Returns
|
34
36
|
# Boolean:: True if file exists under the server root and is readable.
|
37
|
+
#
|
38
|
+
# :api: private
|
35
39
|
def file_exist?(path)
|
36
40
|
full_path = ::File.join(@static_server.root, ::Merb::Parse.unescape(path))
|
37
41
|
::File.file?(full_path) && ::File.readable?(full_path)
|
@@ -39,6 +43,8 @@ module Merb
|
|
39
43
|
|
40
44
|
# ==== Parameters
|
41
45
|
# env<Hash>:: Environment variables to pass on to the server.
|
46
|
+
#
|
47
|
+
# :api: private
|
42
48
|
def serve_static(env)
|
43
49
|
env[Merb::Const::PATH_INFO] = ::Merb::Parse.unescape(env[Merb::Const::PATH_INFO])
|
44
50
|
@static_server.call(env)
|
@@ -2,38 +2,43 @@ module Merb
|
|
2
2
|
module Rack
|
3
3
|
|
4
4
|
class StreamWrapper
|
5
|
-
|
5
|
+
# :api: private
|
6
|
+
def initialize(body)
|
6
7
|
@body = body
|
7
|
-
|
8
|
+
end
|
9
|
+
|
10
|
+
# :api: private
|
11
|
+
def each(&callback)
|
12
|
+
if Proc === @body
|
13
|
+
@writer = lambda { |x| callback.call(x) }
|
14
|
+
@body.call(self)
|
15
|
+
elsif @body.is_a?(String)
|
16
|
+
@body.each_line(&callback)
|
17
|
+
else
|
18
|
+
@body.each(&callback)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# :api: private
|
23
|
+
def write(str)
|
24
|
+
@writer.call str.to_s
|
25
|
+
str
|
26
|
+
end
|
27
|
+
|
28
|
+
# :api: private
|
29
|
+
def to_s
|
30
|
+
@body.to_s
|
31
|
+
end
|
8
32
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def write(str)
|
21
|
-
@writer.call str.to_s
|
22
|
-
str
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_s
|
26
|
-
@body.to_s
|
27
|
-
end
|
28
|
-
|
29
|
-
def ==(other)
|
30
|
-
@body == other
|
31
|
-
end
|
32
|
-
|
33
|
-
def method_missing(sym, *args, &blk)
|
34
|
-
@body.send(sym, *args, &blk)
|
35
|
-
end
|
36
|
-
|
33
|
+
# :api: private
|
34
|
+
def ==(other)
|
35
|
+
@body == other
|
36
|
+
end
|
37
|
+
|
38
|
+
# :api: private
|
39
|
+
def method_missing(sym, *args, &blk)
|
40
|
+
@body.send(sym, *args, &blk)
|
41
|
+
end
|
37
42
|
|
38
43
|
end
|
39
44
|
|
data/lib/merb-core/server.rb
CHANGED
@@ -19,7 +19,7 @@ module Merb
|
|
19
19
|
# If cluster is left out, then one process will be started. This process
|
20
20
|
# will be daemonized if Merb::Config[:daemonize] is true.
|
21
21
|
#
|
22
|
-
#
|
22
|
+
# :api: private
|
23
23
|
def start(port, cluster=nil)
|
24
24
|
|
25
25
|
@port = port
|
@@ -50,7 +50,7 @@ module Merb
|
|
50
50
|
# Boolean::
|
51
51
|
# True if Merb is running on the specified port.
|
52
52
|
#
|
53
|
-
#
|
53
|
+
# :api: private
|
54
54
|
def alive?(port)
|
55
55
|
pidfile = pid_file(port)
|
56
56
|
pid = pid_in_file(pidfile)
|
@@ -62,6 +62,7 @@ module Merb
|
|
62
62
|
Merb.fatal!("You don't have access to the PID file at #{pidfile}: #{e.message}")
|
63
63
|
end
|
64
64
|
|
65
|
+
# :api: private
|
65
66
|
def pid_in_file(pidfile)
|
66
67
|
File.read(pidfile).chomp.to_i
|
67
68
|
end
|
@@ -83,7 +84,7 @@ module Merb
|
|
83
84
|
# ==== Alternatives
|
84
85
|
# If you pass "all" as the port, the signal will be sent to all Merb processes.
|
85
86
|
#
|
86
|
-
#
|
87
|
+
# :api: private
|
87
88
|
def kill(port, sig = "INT")
|
88
89
|
if sig.is_a?(Integer)
|
89
90
|
sig = Signal.list.invert[sig]
|
@@ -103,7 +104,7 @@ module Merb
|
|
103
104
|
end
|
104
105
|
|
105
106
|
# Sends the provided signal to the process pointed at by the provided pid file.
|
106
|
-
#
|
107
|
+
# :api: private
|
107
108
|
def kill_pid(sig, file)
|
108
109
|
begin
|
109
110
|
pid = pid_in_file(file)
|
@@ -136,7 +137,7 @@ module Merb
|
|
136
137
|
# ==== Parameters
|
137
138
|
# port<~to_s>:: The port of the Merb process to daemonize.
|
138
139
|
#
|
139
|
-
#
|
140
|
+
# :api: private
|
140
141
|
def daemonize(port)
|
141
142
|
Merb.logger.warn! "About to fork..." if Merb::Config[:verbose]
|
142
143
|
fork do
|
@@ -163,7 +164,7 @@ module Merb
|
|
163
164
|
|
164
165
|
# Starts up Merb by running the bootloader and starting the adapter.
|
165
166
|
#
|
166
|
-
#
|
167
|
+
# :api: private
|
167
168
|
def bootup
|
168
169
|
Merb.trap("TERM") { shutdown }
|
169
170
|
|
@@ -175,7 +176,7 @@ module Merb
|
|
175
176
|
|
176
177
|
# Shut down Merb, reap any workers if necessary.
|
177
178
|
#
|
178
|
-
#
|
179
|
+
# :api: private
|
179
180
|
def shutdown(status = 0)
|
180
181
|
# reap_workers does exit but may not be called...
|
181
182
|
Merb::BootLoader::LoadClasses.reap_workers(status) if Merb::Config[:fork_for_class_load]
|
@@ -185,7 +186,7 @@ module Merb
|
|
185
186
|
|
186
187
|
# Change process user/group to those specified in Merb::Config.
|
187
188
|
#
|
188
|
-
#
|
189
|
+
# :api: private
|
189
190
|
def change_privilege
|
190
191
|
if Merb::Config[:user] && Merb::Config[:group]
|
191
192
|
Merb.logger.verbose! "About to change privilege to group " \
|
@@ -212,7 +213,7 @@ module Merb
|
|
212
213
|
# If Merb::Config[:pid_file] has been specified, that will be used
|
213
214
|
# instead of the port/socket based PID file.
|
214
215
|
#
|
215
|
-
#
|
216
|
+
# :api: private
|
216
217
|
def remove_pid_file(port)
|
217
218
|
pidfile = pid_file(port)
|
218
219
|
if File.exist?(pidfile)
|
@@ -233,14 +234,14 @@ module Merb
|
|
233
234
|
# If Merb::Config[:pid_file] has been specified, that will be used
|
234
235
|
# instead of the port/socket based PID file.
|
235
236
|
#
|
236
|
-
#
|
237
|
+
# :api: private
|
237
238
|
def store_pid(port)
|
238
239
|
store_details(port)
|
239
240
|
end
|
240
241
|
|
241
242
|
# Delete the pidfile for the specified port/socket.
|
242
243
|
#
|
243
|
-
#
|
244
|
+
# :api: private
|
244
245
|
def remove_pid(port)
|
245
246
|
FileUtils.rm(pid_file(port)) if File.file?(pid_file(port))
|
246
247
|
end
|
@@ -257,7 +258,7 @@ module Merb
|
|
257
258
|
# If Merb::Config[:pid_file] has been specified, that will be used
|
258
259
|
# instead of the port/socket based PID file.
|
259
260
|
#
|
260
|
-
#
|
261
|
+
# :api: private
|
261
262
|
def store_details(port = nil)
|
262
263
|
file = pid_file(port)
|
263
264
|
begin
|
@@ -285,7 +286,7 @@ module Merb
|
|
285
286
|
# Location of pid file for specified port. If clustered and pid_file option
|
286
287
|
# is specified, it adds the port/socket value to the path.
|
287
288
|
#
|
288
|
-
#
|
289
|
+
# :api: private
|
289
290
|
def pid_file(port)
|
290
291
|
pidfile = Merb::Config[:pid_file] || (Merb.log_path / "merb.%s.pid")
|
291
292
|
pidfile % port
|
@@ -297,7 +298,7 @@ module Merb
|
|
297
298
|
# Array::
|
298
299
|
# List of pid file paths. If not running clustered, the array contains a single path.
|
299
300
|
#
|
300
|
-
#
|
301
|
+
# :api: private
|
301
302
|
def pid_files
|
302
303
|
if Merb::Config[:pid_file]
|
303
304
|
if Merb::Config[:cluster]
|
@@ -319,7 +320,7 @@ module Merb
|
|
319
320
|
# ==== Alternatives
|
320
321
|
# If group is left out, the user will be used as the group.
|
321
322
|
#
|
322
|
-
#
|
323
|
+
# :api: private
|
323
324
|
def _change_privilege(user, group=user)
|
324
325
|
Merb.logger.warn! "Changing privileges to #{user}:#{group}"
|
325
326
|
|
@@ -353,7 +354,7 @@ module Merb
|
|
353
354
|
|
354
355
|
# Add trap to enter IRB on SIGINT. Process exit if second SIGINT is received.
|
355
356
|
#
|
356
|
-
#
|
357
|
+
# :api: private
|
357
358
|
def add_irb_trap
|
358
359
|
Merb.trap("INT") do
|
359
360
|
if @interrupted
|
data/lib/merb-core/tasks/merb.rb
CHANGED