waves 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/bin/waves +4 -3
  2. data/doc/VERSION +1 -1
  3. data/lib/waves.rb +52 -40
  4. data/lib/{caches → waves/caches}/file.rb +3 -1
  5. data/lib/waves/caches/memcached.rb +56 -0
  6. data/lib/{caches → waves/caches}/simple.rb +6 -7
  7. data/lib/{caches → waves/caches}/synchronized.rb +15 -1
  8. data/lib/{commands → waves/commands}/console.rb +4 -4
  9. data/lib/{commands → waves/commands}/generate.rb +6 -5
  10. data/lib/{commands → waves/commands}/help.rb +0 -0
  11. data/lib/{commands → waves/commands}/server.rb +1 -1
  12. data/lib/{dispatchers → waves/dispatchers}/base.rb +17 -31
  13. data/lib/waves/dispatchers/default.rb +19 -0
  14. data/lib/{ext → waves/ext}/float.rb +0 -0
  15. data/lib/{ext → waves/ext}/hash.rb +0 -0
  16. data/lib/{ext → waves/ext}/integer.rb +16 -1
  17. data/lib/{ext → waves/ext}/kernel.rb +3 -7
  18. data/lib/{ext → waves/ext}/module.rb +3 -3
  19. data/lib/{ext → waves/ext}/object.rb +2 -0
  20. data/lib/waves/ext/string.rb +73 -0
  21. data/lib/{ext → waves/ext}/symbol.rb +0 -1
  22. data/lib/{ext → waves/ext}/tempfile.rb +0 -0
  23. data/lib/waves/ext/time.rb +5 -0
  24. data/lib/{foundations → waves/foundations}/classic.rb +9 -21
  25. data/lib/{foundations → waves/foundations}/compact.rb +15 -20
  26. data/lib/waves/foundations/rest.rb +311 -0
  27. data/lib/waves/helpers/basic.rb +13 -0
  28. data/lib/{helpers → waves/helpers}/doc_type.rb +3 -0
  29. data/lib/waves/helpers/form.rb +94 -0
  30. data/lib/waves/helpers/formatting.rb +14 -0
  31. data/lib/waves/layers/mvc.rb +65 -0
  32. data/lib/{layers → waves/layers}/mvc/controllers.rb +0 -0
  33. data/lib/{layers → waves/layers}/mvc/extensions.rb +23 -11
  34. data/lib/{layers → waves/layers}/orm/migration.rb +0 -0
  35. data/lib/{layers → waves/layers}/orm/providers/active_record.rb +2 -5
  36. data/lib/{layers → waves/layers}/orm/providers/active_record/migrations/empty.rb.erb +0 -0
  37. data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/generate.rb +1 -1
  38. data/lib/{layers → waves/layers}/orm/providers/active_record/tasks/schema.rb +1 -1
  39. data/lib/{layers → waves/layers}/orm/providers/data_mapper.rb +0 -0
  40. data/lib/{layers → waves/layers}/orm/providers/filebase.rb +0 -0
  41. data/lib/{layers → waves/layers}/orm/providers/sequel.rb +28 -29
  42. data/lib/{layers → waves/layers}/orm/providers/sequel/migrations/empty.rb.erb +0 -0
  43. data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/generate.rb +1 -1
  44. data/lib/{layers → waves/layers}/orm/providers/sequel/tasks/schema.rb +2 -0
  45. data/lib/waves/layers/rack/rack_cache.rb +32 -0
  46. data/lib/waves/layers/renderers/erubis.rb +52 -0
  47. data/lib/waves/layers/renderers/haml.rb +67 -0
  48. data/lib/waves/layers/renderers/markaby.rb +41 -0
  49. data/lib/waves/layers/text/inflect/english.rb +42 -0
  50. data/lib/waves/matchers/accept.rb +47 -0
  51. data/lib/waves/matchers/ext.rb +27 -0
  52. data/lib/waves/matchers/path.rb +72 -0
  53. data/lib/waves/matchers/query.rb +43 -0
  54. data/lib/waves/matchers/request.rb +86 -0
  55. data/lib/waves/matchers/requested.rb +31 -0
  56. data/lib/{matchers → waves/matchers}/resource.rb +8 -1
  57. data/lib/waves/matchers/traits.rb +30 -0
  58. data/lib/waves/matchers/uri.rb +69 -0
  59. data/lib/waves/media/mime_types.rb +542 -0
  60. data/lib/waves/renderers/mixin.rb +9 -0
  61. data/lib/waves/request/accept.rb +92 -0
  62. data/lib/{runtime → waves/request}/request.rb +77 -61
  63. data/lib/waves/resources/file_mixin.rb +11 -0
  64. data/lib/{resources → waves/resources}/mixin.rb +42 -44
  65. data/lib/waves/resources/paths.rb +132 -0
  66. data/lib/waves/response/client_errors.rb +10 -0
  67. data/lib/waves/response/packaged.rb +19 -0
  68. data/lib/waves/response/redirects.rb +35 -0
  69. data/lib/{runtime → waves/response}/response.rb +29 -11
  70. data/lib/{runtime → waves/response}/response_mixin.rb +30 -17
  71. data/lib/waves/runtime/applications.rb +18 -0
  72. data/lib/{runtime → waves/runtime}/configuration.rb +31 -25
  73. data/lib/waves/runtime/console.rb +24 -0
  74. data/lib/{runtime → waves/runtime}/logger.rb +3 -3
  75. data/lib/{runtime → waves/runtime}/mocks.rb +2 -2
  76. data/lib/waves/runtime/rackup.rb +37 -0
  77. data/lib/waves/runtime/runtime.rb +48 -0
  78. data/lib/waves/runtime/server.rb +33 -0
  79. data/lib/{servers → waves/servers}/base.rb +0 -0
  80. data/lib/{servers → waves/servers}/mongrel.rb +0 -0
  81. data/lib/{servers → waves/servers}/webrick.rb +0 -0
  82. data/lib/{tasks → waves/tasks}/gem.rb +0 -0
  83. data/lib/{tasks → waves/tasks}/generate.rb +0 -0
  84. data/lib/waves/views/cassy.rb +173 -0
  85. data/lib/{views → waves/views}/errors.rb +8 -7
  86. data/lib/waves/views/mixin.rb +23 -0
  87. data/lib/waves/views/templated.rb +40 -0
  88. data/samples/basic/basic_startup.rb +70 -0
  89. data/samples/basic/config.ru +9 -0
  90. data/samples/blog/configurations/development.rb +17 -16
  91. data/samples/blog/configurations/production.rb +0 -11
  92. data/samples/blog/resources/entry.rb +3 -3
  93. data/samples/blog/resources/map.rb +10 -3
  94. data/samples/blog/startup.rb +4 -3
  95. data/templates/classic/Rakefile +28 -29
  96. data/templates/classic/configurations/default.rb.erb +8 -3
  97. data/templates/classic/configurations/development.rb.erb +1 -20
  98. data/templates/classic/configurations/production.rb.erb +2 -16
  99. data/templates/classic/public/images/favicon.ico +0 -0
  100. data/templates/classic/resources/server.rb.erb +9 -0
  101. data/templates/classic/startup.rb.erb +3 -3
  102. data/templates/classic/views/css.rb.erb +14 -0
  103. data/templates/classic/views/default.rb.erb +17 -0
  104. data/templates/classic/views/errors.rb.erb +10 -0
  105. data/templates/classic/views/pages.rb.erb +14 -0
  106. data/templates/compact/startup.rb.erb +8 -3
  107. data/test/ext/object.rb +55 -0
  108. data/test/ext/shortcuts.rb +73 -0
  109. data/test/helpers.rb +17 -0
  110. data/test/match/accept.rb +78 -0
  111. data/test/match/ext.rb +156 -0
  112. data/test/match/methods.rb +22 -0
  113. data/test/match/params.rb +33 -0
  114. data/test/match/path.rb +106 -0
  115. data/test/match/query.rb +60 -0
  116. data/test/match/request.rb +91 -0
  117. data/test/match/requested.rb +149 -0
  118. data/test/match/uri.rb +136 -0
  119. data/test/process/request.rb +75 -0
  120. data/test/process/resource.rb +53 -0
  121. data/test/resources/path.rb +166 -0
  122. data/test/runtime/configurations.rb +19 -0
  123. data/test/runtime/request.rb +63 -0
  124. data/test/runtime/response.rb +85 -0
  125. data/test/views/views.rb +40 -0
  126. metadata +243 -157
  127. data/lib/caches/memcached.rb +0 -40
  128. data/lib/dispatchers/default.rb +0 -25
  129. data/lib/ext/string.rb +0 -20
  130. data/lib/helpers/basic.rb +0 -11
  131. data/lib/helpers/extended.rb +0 -21
  132. data/lib/helpers/form.rb +0 -42
  133. data/lib/helpers/formatting.rb +0 -30
  134. data/lib/helpers/layouts.rb +0 -37
  135. data/lib/helpers/model.rb +0 -37
  136. data/lib/helpers/view.rb +0 -22
  137. data/lib/layers/inflect/english.rb +0 -67
  138. data/lib/layers/mvc.rb +0 -54
  139. data/lib/layers/renderers/erubis.rb +0 -60
  140. data/lib/layers/renderers/haml.rb +0 -47
  141. data/lib/layers/renderers/markaby.rb +0 -29
  142. data/lib/matchers/accept.rb +0 -21
  143. data/lib/matchers/base.rb +0 -30
  144. data/lib/matchers/content_type.rb +0 -17
  145. data/lib/matchers/path.rb +0 -67
  146. data/lib/matchers/query.rb +0 -21
  147. data/lib/matchers/request.rb +0 -27
  148. data/lib/matchers/traits.rb +0 -19
  149. data/lib/matchers/uri.rb +0 -20
  150. data/lib/renderers/mixin.rb +0 -36
  151. data/lib/resources/paths.rb +0 -34
  152. data/lib/runtime/console.rb +0 -23
  153. data/lib/runtime/mime_types.rb +0 -536
  154. data/lib/runtime/monitor.rb +0 -32
  155. data/lib/runtime/runtime.rb +0 -67
  156. data/lib/runtime/server.rb +0 -20
  157. data/lib/runtime/session.rb +0 -27
  158. data/lib/runtime/worker.rb +0 -86
  159. data/lib/views/mixin.rb +0 -62
  160. data/samples/blog/blog.db +0 -0
  161. data/samples/blog/log/waves.production +0 -3
  162. data/templates/classic/resources/map.rb.erb +0 -8
  163. data/templates/classic/templates/errors/not_found_404.mab +0 -7
  164. data/templates/classic/templates/errors/server_error_500.mab +0 -7
  165. data/templates/classic/templates/layouts/default.mab +0 -14
  166. data/templates/classic/tmp/sessions/.gitignore +0 -0
data/bin/waves CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # WARNING: This strange preamble might look easy to clean-up, but it is needed
4
- # to work with older versions of gems (< 1.2).
4
+ # to work with older versions of gems (< 1.2). Also allows for local versions of
5
+ # Waves to be used instead of the gem.
5
6
 
6
7
  require 'rubygems'
7
8
 
@@ -24,7 +25,7 @@ require waves
24
25
  puts "** Waves #{Waves.version} **"
25
26
 
26
27
  begin
27
- require "commands/#{ARGV.first}"
28
+ require "waves/commands/#{ARGV.first}"
28
29
  rescue LoadError => e
29
- require "commands/help"
30
+ require "waves/commands/help"
30
31
  end
data/doc/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.2
1
+ 0.9.0
data/lib/waves.rb CHANGED
@@ -1,5 +1,9 @@
1
+ require 'yaml'
2
+ YAML::load_file( File.expand_path( File.dirname( __FILE__ )) + '/../dependencies.yml' ).each { |name,version| gem name, version }
1
3
  # External Dependencies
4
+ require "rubygems"
2
5
  require 'rack'
6
+ require 'rack/cache'
3
7
  require 'daemons'
4
8
 
5
9
  # a bunch of handy stuff
@@ -13,51 +17,59 @@ require 'benchmark'
13
17
  require 'base64'
14
18
  require 'functor'
15
19
  require 'filebase'
20
+ require 'hive/worker'
16
21
  require 'filebase/model'
17
22
 
18
- require 'english/style'
19
-
20
23
  # selected project-specific extensions
21
- require 'ext/integer'
22
- require 'ext/float'
23
- require 'ext/string'
24
- require 'ext/symbol'
25
- require 'ext/hash'
26
- require 'ext/tempfile'
27
- require 'ext/module'
28
- require 'ext/object'
29
- require 'ext/kernel'
24
+ require 'waves/ext/integer'
25
+ require 'waves/ext/float'
26
+ require 'waves/ext/string'
27
+ require 'waves/ext/symbol'
28
+ require 'waves/ext/hash'
29
+ require 'waves/ext/tempfile'
30
+ require 'waves/ext/module'
31
+ require 'waves/ext/object'
32
+ require 'waves/ext/kernel'
33
+ require 'waves/ext/time'
30
34
 
31
35
  # waves Runtime
32
- require 'servers/base'
33
- require 'servers/webrick'
34
- require 'servers/mongrel'
35
- require 'dispatchers/base'
36
- require 'dispatchers/default'
37
- require 'runtime/logger'
38
- require 'runtime/mime_types'
39
- require 'runtime/runtime'
40
- require 'runtime/worker'
41
- require 'runtime/request'
42
- require 'runtime/response'
43
- require 'runtime/response_mixin'
44
- require 'runtime/session'
45
- require 'runtime/configuration'
46
- require 'caches/simple'
36
+ require 'waves/servers/base'
37
+ require 'waves/servers/webrick'
38
+ require 'waves/servers/mongrel'
39
+ require 'waves/request/accept'
40
+ require 'waves/request/request'
41
+ require 'waves/response/response'
42
+ require 'waves/response/packaged'
43
+ require 'waves/response/client_errors'
44
+ require 'waves/response/response_mixin'
45
+ require 'waves/response/redirects'
46
+ require 'waves/dispatchers/base'
47
+ require 'waves/dispatchers/default'
48
+ require 'waves/runtime/logger'
49
+ require 'waves/media/mime_types'
50
+ require 'waves/runtime/applications'
51
+ require 'waves/runtime/runtime'
52
+ require 'waves/runtime/configuration'
53
+ require 'waves/caches/simple'
47
54
 
48
55
  # waves URI mapping
49
- require 'matchers/base'
50
- require 'matchers/accept'
51
- require 'matchers/content_type'
52
- require 'matchers/path'
53
- require 'matchers/query'
54
- require 'matchers/traits'
55
- require 'matchers/uri'
56
- require 'matchers/request'
57
- require 'matchers/resource'
58
- require 'resources/paths'
59
- require 'resources/mixin'
56
+ require 'waves/matchers/accept'
57
+ require "waves/matchers/ext"
58
+ require 'waves/matchers/path'
59
+ require 'waves/matchers/query'
60
+ require 'waves/matchers/traits'
61
+ require 'waves/matchers/uri'
62
+ require 'waves/matchers/request'
63
+ require 'waves/matchers/resource'
64
+ require 'waves/matchers/requested'
65
+ require 'waves/resources/paths'
66
+ require 'waves/resources/mixin'
67
+
68
+ require 'waves/views/mixin'
69
+ require 'waves/views/errors'
70
+ require 'waves/renderers/mixin'
60
71
 
61
- require 'views/mixin'
62
- require 'views/errors'
63
- require 'renderers/mixin'
72
+ module Waves
73
+ def self.version ; File.read( File.expand_path( "#{File.dirname(__FILE__)}/../doc/VERSION" ) ) ; end
74
+ def self.license ; File.read( File.expand_path( "#{File.dirname(__FILE__)}/../doc/LICENSE" ) ) ; end
75
+ end
@@ -1,8 +1,9 @@
1
- require 'caches/synchronized'
1
+ require 'waves/caches/synchronized'
2
2
 
3
3
  module Waves
4
4
  module Caches
5
5
 
6
+ # A file-based cache, where the keys are the filenames.
6
7
  class File < Simple
7
8
 
8
9
  def initialize( args )
@@ -34,6 +35,7 @@ module Waves
34
35
 
35
36
  end
36
37
 
38
+ # A thread-safe version of the File-based cache.
37
39
  class SynchronizedFile < Synchronized
38
40
 
39
41
  def initialize( args )
@@ -0,0 +1,56 @@
1
+ require 'memcached'
2
+ module Waves
3
+ module Caches
4
+
5
+ # A simple interface to Memcached. Pass in the memcached server to
6
+ # the constructor, like this:
7
+ #
8
+ # Waves::Caches::Memcached.new( 'localhost:11211' )
9
+ #
10
+ # Memcached::NotFound is converted to nil, even though nil is, in fact,
11
+ # a valid value to want to cache. Rather than force every use of the
12
+ # cache interface to add exception handling for the (relatively rare)
13
+ # case where nil is an expected value, just code those cases using
14
+ # the #exists? method.
15
+ #
16
+ # This interface is not thread-safe. If you want to use this in apps
17
+ # where you are handling requests in parallel, use SynchronizedMemcached.
18
+ #
19
+ class Memcached < Simple
20
+
21
+ def initialize( args )
22
+ raise ArgumentError, ":servers is nil" if args[ :servers ].nil?
23
+ @cache = ::Memcached.new( args[ :servers ], args[ :options ] || {} )
24
+ end
25
+
26
+ def store( key, value, ttl = 0, marshal = true )
27
+ @cache.add( key.to_s, value, ttl, marshal )
28
+ end
29
+
30
+ def fetch( key )
31
+ @cache.get( key.to_s )
32
+ rescue ::Memcached::NotFound => e
33
+ nil
34
+ end
35
+
36
+ def delete( key )
37
+ @cache.delete( key.to_s )
38
+ end
39
+
40
+ def clear
41
+ @cache.flush
42
+ end
43
+
44
+ end
45
+
46
+ # A thread-safe version of Memcached.
47
+ class SynchronizedMemcached < Synchronized
48
+
49
+ def initialize( args )
50
+ super( Memcached.new( args ) )
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -1,12 +1,11 @@
1
1
  module Waves
2
2
 
3
3
  module Caches
4
-
5
- #
6
- # This class is more or less here to establish the basic interface for caching and for
7
- # lightweight caching that doesn't require a dedicated caching process.
8
- #
9
-
4
+
5
+ # A simple in-memory cache. This also serves as the base class
6
+ # for all the Waves caching implementations, so that descendents
7
+ # only need to override #initialize, #fetch, #store, #delete, and
8
+ # #clear, since the other methods are defined in terms of those.
10
9
  class Simple
11
10
 
12
11
  def initialize( hash = {} ) ; @cache = hash ; end
@@ -20,6 +19,6 @@ module Waves
20
19
  def clear ; @cache = {} ; end
21
20
 
22
21
  end
23
-
22
+
24
23
  end
25
24
  end
@@ -4,7 +4,8 @@ module Waves
4
4
  module Caches
5
5
 
6
6
  #
7
- # This is just a proxy for the real cache, but adds Waves synchronization
7
+ # This is just a proxy for the real cache, but adds Waves synchronization. Pass the cache you
8
+ # want to use when you create the cache.
8
9
  #
9
10
 
10
11
  class Synchronized
@@ -19,7 +20,20 @@ module Waves
19
20
  def delete( key ) ; synchronize { @cache.delete( key ) } ; end
20
21
  def clear ; synchronize { @cache.clear } ; end
21
22
  def synchronize( &block ) ; Waves.synchronize( &block ) ; end
23
+
24
+ end
25
+
26
+
27
+ # A thread-safe version of the in-memory cache.
28
+ class SynchronizedSimple < Synchronized
29
+
30
+ def initialize( args )
31
+ super( Simple.new( args ) )
32
+ end
33
+
22
34
  end
35
+
36
+
23
37
 
24
38
  end
25
39
  end
@@ -10,7 +10,7 @@ Choice.options do
10
10
  desc 'Defaults to development.'
11
11
  cast Symbol
12
12
  end
13
- separator ''
13
+ separator ''
14
14
  option :startup do
15
15
  short '-s'
16
16
  long '--startup'
@@ -20,7 +20,7 @@ Choice.options do
20
20
  separator ''
21
21
  end
22
22
 
23
- require 'runtime/console'
23
+ require 'waves/runtime/console'
24
24
 
25
25
  begin
26
26
  console = Waves::Console.load( Choice.choices )
@@ -28,8 +28,8 @@ begin
28
28
  require 'irb'
29
29
  require 'irb/completion'
30
30
  ARGV.clear
31
- Waves.log.info "Runtime console starting ..."
31
+ Waves.logger.info "Runtime console starting ..."
32
32
  IRB.start
33
33
  rescue LoadError => e
34
34
  puts e.message
35
- end
35
+ end
@@ -1,17 +1,18 @@
1
1
  require 'choice'
2
+ gem 'rakegen', '=0.6.6'
2
3
  require 'rakegen'
3
4
 
4
- waves = File.expand_path( File.dirname( __FILE__ ) / '..' / '..' )
5
- orms = Dir[ waves / :lib / :layers / :orm / :providers / '*.rb' ].map { |path| File.basename( path, '.rb' )}
5
+ waves = File.expand_path( File.dirname( __FILE__ ) / '..' / '..' / '..' )
6
+ orms = Dir[ waves / :lib / :waves / :layers / :orm / :providers / '*.rb' ].map { |path| File.basename( path, '.rb' )}
6
7
  templates = Dir[ waves / :templates / '*' ].map { |path| File.basename( path ) }
7
8
 
8
9
  Choice.options do
9
-
10
+
10
11
  option :help do
11
12
  long '--help'
12
13
  desc 'Show this message'
13
14
  end
14
-
15
+
15
16
  option :orm do
16
17
  short '-o'
17
18
  long '--orm=ORM'
@@ -49,4 +50,4 @@ generator = Rakegen.new("generate") do |gen|
49
50
  gen.template_assigns = options.merge( :name => options.name.gsub('-','_').camel_case )
50
51
  end.invoke
51
52
 
52
- puts "** Application created!"
53
+ puts "** Application created!"
File without changes
@@ -60,7 +60,7 @@ Choice.options do
60
60
  separator ''
61
61
  end
62
62
 
63
- require 'runtime/server'
63
+ require 'waves/runtime/server'
64
64
  begin
65
65
  Waves::Server.run( Choice.choices )
66
66
  rescue LoadError => e
@@ -2,38 +2,21 @@ module Waves
2
2
 
3
3
  module Dispatchers
4
4
 
5
- class NotFoundError < RuntimeError ; end
6
- class Unauthorized < RuntimeError; end
7
- class BadRequest < RuntimeError; end
8
-
9
- # Redirect exceptions are rescued by the Waves dispatcher and used to set the
10
- # response status and location.
11
- class Redirect < SignalException
12
- attr_reader :path, :status
13
- def initialize( path, status = '302' )
14
- @path = path
15
- @status = status
16
- end
17
- def message
18
- "location: #{@path} status: #{@status}"
19
- end
20
- end
21
-
22
5
  #
23
6
  # Waves::Dispatchers::Base provides the basic request processing structure
24
- # for a Rack application. It creates a Waves request, determines whether
25
- # to enclose the request processing in a mutex benchmarks it, logs it,
26
- # and handles redirects. Derived classes need only process the request
27
- # within the +safe+ method, which must take a Waves::Request and return
7
+ # for a Rack application. It creates a Waves request, determines whether
8
+ # to enclose the request processing in a mutex benchmarks it, logs it,
9
+ # and handles redirects. Derived classes need only process the request
10
+ # within the +safe+ method, which must take a Waves::Request and return
28
11
  # a Waves::Response.
29
12
  #
30
-
13
+
31
14
  class Base
32
15
 
33
16
  # As with any Rack application, a Waves dispatcher must provide a call method
34
17
  # that takes an +env+ hash.
35
18
  def call( env )
36
- response = if Waves.synchronize? or Waves.debug?
19
+ response = if Waves.synchronize? || Waves.debug?
37
20
  Waves.synchronize { Waves.reload ; _call( env ) }
38
21
  else
39
22
  _call( env )
@@ -43,24 +26,27 @@ module Waves
43
26
  # Called by event driven servers like thin and ebb. Returns true if
44
27
  # the server should run the request in a separate thread.
45
28
  def deferred?( env ) ; Waves.config.resource.new( Waves::Request.new( env ) ).deferred? ; end
46
-
29
+
47
30
  private
48
-
31
+
49
32
  def _call( env )
50
33
  request = Waves::Request.new( env )
51
34
  response = request.response
52
35
  t = Benchmark.realtime do
53
36
  begin
54
- safe( request )
55
- rescue Dispatchers::Redirect => redirect
56
- response.status = redirect.status
57
- response.location = redirect.path
37
+ response.write( safe( request ).to_s ) if response.body.empty?
38
+ rescue Waves::Response::Packaged => e
39
+ e.call( response ) if e.respond_to?( :call )
40
+ else
41
+ # safeish default
42
+ response.content_type ||= Waves::MimeTypes[ request.ext ].first || 'text/html'
43
+ response.status ||= '200'
58
44
  end
59
45
  end
60
- Waves::Logger.info "#{request.method}: #{request.url} handled in #{(t*1000).round} ms."
46
+ Waves::Logger.info "#{response.status}: #{request.method} #{request.url} handled in #{(t*1000).round} ms."
61
47
  response.finish
62
48
  end
63
-
49
+
64
50
  end
65
51
 
66
52
  end
@@ -0,0 +1,19 @@
1
+ module Waves
2
+
3
+ module Dispatchers
4
+
5
+ class Default < Base
6
+
7
+ #
8
+ # Takes a Waves::Request and returns a Waves::Response
9
+ #
10
+
11
+ def safe(request)
12
+ Waves.config.resource.new( request ).process
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
File without changes
File without changes