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.
- data/bin/nitro +135 -37
- data/doc/CHANGELOG.1 +108 -108
- data/doc/CHANGELOG.2 +89 -89
- data/doc/CHANGELOG.3 +105 -105
- data/{CHANGELOG → doc/CHANGELOG.4} +509 -509
- data/doc/{AUTHORS → CONTRIBUTORS} +49 -37
- data/doc/LIBRARIES +13 -0
- data/doc/LICENSE +2 -3
- data/doc/MIGRATION +45 -0
- data/doc/RELEASES +131 -11
- data/doc/TODO +67 -0
- data/lib/glue/magick.rb +0 -3
- data/lib/glue/sweeper.rb +30 -15
- data/lib/glue/thumbnails.rb +0 -2
- data/lib/glue/webfile.rb +23 -11
- data/lib/nitro.rb +37 -44
- data/lib/nitro/adapter/cgi.rb +0 -3
- data/lib/nitro/adapter/console.rb +0 -2
- data/lib/nitro/adapter/fastcgi.rb +6 -3
- data/lib/nitro/adapter/mongrel.rb +97 -58
- data/lib/nitro/adapter/script.rb +4 -6
- data/lib/nitro/adapter/webrick.rb +33 -87
- data/lib/nitro/adapter/webrick/vcr.rb +85 -0
- data/lib/nitro/caching.rb +0 -2
- data/lib/nitro/caching/actions.rb +0 -2
- data/lib/nitro/caching/fragments.rb +0 -2
- data/lib/nitro/caching/output.rb +45 -16
- data/lib/nitro/caching/proxy.rb +49 -0
- data/lib/nitro/cgi.rb +3 -6
- data/lib/nitro/cgi/cookie.rb +0 -3
- data/lib/nitro/cgi/request.rb +67 -24
- data/lib/nitro/cgi/response.rb +0 -2
- data/lib/nitro/cgi/{sendfile.rb → send_file.rb} +7 -6
- data/lib/nitro/compiler.rb +62 -55
- data/lib/nitro/compiler/cleanup.rb +0 -3
- data/lib/nitro/compiler/elements.rb +31 -28
- data/lib/nitro/compiler/errors.rb +2 -5
- data/lib/nitro/compiler/include.rb +10 -8
- data/lib/nitro/compiler/layout.rb +0 -2
- data/lib/nitro/compiler/localization.rb +0 -2
- data/lib/nitro/compiler/markup.rb +14 -6
- data/lib/nitro/compiler/morphing.rb +1 -5
- data/lib/nitro/compiler/script.rb +2 -4
- data/lib/nitro/compiler/squeeze.rb +0 -2
- data/lib/nitro/compiler/xslt.rb +0 -2
- data/lib/nitro/context.rb +10 -5
- data/lib/nitro/control.rb +18 -0
- data/lib/nitro/control/attribute.rb +88 -0
- data/lib/nitro/control/attribute/checkbox.rb +19 -0
- data/lib/nitro/control/attribute/datetime.rb +21 -0
- data/lib/nitro/control/attribute/file.rb +20 -0
- data/lib/nitro/control/attribute/fixnum.rb +26 -0
- data/lib/nitro/control/attribute/float.rb +26 -0
- data/lib/nitro/control/attribute/options.rb +38 -0
- data/lib/nitro/control/attribute/password.rb +16 -0
- data/lib/nitro/control/attribute/text.rb +16 -0
- data/lib/nitro/control/attribute/textarea.rb +16 -0
- data/lib/nitro/control/none.rb +16 -0
- data/lib/nitro/control/relation.rb +53 -0
- data/lib/nitro/control/relation/belongs_to.rb +0 -0
- data/lib/nitro/control/relation/has_many.rb +97 -0
- data/lib/nitro/control/relation/joins_many.rb +0 -0
- data/lib/nitro/control/relation/many_to_many.rb +0 -0
- data/lib/nitro/control/relation/refers_to.rb +29 -0
- data/lib/nitro/controller.rb +7 -296
- data/lib/nitro/dispatcher.rb +72 -34
- data/lib/nitro/element.rb +36 -10
- data/lib/nitro/element/javascript.rb +0 -2
- data/lib/nitro/flash.rb +23 -10
- data/lib/nitro/global.rb +36 -11
- data/lib/nitro/helper.rb +22 -8
- data/lib/nitro/helper/benchmark.rb +0 -2
- data/lib/nitro/helper/buffer.rb +0 -3
- data/lib/nitro/helper/css.rb +12 -0
- data/lib/nitro/helper/debug.rb +1 -3
- data/lib/nitro/helper/default.rb +1 -0
- data/lib/nitro/helper/feed.rb +400 -386
- data/lib/nitro/helper/form.rb +246 -116
- data/lib/nitro/helper/javascript.rb +28 -2
- data/lib/nitro/helper/javascript/morphing.rb +0 -2
- data/lib/nitro/helper/javascript/prototype.rb +0 -2
- data/lib/nitro/helper/javascript/scriptaculous.rb +0 -1
- data/lib/nitro/helper/layout.rb +0 -2
- data/lib/nitro/helper/navigation.rb +87 -0
- data/lib/nitro/helper/pager.rb +11 -22
- data/lib/nitro/helper/table.rb +9 -32
- data/lib/nitro/helper/url.rb +104 -0
- data/lib/nitro/helper/xhtml.rb +20 -4
- data/lib/nitro/helper/xml.rb +0 -2
- data/lib/nitro/markup.rb +131 -0
- data/lib/nitro/part.rb +52 -7
- data/lib/nitro/publishable.rb +328 -0
- data/lib/nitro/render.rb +30 -61
- data/lib/nitro/router.rb +12 -4
- data/lib/nitro/sanitize.rb +48 -0
- data/lib/nitro/scaffold.rb +9 -11
- data/lib/nitro/scaffold/controller.rb +25 -0
- data/lib/nitro/scaffold/model.rb +150 -0
- data/lib/nitro/scaffolding.rb +1 -3
- data/lib/nitro/server.rb +57 -32
- data/lib/nitro/server/drb.rb +16 -2
- data/lib/nitro/server/runner.rb +80 -102
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/service/xmlrpc.rb +0 -2
- data/lib/nitro/session.rb +26 -18
- data/lib/nitro/session/drb.rb +2 -16
- data/lib/nitro/session/memory.rb +0 -2
- data/lib/nitro/template.rb +219 -0
- data/lib/nitro/test/assertions.rb +1 -3
- data/lib/nitro/test/context.rb +0 -1
- data/lib/nitro/test/testcase.rb +0 -1
- data/lib/nitro/version.rb +6 -0
- data/lib/part/admin.rb +16 -0
- data/lib/part/admin/controller.rb +19 -0
- data/lib/part/admin/helper.rb +30 -0
- data/lib/part/admin/og/controller.rb +114 -0
- data/lib/part/admin/og/customize.rb +4 -0
- data/lib/part/admin/og/template/index.xhtml +27 -0
- data/lib/part/admin/og/template/list.xhtml +38 -0
- data/lib/part/admin/og/template/search.xhtml +20 -0
- data/lib/part/admin/og/template/update.xhtml +25 -0
- data/lib/part/admin/skin.rb +207 -0
- data/lib/part/admin/template/denied.xhtml +13 -0
- data/lib/part/admin/template/index.xhtml +12 -0
- data/lib/part/admin/todo.txt +2 -0
- data/proto/public/error.xhtml +4 -2
- data/proto/run.rb +0 -2
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/cgi/tc_request.rb +23 -0
- data/test/nitro/helper/tc_feed.rb +0 -3
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_table.rb +2 -0
- data/test/nitro/tc_cgi.rb +72 -19
- data/test/nitro/tc_controller.rb +35 -26
- data/test/nitro/tc_controller_aspect.rb +1 -0
- data/test/nitro/tc_controller_params.rb +864 -0
- data/test/nitro/tc_dispatcher.rb +2 -2
- data/test/nitro/tc_element.rb +16 -16
- data/test/nitro/tc_flash.rb +3 -3
- data/test/nitro/tc_markup.rb +31 -0
- data/test/nitro/tc_render.rb +12 -14
- data/test/nitro/tc_session.rb +9 -7
- data/test/nitro/tc_template.rb +34 -0
- metadata +217 -198
- data/INSTALL +0 -121
- data/ProjectInfo +0 -74
- data/README +0 -555
- data/doc/apache.txt +0 -9
- data/doc/config.txt +0 -28
- data/doc/faq.txt +0 -7
- data/doc/lhttpd.txt +0 -7
- data/lib/nitro/adapter/scgi.rb +0 -239
- data/lib/nitro/helper/form/builder.rb +0 -144
- data/lib/nitro/helper/form/controls.rb +0 -389
- data/lib/nitro/helper/rss.rb +0 -72
- data/proto/conf/apache.conf +0 -51
- data/proto/public/scaffold/advanced_search.xhtml +0 -30
- data/proto/public/scaffold/edit.xhtml +0 -11
- data/proto/public/scaffold/form.xhtml +0 -1
- data/proto/public/scaffold/index.xhtml +0 -20
- data/proto/public/scaffold/list.xhtml +0 -32
- data/proto/public/scaffold/new.xhtml +0 -11
- data/proto/public/scaffold/search.xhtml +0 -29
- data/proto/public/scaffold/view.xhtml +0 -8
- data/proto/script/scgi_ctl +0 -221
- data/proto/script/scgi_service +0 -128
- data/setup.rb +0 -1585
- data/src/part/admin.rb +0 -16
- data/src/part/admin/controller.rb +0 -81
- data/src/part/admin/skin.rb +0 -21
- data/src/part/admin/system.css +0 -135
- data/src/part/admin/template/denied.xhtml +0 -1
- data/src/part/admin/template/index.xhtml +0 -43
- data/test/nitro/helper/tc_rss.rb +0 -24
data/lib/glue/magick.rb
CHANGED
data/lib/glue/sweeper.rb
CHANGED
|
@@ -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
|
-
|
|
32
|
-
filename = "#{Server.public_root}/#{
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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>
|
data/lib/glue/thumbnails.rb
CHANGED
data/lib/glue/webfile.rb
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
64
|
+
attr_accessor "#{name}_size".to_sym, Fixnum
|
|
53
65
|
|
|
54
|
-
# The mime type
|
|
66
|
+
# The mime type.
|
|
55
67
|
|
|
56
|
-
|
|
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
|
-
|
|
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(
|
|
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>
|
data/lib/nitro.rb
CHANGED
|
@@ -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
|
|
8
|
-
# and released under the
|
|
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
|
-
|
|
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
|
-
#
|
|
30
|
-
|
|
31
|
-
$LOAD_PATH.unshift File.join(LibPath, '..', 'src')
|
|
25
|
+
# The adapter used to serve nitro applications.
|
|
32
26
|
|
|
33
|
-
|
|
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
|
|
81
|
+
# A helper method. Will be deprecated, use
|
|
82
|
+
# Configuration.mode instead.
|
|
83
83
|
|
|
84
|
-
def
|
|
85
|
-
|
|
84
|
+
def live?
|
|
85
|
+
Configuration.mode == :live
|
|
86
86
|
end
|
|
87
|
-
alias_method :
|
|
88
|
-
|
|
87
|
+
alias_method :production?, :live?
|
|
89
88
|
|
|
90
|
-
#
|
|
89
|
+
# Deprecated, use Configuration.mode instead.
|
|
91
90
|
|
|
92
|
-
def
|
|
93
|
-
|
|
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>
|
data/lib/nitro/adapter/cgi.rb
CHANGED
|
@@ -22,10 +22,15 @@ module Nitro
|
|
|
22
22
|
#
|
|
23
23
|
# === Sessions
|
|
24
24
|
#
|
|
25
|
-
# As FCGI is process based, you have
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
69
|
-
@
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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}
|
|
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 =~ /^([^.]+)
|
|
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>
|