nitro 0.29.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG +410 -0
  2. data/ProjectInfo +36 -44
  3. data/README +5 -5
  4. data/doc/AUTHORS +6 -0
  5. data/doc/RELEASES +159 -2
  6. data/lib/glue/sweeper.rb +2 -2
  7. data/lib/glue/webfile.rb +14 -1
  8. data/lib/nitro.rb +6 -9
  9. data/lib/nitro/adapter/mongrel.rb +36 -43
  10. data/lib/nitro/adapter/scgi.rb +1 -1
  11. data/lib/nitro/adapter/webrick.rb +96 -24
  12. data/lib/nitro/caching/actions.rb +2 -1
  13. data/lib/nitro/caching/fragments.rb +1 -8
  14. data/lib/nitro/caching/output.rb +14 -4
  15. data/lib/nitro/cgi.rb +19 -21
  16. data/lib/nitro/cgi/cookie.rb +5 -1
  17. data/lib/nitro/cgi/request.rb +20 -4
  18. data/lib/nitro/compiler.rb +74 -28
  19. data/lib/nitro/compiler/cleanup.rb +1 -1
  20. data/lib/nitro/compiler/elements.rb +1 -2
  21. data/lib/nitro/compiler/localization.rb +1 -1
  22. data/lib/nitro/compiler/markup.rb +1 -1
  23. data/lib/nitro/compiler/script.rb +52 -44
  24. data/lib/nitro/compiler/squeeze.rb +4 -3
  25. data/lib/nitro/compiler/xslt.rb +7 -6
  26. data/lib/nitro/context.rb +39 -20
  27. data/lib/nitro/controller.rb +24 -5
  28. data/lib/nitro/dispatcher.rb +13 -5
  29. data/lib/nitro/global.rb +63 -0
  30. data/lib/nitro/helper/feed.rb +432 -0
  31. data/lib/nitro/helper/form.rb +11 -3
  32. data/lib/nitro/helper/form/builder.rb +140 -0
  33. data/lib/nitro/helper/form/controls.rb +2 -1
  34. data/lib/nitro/helper/javascript.rb +6 -0
  35. data/lib/nitro/helper/javascript/morphing.rb +13 -6
  36. data/lib/nitro/helper/xhtml.rb +42 -6
  37. data/lib/nitro/helper/xml.rb +3 -0
  38. data/lib/nitro/part.rb +2 -2
  39. data/lib/nitro/render.rb +7 -2
  40. data/lib/nitro/router.rb +57 -16
  41. data/lib/nitro/scaffolding.rb +29 -20
  42. data/lib/nitro/server.rb +4 -10
  43. data/lib/nitro/server/drb.rb +1 -1
  44. data/lib/nitro/server/runner.rb +10 -0
  45. data/lib/nitro/session.rb +31 -12
  46. data/lib/nitro/session/drb.rb +13 -1
  47. data/lib/nitro/session/file.rb +1 -1
  48. data/lib/nitro/session/memcached.rb +1 -1
  49. data/lib/nitro/session/memory.rb +1 -1
  50. data/lib/nitro/session/og.rb +1 -1
  51. data/lib/nitro/test/testcase.rb +3 -0
  52. data/proto/public/error.xhtml +5 -5
  53. data/proto/public/js/controls.js +2 -2
  54. data/proto/public/js/dragdrop.js +320 -79
  55. data/proto/public/js/effects.js +200 -152
  56. data/proto/public/js/prototype.js +284 -63
  57. data/proto/public/js/scriptaculous.js +7 -5
  58. data/proto/public/js/unittest.js +11 -0
  59. data/proto/public/scaffold/advanced_search.xhtml +30 -0
  60. data/proto/public/scaffold/list.xhtml +8 -1
  61. data/proto/public/scaffold/search.xhtml +2 -1
  62. data/proto/script/scgi_service +1 -1
  63. data/src/part/admin/controller.rb +1 -1
  64. data/src/part/admin/skin.rb +1 -1
  65. data/test/nitro/CONFIG.rb +3 -0
  66. data/test/nitro/adapter/tc_webrick.rb +1 -1
  67. data/test/nitro/cgi/tc_cookie.rb +1 -1
  68. data/test/nitro/cgi/tc_request.rb +5 -5
  69. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  70. data/test/nitro/compiler/tc_compiler.rb +2 -0
  71. data/test/nitro/helper/tc_feed.rb +138 -0
  72. data/test/nitro/helper/tc_pager.rb +1 -1
  73. data/test/nitro/helper/tc_rss.rb +1 -1
  74. data/test/nitro/helper/tc_table.rb +1 -1
  75. data/test/nitro/helper/tc_xhtml.rb +1 -1
  76. data/test/nitro/tc_caching.rb +1 -1
  77. data/test/nitro/tc_cgi.rb +1 -1
  78. data/test/nitro/tc_context.rb +1 -1
  79. data/test/nitro/tc_controller.rb +31 -3
  80. data/test/nitro/tc_controller_aspect.rb +1 -1
  81. data/test/nitro/tc_dispatcher.rb +1 -1
  82. data/test/nitro/tc_element.rb +1 -1
  83. data/test/nitro/tc_flash.rb +1 -1
  84. data/test/nitro/tc_helper.rb +1 -1
  85. data/test/nitro/tc_render.rb +6 -6
  86. data/test/nitro/tc_router.rb +8 -4
  87. data/test/nitro/tc_server.rb +1 -3
  88. data/test/nitro/tc_session.rb +1 -3
  89. metadata +107 -104
  90. data/Rakefile +0 -232
  91. data/lib/nitro/adapter/acgi.rb +0 -237
  92. data/proto/public/Makefile.acgi +0 -40
  93. data/proto/public/acgi.c +0 -138
data/README CHANGED
@@ -1,4 +1,4 @@
1
- = Nitro 0.29.0 README
1
+ = Nitro 0.30.0 README
2
2
 
3
3
  Nitro provides everything you need to develop professional Web
4
4
  applications using Ruby and Javascript.
@@ -325,14 +325,14 @@ doc/RELEASES
325
325
 
326
326
  The latest version of Nitro can be found at
327
327
 
328
- * http://www.nitrohq.com
328
+ * http://www.nitroproject.org
329
329
 
330
330
 
331
331
  == Documentation
332
332
 
333
333
  Documentation for Nitro can be found at
334
334
 
335
- * http://www.nitrohq.com
335
+ * http://www.nitroproject.org
336
336
 
337
337
  Don't forget to read the file doc/RELEASES for usefull
338
338
  documentation bits. Also, have a look at the test cases in
@@ -344,7 +344,7 @@ the test directory for examples of usage.
344
344
  A number of videos that demonstrate Nitro in practical usage
345
345
  are available here:
346
346
 
347
- http://www.nitrohq.com/view/Videos
347
+ http://www.nitroproject.org/view/Videos
348
348
 
349
349
 
350
350
  == Requirements
@@ -549,7 +549,7 @@ http://rubyforge.org/mailman/listinfo/nitro-general
549
549
  Copyright (c) 2004-2006, George 'gmosx' Moschovitis (http://www.gmosx.com)
550
550
  Copyright (c) 2004-2006, Navel Ltd (http://www.navel.gr)
551
551
 
552
- Nitro (http://www.nitrohq.com) is copyrighted free software
552
+ Nitro (http://www.nitroproject.org) is copyrighted free software
553
553
  created and maintained by George Moschovitis (mailto:gm@navel.gr)
554
554
  and released under the standard BSD Licence. For details consult
555
555
  the file LICENCE.
@@ -50,6 +50,12 @@ IDEAS, ADDITIONAL CODING, SUPPORT:
50
50
  * TRANS <transfire@gmail.com>
51
51
  Small bug fixes, patches.
52
52
 
53
+ * Kashia Buch <kashia@vfemail.net>
54
+ Patches, documentation.
55
+
56
+ * Massimo Maria Ghisalberti
57
+ Patches.
58
+
53
59
  * Dan Yoder <dan@zeraweb.com>
54
60
  Original 'Elements' implementation, bug reports.
55
61
 
@@ -1,3 +1,160 @@
1
+ == Version 0.30.0
2
+
3
+ Another pragmatic release. The Nitro development team worked over
4
+ the submitted tickets and provided many bug fixes. More over, there
5
+ are many small improvements along the codebase and as always
6
+ we could not resist adding some cool new features.
7
+
8
+ Special thanks fly to Bryan Sotto for making this release
9
+ possible!
10
+
11
+ Most notable chages:
12
+
13
+ * Nitro allows fine grained customization of the compiler
14
+ tranformation pipeline per controller or even per action.
15
+ Here come some examples:
16
+
17
+ class MyController
18
+ ann :self, :transformation_pipeline => [MyTransformer, AnotherXForm]
19
+
20
+ ...
21
+
22
+ def my_action
23
+ ...
24
+ end
25
+ ann :my_action, :transformation_pipeline => Compiler.transformation_pipeline.dup.shift(CustomXForm)
26
+
27
+ ...
28
+ end
29
+
30
+ * Nitro automates integration testing by means of the new
31
+ session VCR feature that allows for easy proxy based
32
+ functional testing. A typicall session goes like this:
33
+
34
+ Start your app with:
35
+
36
+ ruby run.rb --record myfile
37
+
38
+ Then use your web browser to 'perform' your testing session.
39
+ You can used multiple browsers, concurrent users and hit all
40
+ the pages in your app. At the end, just stop the server.
41
+
42
+ In order to perform regression testing against this recorded
43
+ session just restart the server in playback mode:
44
+
45
+ ruby run.rb --playback myfile
46
+
47
+ Nitro automatically plays back the recorded session and logs
48
+ any errors or Exceptions.
49
+
50
+ * Better Global variable implementation works better with
51
+ distributed stores (Drb, Memcached). Notice the new
52
+ Global.init and Global[:key].update { |v| } methods.
53
+
54
+ * Improved the Router implementation. One notable addition
55
+ is support for global router initialization:
56
+
57
+ Router.rules = [
58
+ { :match => /~(.*)/, :controller => IdController, :action => :view, :params => [:name] }
59
+ ]
60
+
61
+ * Cleaned up glue by removing files duplicating functionality
62
+ allready available in Facets. Moreover, we moved several
63
+ generally useful files and methods from Glue to Facets.
64
+
65
+ * Replaced the old RSSHelper with the new FeedHelper. The new
66
+ implementation provides support for RSS, Atom, OPML. The
67
+ FeedHelper is backwards compatible with the old helper but
68
+ provides even more features.
69
+
70
+ class MyController
71
+ helper :feed
72
+ end
73
+
74
+ * Added Og query by example support. Query the database for an
75
+ entity that matches the example. The example is a hash
76
+ populated with the property values to search for.
77
+
78
+ The provided property values are joined with AND to build
79
+ the actual query.
80
+
81
+ Article.query_by_example :title => 'IBM%', :hits => 2
82
+ Article.find_with_properties :title => 'IBM%', :hits => 2
83
+
84
+ * Added type casting support for Og aggregations and
85
+ calculations.
86
+
87
+ * Greatly improved the configuration system. One noteable
88
+ (and extremely useful) new feature is that you can now
89
+ customize classes before they are even defined:
90
+
91
+
92
+ Configuration.User.crypt_salt = 'HELLO'
93
+ require 'users'
94
+
95
+ in users.rb:
96
+
97
+ class User
98
+ setting :crypt_salt, :default => 'DF', :doc => 'The crypt salt'
99
+ end
100
+
101
+ * Calculate rendering level in actions to allow for conditional
102
+ rendering in top level actions or sub-actions. Some helpers
103
+ are also provided:
104
+
105
+ def myaction
106
+ if request.is_top_level?
107
+ ...
108
+ end
109
+ end
110
+
111
+ * Introduced an alternative more sophisticated (yet intuitive)
112
+ form builder. While this new helper is still under construction,
113
+ it is already very useful. Here come some examples:
114
+
115
+ <!-- entity backed form -->
116
+
117
+ <div id="myform">
118
+ #{form :object => @owner, :action => :save_profile do |f|
119
+ f.property :name, :editable => false
120
+ f.property :password
121
+ f.br
122
+ f.submit 'Update'
123
+ end}
124
+ </div>
125
+
126
+ <!-- form with virtual method (:multipart),
127
+ special controls (:select_file) -->
128
+
129
+ <div id="myform">
130
+ #{form :method => :multipart do |f|
131
+ f.p {
132
+ f.label 'Select the new icon filename'
133
+ f.select_file :file, :label => 'Select icon'
134
+ }
135
+ f.p {
136
+ f.submit 'Change'
137
+ }
138
+ end}
139
+ </div>
140
+
141
+ * More flexible Script generator, the developer can use most of
142
+ its features without a Client subclass.
143
+
144
+ * Reimplemented session garbage collection.
145
+
146
+ * Added many more RDoc comments to the source code.
147
+
148
+ * Many, many bug fixes.
149
+
150
+ * Updated to latest Facets, Scriptaculous, Prototype.
151
+
152
+
153
+ Please note that the project home page has been moved to:
154
+
155
+ http://www.nitroproject.org
156
+
157
+
1
158
  == Version 0.29.0
2
159
 
3
160
  A bold step towards maturity. Great care was taken to
@@ -1098,7 +1255,7 @@ Another superb release! State of the art AJAX/Javascript support,
1098
1255
  Wee components / programmatic renderer integration, a beginners
1099
1256
  tutorial, self documenting configuration and many important bug
1100
1257
  fixes. Don't forget to check out our new community site at
1101
- http://www.nitrohq.com
1258
+ http://www.nitroproject.org
1102
1259
 
1103
1260
  Some notable changes:
1104
1261
 
@@ -1297,7 +1454,7 @@ Some notable changes:
1297
1454
 
1298
1455
  * This is surely the most request feature: Nitro Step by Step
1299
1456
  by James Britt, a beginers guide to Nitro. Available in the
1300
- brand-new, Nitro-powered, www.nitrohq.com Community wiki.
1457
+ brand-new, Nitro-powered, www.nitroproject.org Community wiki.
1301
1458
 
1302
1459
  * New examples: The totaly recoded and ultra cool ajax example,
1303
1460
  a Wee/Nitro example and the new Hello world example.
@@ -1,4 +1,4 @@
1
- require 'glue/aspects'
1
+ require 'facets/more/aspects'
2
2
 
3
3
  module Glue
4
4
 
@@ -12,7 +12,7 @@ module Glue
12
12
  #++
13
13
 
14
14
  module Sweeper
15
- include Glue::Aspects
15
+ include ::Aspects
16
16
 
17
17
  before "sweep_affected(:insert)", :on => :og_insert
18
18
  before "sweep_affected(:update)", :on => :og_update
@@ -5,6 +5,20 @@ require 'facet/inheritor'
5
5
  module Glue
6
6
 
7
7
  # A Web File.
8
+ #
9
+ # You can customize the path where the uploaded file will be
10
+ # by defining a webfile_path class method *before* the property:
11
+ #
12
+ # class Icon
13
+ # def self.webfile_path request, name
14
+ # File.join(Uploads.public_root, request.user.name, 'icon.png')
15
+ # end
16
+ #
17
+ # property :file, WebFile, :magick => { :small => '64x64', :medium => '96x96' }
18
+ # end
19
+ #--
20
+ # TODO: webfile_path customization sucks, should be improved!
21
+ #++
8
22
 
9
23
  class WebFile
10
24
 
@@ -65,7 +79,6 @@ class WebFile
65
79
  def #{name}_from_request(request)
66
80
  param = request['#{name}']
67
81
  }
68
-
69
82
  if base.respond_to? :webfile_path
70
83
  code << %{
71
84
  path = #{base}.webfile_path(request, '#{name}')
@@ -1,9 +1,9 @@
1
1
  # = Nitro
2
2
  #
3
- # Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
4
- # Copyright (c) 2004-2005, George Moschovitis (http://www.gmosx.com)
3
+ # Copyright (c) 2004-2006, George Moschovitis (http://www.gmosx.com)
4
+ # Copyright (c) 2004-2006, Navel Ltd (http://www.navel.gr)
5
5
  #
6
- # Nitro (http://www.nitrohq.com) is copyrighted free software
6
+ # Nitro (http://www.nitroproject.org) is copyrighted free software
7
7
  # created and maintained by George Moschovitis (mailto:gm@navel.gr)
8
8
  # and released under the standard BSD Licence. For details
9
9
  # consult the file doc/LICENCE.
@@ -16,7 +16,7 @@ module Nitro
16
16
 
17
17
  # The version.
18
18
 
19
- Version = '0.29.0'
19
+ Version = '0.30.0'
20
20
 
21
21
  # Library path.
22
22
 
@@ -39,6 +39,7 @@ end
39
39
  # gmosx: leave them here.
40
40
  #++
41
41
 
42
+ require 'nitro/global'
42
43
  require 'nitro/context'
43
44
  require 'nitro/controller'
44
45
  require 'nitro/dispatcher'
@@ -95,11 +96,7 @@ module Nitro
95
96
 
96
97
  end
97
98
 
98
- # Cache for application scoped (global) variables. This is a
99
- # temporal store, will be moved to the actuall cache in
100
- # Server.start
101
-
102
- $global = $application = {}
99
+ $global = $application = Global
103
100
 
104
101
  end
105
102
 
@@ -138,59 +138,53 @@ class MongrelAdapter < ::Mongrel::HttpHandler
138
138
  unless handle_file(req, res)
139
139
  path = req.path_info
140
140
 
141
- unless path =~ /\./
142
- begin
143
- context = Context.new(@server)
141
+ begin
142
+ context = Context.new(@server)
144
143
 
145
- context.in = StringIO.new(req.body || "")
144
+ context.in = StringIO.new(req.body || "")
146
145
 
147
- context.headers = {}
148
- req.params.each { |h, v|
149
- if h =~ /\AHTTP_(.*)\Z/
146
+ context.headers = {}
147
+ req.params.each { |h, v|
148
+ if h =~ /\AHTTP_(.*)\Z/
150
149
  context.headers[$1.gsub("_", "-")] = v
151
150
  end
152
151
  context.headers[h] = v
153
- }
154
- # context.headers.update(req.meta_vars)
152
+ }
153
+ # context.headers.update(req.meta_vars)
155
154
 
156
- context.headers['REQUEST_URI'] = context.headers['SCRIPT_NAME']
155
+ context.headers['REQUEST_URI'] = context.headers['SCRIPT_NAME']
157
156
 
158
- if context.headers['PATH_INFO'].blank?
159
- context.headers['REQUEST_URI'] = '/'
160
- else
161
- context.headers['REQUEST_URI'] = '/' + context.headers['PATH_INFO']
162
- end
157
+ if context.headers['PATH_INFO'].blank?
158
+ context.headers['REQUEST_URI'] = '/'
159
+ else
160
+ context.headers['REQUEST_URI'] = '/' + context.headers['PATH_INFO']
161
+ end
163
162
 
164
- # gmosx: make compatible with fastcgi.
165
- #context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
166
- # context.headers['REQUEST_URI'] << '/'
163
+ # gmosx: make compatible with fastcgi.
167
164
 
168
- Cgi.parse_params(context)
169
- Cgi.parse_cookies(context)
165
+ context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
166
+ context.headers['REQUEST_URI'] = '/' + context.headers['REQUEST_URI']
170
167
 
171
- context.render(path)
172
-
173
- res.socket << "HTTP/1.1 #{context.status.to_s} "
174
-
175
- if STATUS_CODES.has_key? context.status
176
- res.socket << STATUS_CODES[context.status]
177
- else
178
- res.socket << "Unknown Status Code"
179
- end
180
- res.socket << "\r\n"
181
-
182
- headers = context.response_headers
183
- headers["Content-length"] = context.out.size
184
- headers.each { |h,v| res.socket << "#{h}: #{v}\r\n" }
185
- res.socket << "\r\n"
186
-
187
- # TODO handle setting cookies
188
- res.socket << context.out
189
-
190
- context.close
191
- ensure
192
- Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
168
+ Cgi.parse_params(context)
169
+ Cgi.parse_cookies(context)
170
+
171
+ context.render(path)
172
+
173
+ res.socket << "HTTP/1.1 #{context.status.to_s} "
174
+
175
+ if STATUS_CODES.has_key? context.status
176
+ res.socket << STATUS_CODES[context.status]
177
+ else
178
+ res.socket << "Unknown Status Code"
193
179
  end
180
+ res.socket << "\r\n"
181
+
182
+ res.socket << Cgi.response_headers(context)
183
+ res.socket << context.out
184
+
185
+ context.close
186
+ ensure
187
+ Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager) and Og.manager
194
188
  end
195
189
  end
196
190
  end
@@ -218,4 +212,3 @@ end
218
212
 
219
213
  # * Joshua Hoke
220
214
  # * George Moschovitis <gm@navel.gr>
221
-
@@ -168,7 +168,7 @@ module SCGI # :nodoc: all
168
168
  Nitro::Cgi.process(@server, cgi, cgi.stdinput, cgi.stdoutput)
169
169
  #end
170
170
  ensure
171
- Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
171
+ Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager) and Og.manager
172
172
  end
173
173
  end
174
174
 
@@ -32,6 +32,7 @@ class Webrick
32
32
  end
33
33
 
34
34
  webrick_options = server.options.dup
35
+
35
36
  require 'webrick/https' if webrick_options[:SSLEnable]
36
37
 
37
38
  webrick_options.update(
@@ -43,6 +44,10 @@ class Webrick
43
44
  [wblog, WEBrick::AccessLog::REFERER_LOG_FORMAT]
44
45
  ]
45
46
  )
47
+
48
+ enable_record_mode($record_session_filename) if $record_session_filename
49
+ enable_playback_mode($playback_session_filename) if $playback_session_filename
50
+
46
51
  @webrick = WEBrick::HTTPServer.new(webrick_options)
47
52
 
48
53
  trap('INT') { stop }
@@ -65,6 +70,75 @@ class Webrick
65
70
 
66
71
  def initialize_webrick(server)
67
72
  end
73
+
74
+ # Enables session recording. The recorded data can be used
75
+ # for automatic app testing by means of the playback mode.
76
+
77
+ def enable_record_mode(filename = 'session.yaml')
78
+ Logger.info "Recording application server session to '#{filename}'."
79
+
80
+ require 'facets/core/file/self/create'
81
+
82
+ $record_session = []
83
+ $last_record_time = Time.now
84
+
85
+ Nitro::WebrickAdapter.class_eval %{
86
+ def do_GET(req, res)
87
+ record_context(req, res)
88
+ handle(req, res)
89
+ end
90
+ alias_method :do_POST, :do_GET
91
+
92
+ def record_context(req, res)
93
+ delta = Time.now - $last_record_time
94
+ $last_record_time = Time.now
95
+ $record_session << [delta, req, res]
96
+ end
97
+ }
98
+
99
+ at_exit do
100
+ File.create(filename, YAML.dump($record_session))
101
+ end
102
+ end
103
+
104
+ # Playback a recorded session. Typically used for testing.
105
+
106
+ def enable_playback_mode(filename = 'session.yaml')
107
+ Logger.info "Playing back application server session from '#{filename}'."
108
+
109
+ $playback_session = YAML.load_file(filename)
110
+ $playback_exception_count = 0
111
+
112
+ WEBrick::HTTPServer.class_eval %{
113
+ def start(&block)
114
+ run(nil)
115
+ end
116
+
117
+ def run(sock)
118
+ while true
119
+ delta, req, res = $playback_session.shift
120
+
121
+ if delta
122
+ sleep(delta)
123
+ begin
124
+ service(req, res)
125
+ rescue Object => ex
126
+ $playback_exception_count += 1
127
+ p '---', ex
128
+ end
129
+ else
130
+ return
131
+ end
132
+ end
133
+ end
134
+ }
135
+
136
+ at_exit do
137
+ puts "\n\n"
138
+ puts "Playback raised #$playback_exception_count exceptions.\n"
139
+ puts "\n"
140
+ end
141
+ end
68
142
 
69
143
  end
70
144
 
@@ -127,39 +201,37 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
127
201
  unless handle_file(req, res)
128
202
  path = req.request_uri.path
129
203
 
130
- unless path =~ /\./
131
- begin
132
- path = req.request_uri.path
204
+ begin
205
+ path = req.request_uri.path
133
206
 
134
- context = Context.new(@server)
207
+ context = Context.new(@server)
135
208
 
136
- context.in = StringIO.new(req.body || "")
209
+ context.in = StringIO.new(req.body || "")
137
210
 
138
- context.headers = {}
139
- req.header.each { |h, v| context.headers[h.upcase] = v.first }
140
- context.headers.update(req.meta_vars)
211
+ context.headers = {}
212
+ req.header.each { |h, v| context.headers[h.upcase] = v.first }
213
+ context.headers.update(req.meta_vars)
141
214
 
142
- # gmosx: make compatible with fastcgi.
215
+ # gmosx: make compatible with fastcgi.
143
216
 
144
- context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
145
- context.headers['REQUEST_URI'] = '/' + context.headers['REQUEST_URI']
217
+ context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
218
+ context.headers['REQUEST_URI'] = '/' + context.headers['REQUEST_URI']
146
219
 
147
- Cgi.parse_params(context)
148
- Cgi.parse_cookies(context)
220
+ Cgi.parse_params(context)
221
+ Cgi.parse_cookies(context)
149
222
 
150
- context.render(path)
223
+ context.render(path)
151
224
 
152
- res.status = context.status
153
- res.instance_variable_set(:@header, context.response_headers || {})
154
- res.instance_variable_set(:@cookies, context.response_cookies || {})
155
- res.body = context.out
156
- res.chunked = true if context.out.is_a?(IO) and context["SERVER_PROTOCOL"] == "HTTP/1.1"
225
+ res.status = context.status
226
+ res.instance_variable_set(:@header, context.response_headers || {})
227
+ res.instance_variable_set(:@cookies, context.response_cookies || {})
228
+ res.body = context.out
229
+ res.chunked = true if context.out.is_a?(IO) and context["SERVER_PROTOCOL"] == "HTTP/1.1"
157
230
 
158
- context.close
159
- ensure
160
- $autoreload_dirty = false
161
- Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
162
- end
231
+ context.close
232
+ ensure
233
+ $autoreload_dirty = false
234
+ Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager) and Og.manager
163
235
  end
164
236
  end
165
237
  end