nitro 0.31.0 → 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
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>