merb-core 0.9.13 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/Rakefile +5 -3
  2. data/lib/merb-core.rb +84 -41
  3. data/lib/merb-core/bootloader.rb +71 -60
  4. data/lib/merb-core/config.rb +31 -17
  5. data/lib/merb-core/controller/abstract_controller.rb +35 -35
  6. data/lib/merb-core/controller/exceptions.rb +14 -9
  7. data/lib/merb-core/controller/merb_controller.rb +22 -20
  8. data/lib/merb-core/controller/mime.rb +5 -5
  9. data/lib/merb-core/controller/mixins/authentication.rb +11 -8
  10. data/lib/merb-core/controller/mixins/conditional_get.rb +7 -7
  11. data/lib/merb-core/controller/mixins/controller.rb +15 -15
  12. data/lib/merb-core/controller/mixins/render.rb +16 -16
  13. data/lib/merb-core/controller/mixins/responder.rb +23 -23
  14. data/lib/merb-core/controller/template.rb +17 -17
  15. data/lib/merb-core/core_ext/hash.rb +2 -2
  16. data/lib/merb-core/core_ext/kernel.rb +19 -18
  17. data/lib/merb-core/dispatch/cookies.rb +13 -0
  18. data/lib/merb-core/dispatch/default_exception/default_exception.rb +12 -1
  19. data/lib/merb-core/dispatch/dispatcher.rb +6 -5
  20. data/lib/merb-core/dispatch/request.rb +56 -52
  21. data/lib/merb-core/dispatch/request_parsers.rb +7 -7
  22. data/lib/merb-core/dispatch/router.rb +14 -14
  23. data/lib/merb-core/dispatch/router/behavior.rb +31 -31
  24. data/lib/merb-core/dispatch/router/cached_proc.rb +13 -1
  25. data/lib/merb-core/dispatch/router/resources.rb +9 -9
  26. data/lib/merb-core/dispatch/router/route.rb +60 -7
  27. data/lib/merb-core/dispatch/session.rb +21 -15
  28. data/lib/merb-core/dispatch/session/container.rb +10 -8
  29. data/lib/merb-core/dispatch/session/cookie.rb +12 -11
  30. data/lib/merb-core/dispatch/session/memcached.rb +4 -2
  31. data/lib/merb-core/dispatch/session/memory.rb +8 -6
  32. data/lib/merb-core/dispatch/session/store_container.rb +6 -5
  33. data/lib/merb-core/dispatch/worker.rb +28 -10
  34. data/lib/merb-core/gem_ext/erubis.rb +4 -2
  35. data/lib/merb-core/logger.rb +3 -22
  36. data/lib/merb-core/plugins.rb +5 -5
  37. data/lib/merb-core/rack.rb +1 -1
  38. data/lib/merb-core/rack/adapter.rb +5 -1
  39. data/lib/merb-core/rack/adapter/abstract.rb +15 -10
  40. data/lib/merb-core/rack/adapter/ebb.rb +4 -2
  41. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -1
  42. data/lib/merb-core/rack/adapter/fcgi.rb +3 -1
  43. data/lib/merb-core/rack/adapter/irb.rb +10 -1
  44. data/lib/merb-core/rack/adapter/mongrel.rb +5 -2
  45. data/lib/merb-core/rack/adapter/runner.rb +3 -1
  46. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +2 -1
  47. data/lib/merb-core/rack/adapter/thin.rb +4 -1
  48. data/lib/merb-core/rack/adapter/thin_turbo.rb +1 -0
  49. data/lib/merb-core/rack/adapter/webrick.rb +8 -34
  50. data/lib/merb-core/rack/application.rb +2 -2
  51. data/lib/merb-core/rack/handler/mongrel.rb +7 -0
  52. data/lib/merb-core/rack/helpers.rb +1 -1
  53. data/lib/merb-core/rack/middleware.rb +7 -1
  54. data/lib/merb-core/rack/middleware/conditional_get.rb +3 -0
  55. data/lib/merb-core/rack/middleware/content_length.rb +2 -0
  56. data/lib/merb-core/rack/middleware/path_prefix.rb +4 -0
  57. data/lib/merb-core/rack/middleware/profiler.rb +3 -1
  58. data/lib/merb-core/rack/middleware/static.rb +7 -1
  59. data/lib/merb-core/rack/middleware/tracer.rb +1 -0
  60. data/lib/merb-core/rack/stream_wrapper.rb +35 -30
  61. data/lib/merb-core/server.rb +17 -16
  62. data/lib/merb-core/tasks/gem_management.rb +1 -1
  63. data/lib/merb-core/tasks/merb.rb +3 -1
  64. data/lib/merb-core/tasks/merb_rake_helper.rb +1 -1
  65. data/lib/merb-core/test.rb +8 -8
  66. data/lib/merb-core/test/helpers.rb +1 -1
  67. data/lib/merb-core/test/helpers/cookie_jar.rb +16 -2
  68. data/lib/merb-core/test/helpers/mock_request_helper.rb +13 -13
  69. data/lib/merb-core/test/helpers/request_helper.rb +1 -1
  70. data/lib/merb-core/test/helpers/route_helper.rb +2 -2
  71. data/lib/merb-core/test/matchers.rb +3 -3
  72. data/lib/merb-core/test/matchers/request_matchers.rb +1 -1
  73. data/lib/merb-core/test/run_spec.rb +1 -1
  74. data/lib/merb-core/test/tasks/spectasks.rb +1 -1
  75. data/lib/merb-core/test/test_ext/hpricot.rb +1 -1
  76. data/lib/merb-core/test/test_ext/rspec.rb +2 -2
  77. data/lib/merb-core/test/test_ext/string.rb +1 -1
  78. data/lib/merb-core/version.rb +1 -1
  79. metadata +8 -22
  80. data/lib/merb-core/test/matchers/view_matchers.rb +0 -231
  81. data/lib/merb-core/test/webrat.rb +0 -37
  82. data/lib/merb-core/vendor/nokogiri/css.rb +0 -6
  83. data/lib/merb-core/vendor/nokogiri/css/generated_parser.rb +0 -653
  84. data/lib/merb-core/vendor/nokogiri/css/generated_tokenizer.rb +0 -159
  85. data/lib/merb-core/vendor/nokogiri/css/node.rb +0 -95
  86. data/lib/merb-core/vendor/nokogiri/css/parser.rb +0 -24
  87. data/lib/merb-core/vendor/nokogiri/css/parser.y +0 -198
  88. data/lib/merb-core/vendor/nokogiri/css/tokenizer.rb +0 -9
  89. data/lib/merb-core/vendor/nokogiri/css/tokenizer.rex +0 -63
  90. 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
- # @api private
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
- # @api private
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
@@ -15,7 +15,7 @@ module Merb
15
15
  # ==== Returns
16
16
  # <Array>:: A rack response to redirect to the specified url.
17
17
  #
18
- # @api plugin
18
+ # :api: plugin
19
19
  def self.redirect(url, options = {})
20
20
  # Build the rack array
21
21
  status = options.delete(:status)
@@ -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,6 +2,8 @@ module Merb
2
2
  module Rack
3
3
 
4
4
  class ContentLength < Merb::Rack::Middleware
5
+
6
+ # :api: plugin
5
7
  def call(env)
6
8
  status, headers, body = @app.call(env)
7
9
 
@@ -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
- # ==== Parameters
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,6 +2,7 @@ module Merb
2
2
  module Rack
3
3
  class Tracer < Merb::Rack::Middleware
4
4
 
5
+ # :api: plugin
5
6
  def call(env)
6
7
 
7
8
  Merb.logger.debug!("Rack environment:\n" + env.inspect + "\n\n")
@@ -2,38 +2,43 @@ module Merb
2
2
  module Rack
3
3
 
4
4
  class StreamWrapper
5
- def initialize(body)
5
+ # :api: private
6
+ def initialize(body)
6
7
  @body = body
7
- end
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
- def each(&callback)
10
- if Proc === @body
11
- @writer = lambda { |x| callback.call(x) }
12
- @body.call(self)
13
- elsif @body.is_a?(String)
14
- @body.each_line(&callback)
15
- else
16
- @body.each(&callback)
17
- end
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
 
@@ -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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
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
- # @api private
357
+ # :api: private
357
358
  def add_irb_trap
358
359
  Merb.trap("INT") do
359
360
  if @interrupted
@@ -361,4 +361,4 @@ TEXT
361
361
  Gem.source_index.load_gems_in(File.join(dir, 'specifications'))
362
362
  end
363
363
 
364
- end
364
+ end
@@ -1,2 +1,4 @@
1
+ local_gem_path = Gem.path if $BUNDLE
1
2
  require 'merb-core/tasks/merb_rake_helper'
2
- Dir[File.dirname(__FILE__) / '*.rake'].each { |ext| load ext }
3
+ Gem.path.replace(local_gem_path) if local_gem_path
4
+ Dir[File.dirname(__FILE__) / '*.rake'].each { |ext| load ext }
@@ -56,4 +56,4 @@ module Merb
56
56
  end
57
57
 
58
58
  end
59
- end
59
+ end