nitro 0.31.0 → 0.40.0

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.
Files changed (174) hide show
  1. data/bin/nitro +135 -37
  2. data/doc/CHANGELOG.1 +108 -108
  3. data/doc/CHANGELOG.2 +89 -89
  4. data/doc/CHANGELOG.3 +105 -105
  5. data/{CHANGELOG → doc/CHANGELOG.4} +509 -509
  6. data/doc/{AUTHORS → CONTRIBUTORS} +49 -37
  7. data/doc/LIBRARIES +13 -0
  8. data/doc/LICENSE +2 -3
  9. data/doc/MIGRATION +45 -0
  10. data/doc/RELEASES +131 -11
  11. data/doc/TODO +67 -0
  12. data/lib/glue/magick.rb +0 -3
  13. data/lib/glue/sweeper.rb +30 -15
  14. data/lib/glue/thumbnails.rb +0 -2
  15. data/lib/glue/webfile.rb +23 -11
  16. data/lib/nitro.rb +37 -44
  17. data/lib/nitro/adapter/cgi.rb +0 -3
  18. data/lib/nitro/adapter/console.rb +0 -2
  19. data/lib/nitro/adapter/fastcgi.rb +6 -3
  20. data/lib/nitro/adapter/mongrel.rb +97 -58
  21. data/lib/nitro/adapter/script.rb +4 -6
  22. data/lib/nitro/adapter/webrick.rb +33 -87
  23. data/lib/nitro/adapter/webrick/vcr.rb +85 -0
  24. data/lib/nitro/caching.rb +0 -2
  25. data/lib/nitro/caching/actions.rb +0 -2
  26. data/lib/nitro/caching/fragments.rb +0 -2
  27. data/lib/nitro/caching/output.rb +45 -16
  28. data/lib/nitro/caching/proxy.rb +49 -0
  29. data/lib/nitro/cgi.rb +3 -6
  30. data/lib/nitro/cgi/cookie.rb +0 -3
  31. data/lib/nitro/cgi/request.rb +67 -24
  32. data/lib/nitro/cgi/response.rb +0 -2
  33. data/lib/nitro/cgi/{sendfile.rb → send_file.rb} +7 -6
  34. data/lib/nitro/compiler.rb +62 -55
  35. data/lib/nitro/compiler/cleanup.rb +0 -3
  36. data/lib/nitro/compiler/elements.rb +31 -28
  37. data/lib/nitro/compiler/errors.rb +2 -5
  38. data/lib/nitro/compiler/include.rb +10 -8
  39. data/lib/nitro/compiler/layout.rb +0 -2
  40. data/lib/nitro/compiler/localization.rb +0 -2
  41. data/lib/nitro/compiler/markup.rb +14 -6
  42. data/lib/nitro/compiler/morphing.rb +1 -5
  43. data/lib/nitro/compiler/script.rb +2 -4
  44. data/lib/nitro/compiler/squeeze.rb +0 -2
  45. data/lib/nitro/compiler/xslt.rb +0 -2
  46. data/lib/nitro/context.rb +10 -5
  47. data/lib/nitro/control.rb +18 -0
  48. data/lib/nitro/control/attribute.rb +88 -0
  49. data/lib/nitro/control/attribute/checkbox.rb +19 -0
  50. data/lib/nitro/control/attribute/datetime.rb +21 -0
  51. data/lib/nitro/control/attribute/file.rb +20 -0
  52. data/lib/nitro/control/attribute/fixnum.rb +26 -0
  53. data/lib/nitro/control/attribute/float.rb +26 -0
  54. data/lib/nitro/control/attribute/options.rb +38 -0
  55. data/lib/nitro/control/attribute/password.rb +16 -0
  56. data/lib/nitro/control/attribute/text.rb +16 -0
  57. data/lib/nitro/control/attribute/textarea.rb +16 -0
  58. data/lib/nitro/control/none.rb +16 -0
  59. data/lib/nitro/control/relation.rb +53 -0
  60. data/lib/nitro/control/relation/belongs_to.rb +0 -0
  61. data/lib/nitro/control/relation/has_many.rb +97 -0
  62. data/lib/nitro/control/relation/joins_many.rb +0 -0
  63. data/lib/nitro/control/relation/many_to_many.rb +0 -0
  64. data/lib/nitro/control/relation/refers_to.rb +29 -0
  65. data/lib/nitro/controller.rb +7 -296
  66. data/lib/nitro/dispatcher.rb +72 -34
  67. data/lib/nitro/element.rb +36 -10
  68. data/lib/nitro/element/javascript.rb +0 -2
  69. data/lib/nitro/flash.rb +23 -10
  70. data/lib/nitro/global.rb +36 -11
  71. data/lib/nitro/helper.rb +22 -8
  72. data/lib/nitro/helper/benchmark.rb +0 -2
  73. data/lib/nitro/helper/buffer.rb +0 -3
  74. data/lib/nitro/helper/css.rb +12 -0
  75. data/lib/nitro/helper/debug.rb +1 -3
  76. data/lib/nitro/helper/default.rb +1 -0
  77. data/lib/nitro/helper/feed.rb +400 -386
  78. data/lib/nitro/helper/form.rb +246 -116
  79. data/lib/nitro/helper/javascript.rb +28 -2
  80. data/lib/nitro/helper/javascript/morphing.rb +0 -2
  81. data/lib/nitro/helper/javascript/prototype.rb +0 -2
  82. data/lib/nitro/helper/javascript/scriptaculous.rb +0 -1
  83. data/lib/nitro/helper/layout.rb +0 -2
  84. data/lib/nitro/helper/navigation.rb +87 -0
  85. data/lib/nitro/helper/pager.rb +11 -22
  86. data/lib/nitro/helper/table.rb +9 -32
  87. data/lib/nitro/helper/url.rb +104 -0
  88. data/lib/nitro/helper/xhtml.rb +20 -4
  89. data/lib/nitro/helper/xml.rb +0 -2
  90. data/lib/nitro/markup.rb +131 -0
  91. data/lib/nitro/part.rb +52 -7
  92. data/lib/nitro/publishable.rb +328 -0
  93. data/lib/nitro/render.rb +30 -61
  94. data/lib/nitro/router.rb +12 -4
  95. data/lib/nitro/sanitize.rb +48 -0
  96. data/lib/nitro/scaffold.rb +9 -11
  97. data/lib/nitro/scaffold/controller.rb +25 -0
  98. data/lib/nitro/scaffold/model.rb +150 -0
  99. data/lib/nitro/scaffolding.rb +1 -3
  100. data/lib/nitro/server.rb +57 -32
  101. data/lib/nitro/server/drb.rb +16 -2
  102. data/lib/nitro/server/runner.rb +80 -102
  103. data/lib/nitro/service.rb +0 -1
  104. data/lib/nitro/service/xmlrpc.rb +0 -2
  105. data/lib/nitro/session.rb +26 -18
  106. data/lib/nitro/session/drb.rb +2 -16
  107. data/lib/nitro/session/memory.rb +0 -2
  108. data/lib/nitro/template.rb +219 -0
  109. data/lib/nitro/test/assertions.rb +1 -3
  110. data/lib/nitro/test/context.rb +0 -1
  111. data/lib/nitro/test/testcase.rb +0 -1
  112. data/lib/nitro/version.rb +6 -0
  113. data/lib/part/admin.rb +16 -0
  114. data/lib/part/admin/controller.rb +19 -0
  115. data/lib/part/admin/helper.rb +30 -0
  116. data/lib/part/admin/og/controller.rb +114 -0
  117. data/lib/part/admin/og/customize.rb +4 -0
  118. data/lib/part/admin/og/template/index.xhtml +27 -0
  119. data/lib/part/admin/og/template/list.xhtml +38 -0
  120. data/lib/part/admin/og/template/search.xhtml +20 -0
  121. data/lib/part/admin/og/template/update.xhtml +25 -0
  122. data/lib/part/admin/skin.rb +207 -0
  123. data/lib/part/admin/template/denied.xhtml +13 -0
  124. data/lib/part/admin/template/index.xhtml +12 -0
  125. data/lib/part/admin/todo.txt +2 -0
  126. data/proto/public/error.xhtml +4 -2
  127. data/proto/run.rb +0 -2
  128. data/test/glue/tc_webfile.rb +1 -0
  129. data/test/nitro/cgi/tc_request.rb +23 -0
  130. data/test/nitro/helper/tc_feed.rb +0 -3
  131. data/test/nitro/helper/tc_navbar.rb +74 -0
  132. data/test/nitro/helper/tc_table.rb +2 -0
  133. data/test/nitro/tc_cgi.rb +72 -19
  134. data/test/nitro/tc_controller.rb +35 -26
  135. data/test/nitro/tc_controller_aspect.rb +1 -0
  136. data/test/nitro/tc_controller_params.rb +864 -0
  137. data/test/nitro/tc_dispatcher.rb +2 -2
  138. data/test/nitro/tc_element.rb +16 -16
  139. data/test/nitro/tc_flash.rb +3 -3
  140. data/test/nitro/tc_markup.rb +31 -0
  141. data/test/nitro/tc_render.rb +12 -14
  142. data/test/nitro/tc_session.rb +9 -7
  143. data/test/nitro/tc_template.rb +34 -0
  144. metadata +217 -198
  145. data/INSTALL +0 -121
  146. data/ProjectInfo +0 -74
  147. data/README +0 -555
  148. data/doc/apache.txt +0 -9
  149. data/doc/config.txt +0 -28
  150. data/doc/faq.txt +0 -7
  151. data/doc/lhttpd.txt +0 -7
  152. data/lib/nitro/adapter/scgi.rb +0 -239
  153. data/lib/nitro/helper/form/builder.rb +0 -144
  154. data/lib/nitro/helper/form/controls.rb +0 -389
  155. data/lib/nitro/helper/rss.rb +0 -72
  156. data/proto/conf/apache.conf +0 -51
  157. data/proto/public/scaffold/advanced_search.xhtml +0 -30
  158. data/proto/public/scaffold/edit.xhtml +0 -11
  159. data/proto/public/scaffold/form.xhtml +0 -1
  160. data/proto/public/scaffold/index.xhtml +0 -20
  161. data/proto/public/scaffold/list.xhtml +0 -32
  162. data/proto/public/scaffold/new.xhtml +0 -11
  163. data/proto/public/scaffold/search.xhtml +0 -29
  164. data/proto/public/scaffold/view.xhtml +0 -8
  165. data/proto/script/scgi_ctl +0 -221
  166. data/proto/script/scgi_service +0 -128
  167. data/setup.rb +0 -1585
  168. data/src/part/admin.rb +0 -16
  169. data/src/part/admin/controller.rb +0 -81
  170. data/src/part/admin/skin.rb +0 -21
  171. data/src/part/admin/system.css +0 -135
  172. data/src/part/admin/template/denied.xhtml +0 -1
  173. data/src/part/admin/template/index.xhtml +0 -43
  174. data/test/nitro/helper/tc_rss.rb +0 -24
@@ -33,6 +33,3 @@ module Thumbnails
33
33
  end
34
34
 
35
35
  end
36
-
37
- # * George Moschovitis <gm@navel.gr>
38
- # * Michael Fellinger <m.fellinger@gmail.com>
@@ -13,12 +13,22 @@ module Glue
13
13
 
14
14
  module Sweeper
15
15
  include Aspects
16
-
16
+
17
+ #--
18
+ # Inject the sweepers *after* the event to have a valid
19
+ # oid.
20
+ #++
21
+
17
22
  before "sweep_affected(:insert)", :on => :og_insert
18
23
  before "sweep_affected(:update)", :on => :og_update
19
24
  before "sweep_affected(:delete)", :on => :og_delete
20
25
 
21
26
  # Expires (deletes) a cached page from the file system.
27
+ #
28
+ # == Input
29
+ #
30
+ # * relative = if set to true, prepends the controller
31
+ # mount path.
22
32
  #--
23
33
  # FIXME: replace with 'extend Nitro::Caching::Output' ?
24
34
  # this way we wont have to sync the same code in two different
@@ -27,14 +37,16 @@ module Sweeper
27
37
  # expire method.
28
38
  #++
29
39
 
30
- def self.expire(name, klass)
31
- begin
32
- filename = "#{Server.public_root}/#{klass.ann.self.controller.mount_path}/#{name}".squeeze('/')
33
- Logger.debug "Sweeper expired cache file '#{filename}'" if $DBG
34
- FileUtils.rm_rf(filename)
35
- rescue Object
36
- # gmosx: is this the right thing to do?
40
+ def self.expire(name, klass, relative = false)
41
+ if relative and controller = klass.ann.self[:controller]
42
+ filename = "#{Server.public_root}/#{controller.mount_path}/#{name}.html".squeeze('/')
43
+ else
44
+ filename = "#{Server.public_root}/#{name}.html".squeeze('/')
37
45
  end
46
+ Logger.debug "Sweeper expired cache file '#{filename}'" if $DBG
47
+ FileUtils.rm_rf(filename)
48
+ rescue Object => ex
49
+ # ignore any error.
38
50
  end
39
51
 
40
52
  private
@@ -52,12 +64,17 @@ private
52
64
  end
53
65
  alias_method :expire_affected, :sweep_affected
54
66
 
55
- #--
56
- # Generally you don't override this.
57
- #++
67
+ # Called from an action that modifies the model to expire
68
+ # affected (dependend) cached pages. Generally you don't
69
+ # override this method.
70
+ #
71
+ # == Input
72
+ #
73
+ # * relative = if set to true, prepends the controller
74
+ # mount path.
58
75
 
59
- def expire_affected_output(name)
60
- Sweeper.expire(name, self.class)
76
+ def expire_affected_output(name, relative = true)
77
+ Sweeper.expire(name, self.class, relative)
61
78
  end
62
79
  alias_method :expire_output, :expire_affected_output
63
80
 
@@ -71,5 +88,3 @@ private
71
88
  end
72
89
 
73
90
  end
74
-
75
- # * George Moschovitis <gm@navel.gr>
@@ -1,3 +1 @@
1
1
  require 'glue/magick'
2
-
3
- # * George Moschovitis <gm@navel.gr>
@@ -27,33 +27,45 @@ class WebFile
27
27
  # webapp dir for easier updates.
28
28
 
29
29
  setting :upload_root, :default => 'upload', :doc => 'The directory where upload files are stored'
30
+
31
+ # Override files by default?
32
+
33
+ setting :override_files, :default => true, :doc => 'Override files by default?'
30
34
 
31
35
  # Modify the base class when this class is included as
32
36
  # property
33
37
 
34
- def self.included_as_property(base, names, options)
38
+ def self.included_as_property base, args
39
+ if args.last.is_a?(Hash)
40
+ options = args.pop
41
+ else
42
+ options = Hash.new
43
+ end
44
+
45
+ args.pop if args.last.is_a?(Class)
46
+
35
47
  if thumbnails = (options[:thumbnail] || options[:thumbnails] || options[:magick]) or self.name == 'WebImage'
36
48
  require 'glue/thumbnails'
37
49
  base.send :include, Thumbnails
38
50
  thumbnails = { :small => :thumbnails } if thumbnails.is_a?(String)
39
51
  end
40
52
 
41
- for name in names
53
+ for name in args
42
54
  base.module_eval do
43
55
  # The 'web' path to the file (relative to the public
44
56
  # root directory. Uses the original property name
45
57
  # or the #{name}_path alias.
46
58
 
47
- property name.to_sym, String
59
+ attr_accessor name.to_sym, String
48
60
  alias_method "#{name}_path".to_sym, name.to_sym
49
61
 
50
62
  # The file size.
51
63
 
52
- property "#{name}_size".to_sym, Fixnum
64
+ attr_accessor "#{name}_size".to_sym, Fixnum
53
65
 
54
- # The mime type
66
+ # The mime type.
55
67
 
56
- property "#{name}_mime_type".to_sym, String
68
+ attr_accessor "#{name}_mime_type".to_sym, String
57
69
 
58
70
  # Assignment callbacks.
59
71
  #--
@@ -66,7 +78,7 @@ class WebFile
66
78
  if thumbnails
67
79
  for tname in thumbnails.keys
68
80
  base.module_eval do
69
- property "#{name}_#{tname}_thumbnail".to_sym, String
81
+ attr_accessor "#{name}_#{tname}_thumbnail".to_sym, String
70
82
  end
71
83
  end
72
84
  end
@@ -78,6 +90,8 @@ class WebFile
78
90
 
79
91
  def #{name}_from_request(request)
80
92
  param = request['#{name}']
93
+
94
+ return if param.nil? or param.original_filename.blank?
81
95
  }
82
96
  if base.respond_to? :webfile_path
83
97
  code << %{
@@ -94,6 +108,7 @@ class WebFile
94
108
  @#{name}_size = param.size
95
109
 
96
110
  real_path = #{name}_real_path
111
+ raise 'file exists' if !WebFile.override_files and File.exists?(real_path)
97
112
  FileUtils.mkdir_p(File.dirname(real_path))
98
113
  if param.path
99
114
  FileUtils.cp(param.path, real_path)
@@ -102,7 +117,7 @@ class WebFile
102
117
  param.rewind
103
118
  File.open(real_path, 'wb') { |f| f << param.read }
104
119
  end
105
- FileUtils.chmod(0777, real_path)
120
+ FileUtils.chmod(0664, real_path)
106
121
  }
107
122
 
108
123
  if thumbnails
@@ -145,6 +160,3 @@ end
145
160
  WebImage = WebFile
146
161
 
147
162
  end
148
-
149
- # * George Moschovitis <gm@navel.gr>
150
- # * Michael Fellinger <m.fellinger@gmail.com>
@@ -1,23 +1,19 @@
1
1
  # = Nitro
2
2
  #
3
3
  # Copyright (c) 2004-2006, George Moschovitis (http://www.gmosx.com)
4
- # Copyright (c) 2004-2006, Navel Ltd (http://www.navel.gr)
5
4
  #
6
5
  # Nitro (http://www.nitroproject.org) is copyrighted free software
7
- # created and maintained by George Moschovitis (mailto:gm@navel.gr)
8
- # and released under the standard BSD Licence. For details
9
- # consult the file doc/LICENCE.
6
+ # created and maintained by George Moschovitis
7
+ # (mailto:george.moschovitis@gmail.com) and released under the
8
+ # standard BSD Licence. For details consult the file doc/LICENCE.
10
9
 
11
10
  require 'glue'
12
11
  require 'glue/logger'
13
12
  require 'glue/configuration'
14
13
 
15
- module Nitro
16
-
17
- # The version.
18
-
19
- Version = '0.31.0'
14
+ require 'nitro/version'
20
15
 
16
+ module Nitro
21
17
  # Library path.
22
18
 
23
19
  LibPath = File.dirname(__FILE__)
@@ -26,15 +22,32 @@ module Nitro
26
22
 
27
23
  setting :proto_path, :default => File.join(LibPath, '..', 'proto'), :doc => 'The path to the prototype application'
28
24
 
29
- # Add the src dir in the path.
30
-
31
- $LOAD_PATH.unshift File.join(LibPath, '..', 'src')
25
+ # The adapter used to serve nitro applications.
32
26
 
33
- # Include the Glue namespace in Nitro
27
+ setting :adapter, :default => :webrick, :doc => 'The web adapter'
28
+
29
+ # Add standard dirs in the path.
30
+
31
+ $LOAD_PATH.unshift Dir.pwd
32
+ $LOAD_PATH.unshift File.join(Dir.pwd, 'lib')
33
+
34
+ # Include the Glue namespace in Nitro.
34
35
 
35
36
  include Glue
36
37
  end
37
38
 
39
+ #--
40
+ # gmosx: leave them here.
41
+ #++
42
+
43
+ require 'nitro/global'
44
+ require 'nitro/context'
45
+ require 'nitro/controller'
46
+ require 'nitro/dispatcher'
47
+ require 'nitro/render'
48
+ require 'nitro/server'
49
+ require 'nitro/part'
50
+
38
51
  unless $NITRO_NO_ENVIRONMENT
39
52
  # Setup up the proposed environment. You are free
40
53
  # to skip this if you dont like it. Just set
@@ -47,58 +60,38 @@ unless $NITRO_NO_ENVIRONMENT
47
60
 
48
61
  Dir.chdir(File.dirname($0))
49
62
 
50
- # Application code come here.
51
-
52
- $LOAD_PATH.unshift 'src'
53
-
54
63
  # Library code come here.
55
64
 
56
65
  $LOAD_PATH.unshift 'lib'
57
66
  end
58
67
 
59
- #--
60
- # gmosx: leave them here.
61
- #++
62
-
63
- require 'nitro/global'
64
- require 'nitro/context'
65
- require 'nitro/controller'
66
- require 'nitro/dispatcher'
67
- require 'nitro/render'
68
- require 'nitro/server'
69
- require 'nitro/part'
70
-
71
68
  module Nitro
72
69
 
73
70
  class << self
74
71
 
72
+ attr_accessor :server
73
+
75
74
  # A helper method to start a Nitro application.
76
75
 
77
76
  def run(controller = nil)
78
- Server.run(controller)
77
+ @server = Server.run(controller)
79
78
  end
80
79
  alias_method :start, :run
81
80
 
82
- # A helper to get the current execution mode.
81
+ # A helper method. Will be deprecated, use
82
+ # Configuration.mode instead.
83
83
 
84
- def mode
85
- Runner.mode
84
+ def live?
85
+ Configuration.mode == :live
86
86
  end
87
- alias_method :execution_mode, :mode
88
-
87
+ alias_method :production?, :live?
89
88
 
90
- # A helper method.
89
+ # Deprecated, use Configuration.mode instead.
91
90
 
92
- def live?
93
- Runner.mode == :live
91
+ def mode
92
+ Configuration.mode
94
93
  end
95
- alias_method :production?, :live?
96
94
 
97
95
  end
98
96
 
99
- $global = $application = Global
100
-
101
97
  end
102
-
103
-
104
- # * George Moschovitis <gm@navel.gr>
@@ -41,6 +41,3 @@ class CgiAdapter
41
41
  end
42
42
 
43
43
  end
44
-
45
- # * James Britt <james_b@neurogami.com>
46
- # * George Moschovitis <gm@navel.gr>
@@ -3,5 +3,3 @@ require 'nitro/adapter/script'
3
3
  module Nitro
4
4
  ConsoleAdapter = ScriptAdapter
5
5
  end
6
-
7
- # * George Moschovitis <gm@navel.gr>
@@ -22,10 +22,15 @@ module Nitro
22
22
  #
23
23
  # === Sessions
24
24
  #
25
- # As FCGI is process based, you have cant use the default
25
+ # As FCGI is process based, you have can't use the default
26
26
  # in-memory session store. For production web sites you should
27
27
  # use the drb session store. Moreover, there is no need for
28
28
  # DB connection pooling in Og.
29
+ #
30
+ #--
31
+ # gmosx: I always thought that the concept of FastCGI is stupid!
32
+ # Why don't you use a proxy setup? (For example Apache + Mongrel)
33
+ #++
29
34
 
30
35
  class FastCGI
31
36
 
@@ -41,5 +46,3 @@ class FastCGI
41
46
  end
42
47
 
43
48
  end
44
-
45
- # * George Moschovitis <gm@navel.gr>
@@ -16,6 +16,7 @@ Socket.do_not_reverse_lookup = true
16
16
  #++
17
17
 
18
18
  module Mongrel # :nodoc: all
19
+
19
20
  class HttpRequest
20
21
  def method_missing(name, *args)
21
22
  if @params.has_key?(name.to_s.upcase)
@@ -27,6 +28,13 @@ module Mongrel # :nodoc: all
27
28
  end
28
29
  end
29
30
  end
31
+
32
+ class Configurator
33
+ def log(msg)
34
+ Logger.info msg
35
+ end
36
+ end
37
+
30
38
  end
31
39
 
32
40
  module Nitro
@@ -35,57 +43,53 @@ class Mongrel
35
43
 
36
44
  class << self
37
45
  attr_accessor :mongrel
46
+ attr_accessor :mongrel_config
38
47
 
39
- # Start the Webrick adapter.
48
+ # Start the Mongrel adapter.
40
49
 
41
50
  def start(server)
42
51
  # TODO add logging.
43
-
44
- mongrel_options = server.options.dup
45
-
46
- mongrel_options.update(
47
- :BindAddress => server.address,
48
- :Port => server.port,
49
- :DocumentRoot => server.public_root
50
- )
51
-
52
- @mongrel = ::Mongrel::HttpServer.new(mongrel_options[:BindAddress],
53
- mongrel_options[:Port])
54
-
55
- trap('INT') { exit } # works until you use breakpoint... why?
56
-
57
- @mongrel.register('/', MongrelAdapter.new(server))
58
-
59
- initialize_mongrel(server)
60
-
61
- @mongrel.run
62
- @mongrel_thread = @mongrel.acceptor
63
- @mongrel_thread.join
64
- end
65
52
 
66
- # Stop the Mongrel adapter.
53
+ @mongrel_config = ::Mongrel::Configurator.new :host => server.address do
54
+ listener :port => server.port do
55
+ uri "/", :handler => MongrelAdapter.new(server)
56
+ trap('INT') { Nitro::Mongrel.stop(server) }
57
+ run
58
+ end
59
+ end
67
60
 
68
- def stop
69
- @mongrel_thread.kill
61
+ @mongrel_config.log("Started Mongrel on " + server.address + ":" + server.port.to_s)
62
+ @mongrel_config.join
70
63
  end
71
-
64
+
65
+ # Stop the Mongrel adapter.
66
+
67
+ def stop(server = nil)
68
+ @mongrel_config.log("Stopped Mongrel on " + server.address + ":" + server.port.to_s)
69
+ @mongrel_config.stop
70
+ end
71
+
72
72
  # Override this method to perform customized mongrel
73
73
  # initialization.
74
-
74
+
75
75
  def initialize_mongrel(server)
76
76
  end
77
-
77
+
78
78
  end
79
-
79
+
80
80
  end
81
81
 
82
- # A Mongrel Adapter for Nitro.
82
+ # A Mongrel Adapter for Nitro. This is the prefered adapter to
83
+ # use in production mode. Typically you will have a front-end
84
+ # web server (for example apache) handle static content and
85
+ # proxy dynamic content request to a cluster of mongrel servers.
83
86
 
84
87
  class MongrelAdapter < ::Mongrel::HttpHandler
85
88
  attr_accessor :server
86
-
89
+
87
90
  def initialize(server)
88
91
  @server = server
92
+ @handle_static_files = Server.handle_static_files
89
93
  end
90
94
 
91
95
  def process(req, res)
@@ -95,30 +99,45 @@ class MongrelAdapter < ::Mongrel::HttpHandler
95
99
  # Handle a static file. Also handles cached pages.
96
100
 
97
101
  def handle_file(req, res)
98
- begin
99
- rewrite(req)
100
- # TODO handle If-Modified-Since and add Last-Modified headers
101
- filename = [@server.public_root, req.path_info].join("/").gsub(%r[//], '/')
102
- File.open(filename, "rb") { |f|
103
- # TODO check whether path circumvents public_root directory?
104
- res.status = 200
105
- res.body << f.read # XXX inefficient for large files, may cause leaks
106
- }
107
- return true
108
- rescue Object => ex
102
+ rewrite(req)
103
+
104
+ # gmosx, FIXME: this is a nasty hack that fixes a really
105
+ # *nasty* caching bug. Find a better solution. When hitting
106
+ # the backend server, if the index method takes parameters
107
+ # the dispatcher considers all static files as parameters.
108
+ # If you have output caching enabled for the index page,
109
+ # all your static files get corrupted.
110
+
111
+ if (@handle_static_files == false) and (req.path_info =~ /\.html$/)
109
112
  return false
110
- ensure
111
- unrewrite(req)
112
113
  end
114
+
115
+ # TODO: handle If-Modified-Since and add Last-Modified headers
116
+
117
+ filename = File.join(@server.public_root, req.path_info).squeeze('/')
118
+
119
+ File.open(filename, "rb") do |f|
120
+ # TODO: check whether path circumvents public_root directory?
121
+ res.status = 200
122
+ res.body << f.read # XXX inefficient for large files, may cause leaks
123
+ end
124
+ return true
125
+ rescue Errno::ENOENT => ex # TODO: Lookup Win32 error for 'file missing'
126
+ return false
127
+ ensure
128
+ unrewrite(req)
113
129
  end
114
130
 
115
131
  # Handle the request.
116
-
132
+ #--
133
+ # TODO: recode this like the camping mongrel handler.
134
+ #++
135
+
117
136
  def handle(req, res)
118
137
  unless handle_file(req, res)
119
- path = req.path_info
120
-
121
138
  begin
139
+ path = req.path_info
140
+
122
141
  context = Context.new(@server)
123
142
 
124
143
  context.in = if req.body.is_a? String
@@ -134,29 +153,52 @@ class MongrelAdapter < ::Mongrel::HttpHandler
134
153
  end
135
154
  context.headers[h] = v
136
155
  }
156
+
157
+ # hackfix: make it behave like webrick and fcgi
158
+ context.headers['REQUEST_URI'] << "?#{context.headers['QUERY_STRING']}" if context.headers['QUERY_STRING']
159
+ context.headers['QUERY_STRING'] ||= ''
137
160
 
138
161
  Cgi.parse_params(context)
139
162
  Cgi.parse_cookies(context)
140
163
 
141
164
  context.render(path)
165
+ =begin
166
+ res.start(context.status,true) do |head,out|
167
+ out.write(Cgi.response_headers(context))
168
+ out.write(context.out)
169
+ end
170
+ =end
171
+
172
+ # what is the error code if a request without a handler
173
+ # is comming?! al 2006-Aug-05
142
174
 
143
- res.status = context.status
144
-
145
- res.header.out << Cgi.response_headers(context)
146
- res.body << context.out
147
-
175
+ res.start(context.status, true) do |head,out|
176
+ context.response_headers.each do |key, value|
177
+ head[key] = value
178
+ end
179
+
180
+ context.response_cookies.each do |cookie|
181
+ head['Set-Cookie'] = cookie
182
+ end if context.response_cookies
183
+
184
+ out.write(context.out)
185
+ end
186
+
148
187
  context.close
149
188
  ensure
189
+ $autoreload_dirty = false
150
190
  Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager) and Og.manager
151
191
  end
152
192
  end
153
193
  end
154
194
 
195
+ # Try to rewrite the path to a filename.
196
+
155
197
  def rewrite(req)
156
198
  if req.path_info == '/' || req.path_info == ''
157
199
  req.path_info = '/index.html'
158
200
  elsif req.path_info =~ /^([^.]+)$/
159
- req.path_info = "#{$1}/index.html"
201
+ req.path_info = "#{$1}.html"
160
202
  end
161
203
  end
162
204
 
@@ -165,13 +207,10 @@ class MongrelAdapter < ::Mongrel::HttpHandler
165
207
  def unrewrite(req)
166
208
  if req.path_info == '/index.html'
167
209
  req.path_info = '/'
168
- elsif req.path_info =~ /^([^.]+)\/index.html$/
210
+ elsif req.path_info =~ /^([^.]+)\.html$/
169
211
  req.path_info = $1
170
212
  end
171
213
  end
172
214
  end
173
215
 
174
216
  end
175
-
176
- # * Joshua Hoke
177
- # * George Moschovitis <gm@navel.gr>