mongrel 0.3.8 → 0.3.9

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 (97) hide show
  1. data/README +30 -24
  2. data/Rakefile +12 -2
  3. data/bin/mongrel_rails +12 -8
  4. data/doc/rdoc/classes/Mongrel.html +18 -1
  5. data/doc/rdoc/classes/Mongrel/CGIWrapper.html +381 -0
  6. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000051.html +24 -0
  7. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000052.html +47 -0
  8. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000053.html +34 -0
  9. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000054.html +27 -0
  10. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000055.html +25 -0
  11. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000056.html +18 -0
  12. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000057.html +18 -0
  13. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000058.html +18 -0
  14. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000059.html +19 -0
  15. data/doc/rdoc/classes/Mongrel/Command.html +119 -0
  16. data/doc/rdoc/classes/Mongrel/Command/Base.html +332 -0
  17. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000003.html +24 -0
  18. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000004.html +41 -0
  19. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000005.html +18 -0
  20. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000006.html +18 -0
  21. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000007.html +18 -0
  22. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000008.html +22 -0
  23. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000009.html +18 -0
  24. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000010.html +18 -0
  25. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000011.html +18 -0
  26. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000012.html +18 -0
  27. data/doc/rdoc/classes/Mongrel/Command/Registry.html +192 -0
  28. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000013.html +20 -0
  29. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000014.html +25 -0
  30. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000015.html +46 -0
  31. data/doc/rdoc/classes/Mongrel/Const.html +2 -2
  32. data/doc/rdoc/classes/Mongrel/DirHandler.html +283 -0
  33. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000023.html +20 -0
  34. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000024.html +42 -0
  35. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000025.html +40 -0
  36. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000026.html +31 -0
  37. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000027.html +38 -0
  38. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000028.html +18 -0
  39. data/doc/rdoc/classes/Mongrel/Error404Handler.html +171 -0
  40. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000060.html +18 -0
  41. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000061.html +18 -0
  42. data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
  43. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000014.html → M000035.html} +0 -0
  44. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000015.html → M000036.html} +0 -0
  45. data/doc/rdoc/classes/Mongrel/HttpHandler.html +146 -0
  46. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000037.html +17 -0
  47. data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
  48. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000001.html → M000016.html} +0 -0
  49. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000002.html → M000017.html} +0 -0
  50. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000003.html → M000018.html} +0 -0
  51. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000004.html → M000019.html} +0 -0
  52. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000005.html → M000020.html} +0 -0
  53. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000006.html → M000021.html} +0 -0
  54. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000007.html → M000022.html} +0 -0
  55. data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
  56. data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000029.html → M000062.html} +0 -0
  57. data/doc/rdoc/classes/Mongrel/HttpResponse.html +36 -36
  58. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000016.html → M000038.html} +0 -0
  59. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000017.html → M000039.html} +0 -0
  60. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000018.html → M000040.html} +0 -0
  61. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000019.html → M000041.html} +0 -0
  62. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000020.html → M000042.html} +0 -0
  63. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000021.html → M000043.html} +0 -0
  64. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000022.html → M000044.html} +0 -0
  65. data/doc/rdoc/classes/Mongrel/HttpServer.html +33 -33
  66. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000008.html → M000029.html} +0 -0
  67. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000009.html → M000030.html} +0 -0
  68. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000010.html → M000031.html} +0 -0
  69. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000011.html → M000032.html} +0 -0
  70. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000012.html → M000033.html} +0 -0
  71. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000013.html → M000034.html} +0 -0
  72. data/doc/rdoc/classes/Mongrel/URIClassifier.html +33 -32
  73. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000023.html → M000045.html} +0 -0
  74. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000024.html → M000046.html} +0 -0
  75. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000025.html → M000047.html} +0 -0
  76. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000026.html → M000048.html} +0 -0
  77. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000027.html → M000049.html} +0 -0
  78. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000028.html → M000050.html} +0 -0
  79. data/doc/rdoc/classes/RailsHandler.html +225 -0
  80. data/doc/rdoc/classes/RailsHandler.src/M000001.html +22 -0
  81. data/doc/rdoc/classes/RailsHandler.src/M000002.html +48 -0
  82. data/doc/rdoc/created.rid +1 -1
  83. data/doc/rdoc/files/README.html +45 -50
  84. data/doc/rdoc/files/lib/mongrel/cgi_rb.html +108 -0
  85. data/doc/rdoc/files/lib/mongrel/command_rb.html +110 -0
  86. data/doc/rdoc/files/lib/mongrel/handlers_rb.html +101 -0
  87. data/doc/rdoc/files/lib/mongrel/plugins_rb.html +108 -0
  88. data/doc/rdoc/files/lib/mongrel/rails_rb.html +108 -0
  89. data/doc/rdoc/fr_class_index.html +8 -0
  90. data/doc/rdoc/fr_file_index.html +5 -0
  91. data/doc/rdoc/fr_method_index.html +62 -29
  92. data/lib/mongrel/command.rb +5 -5
  93. data/lib/mongrel/plugins.rb +3 -152
  94. data/lib/mongrel/rails.rb +1 -1
  95. metadata +95 -35
  96. data/test/plugins/commands/test1.rb +0 -19
  97. data/test/test_plugins.rb +0 -45
data/README CHANGED
@@ -11,11 +11,27 @@ scream without too many portability issues.
11
11
 
12
12
  == Status
13
13
 
14
- The 0.3.6 release supports Ruby On Rails much better than previously, and also
15
- sports the beginning of a command and plugin infrastructure. There is now a more
16
- complete CGIWrapper that handles most of the CGI usage, but still doesn't do the
17
- MIME decoding or file upload/send (it leaves that to CGI). Finally, there's a
18
- great mongrel_rails_service script for running under Win32 as a service.
14
+ Mongrel 0.3.9 now supports a fancy RubyGems based plugin system called GemPlugin.
15
+ It uses the basic machinery of RubyGems to implement dynamically loaded plugins
16
+ based on dependencies. Writing a plugin is pretty easy, but right now it's
17
+ not as well documented as it should be. There is a simple example plugin
18
+ for adding a status command to your mongrel. Just do:
19
+
20
+ > gem install mongrel_status
21
+
22
+ And you'll then get a new status command. Then just do:
23
+
24
+ > cd myrailsapp
25
+ > mongrel_rails start -d
26
+ > mongrel_rails status
27
+
28
+ And it'll print out the PID your Rails app is running under.
29
+
30
+ The GemPlugin project is a sub-project of Mongrel, but it's licensed under
31
+ the Ruby license and is usable outside Mongrel
32
+
33
+
34
+ == Quick Start
19
35
 
20
36
  After you've installed (either with gem install mongrel or via source) you should
21
37
  have the mongrel_rails command available in your PATH. Then you just do the following:
@@ -58,7 +74,11 @@ and do:
58
74
  -r c:\my\path\to\myapp -p 4000 -e production
59
75
  $ mongrel_rails_service start -n myapp
60
76
 
61
- Now hit the port and poof, works. *Stopping the service is a little problematic right now.*
77
+ Now hit the port and poof, works.
78
+
79
+ Stopping a service is simple:
80
+
81
+ $ mongrel_rails_service stop -n myapp
62
82
 
63
83
  If you run into an app that's not running right, my suggestion is to run it with
64
84
  the regular mongrel_rails runner:
@@ -68,6 +88,10 @@ the regular mongrel_rails runner:
68
88
 
69
89
  Since that will spit out error messages and stuff to the console. *Use CTRL-Pause/Break to stop.*
70
90
 
91
+ Best thing about the win32 support is that you can simply use the Windows Services
92
+ in Control Panel->Admin Tools to work with it. You can also install the same
93
+ Rails app as different installs. For example I've got myapp_dev, and myapp_prod and
94
+ just start/stop which one I want to work with.
71
95
 
72
96
  == Install
73
97
 
@@ -131,24 +155,6 @@ create a matching database connection for each processor thread. More on
131
155
  this in future releases.
132
156
 
133
157
 
134
- == The Future
135
-
136
- With the core of Mongrel completed I'm now turning to the next set of features
137
- to make Mongrel useful for hosting web applications in a heavily utilized
138
- production environment. Right now I'm looking at:
139
-
140
- * An idea I've had for an insane caching handler which could speed up quite a
141
- few deployments.
142
-
143
- Overall though the goal of Mongrel is to be just enough HTTP to serve a Ruby
144
- web application that sits behind a more complete web server. Everything
145
- in the next will focus on actually hosting the major web frameworks for Ruby:
146
-
147
- * Camping -- because it's already done (thanks Why).
148
- * Ruby on Rails -- that's where my bread is buttered right now.
149
- * Nitro -- Nitro folks have already hooked this up and started using it. Nice.
150
- * ????? -- Others people might be interested in.
151
-
152
158
  == Contact
153
159
 
154
160
  E-mail zedshaw at zedshaw.com and I'll help. Comments about the API are welcome.
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ include FileUtils
10
10
  setup_tests
11
11
  setup_clean ["ext/http11/*.{bundle,so,obj,pdb,lib,def,exp}", "ext/http11/Makefile", "pkg", "lib/*.bundle", "*.gem", "doc/site/output", ".config"]
12
12
 
13
- setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/*.rb', 'doc/**/*.rdoc', 'ext/http11/http11.c']
13
+ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc', 'ext/http11/http11.c']
14
14
 
15
15
  desc "Does a full compile, test run"
16
16
  task :default => [:compile, :test]
@@ -26,11 +26,12 @@ end
26
26
  task :site do
27
27
  sh %{pushd doc/site; webgen; scp -r output/* #{ENV['SSH_USER']}@rubyforge.org:/var/www/gforge-projects/mongrel/; popd }
28
28
  sh %{ scp -r doc/rdoc/* #{ENV['SSH_USER']}@rubyforge.org:/var/www/gforge-projects/mongrel/rdoc/ }
29
+ sh %{ cd projects/gem_plugin; rake site }
29
30
  end
30
31
 
31
32
  setup_extension("http11", "http11")
32
33
 
33
- version="0.3.8"
34
+ version="0.3.9"
34
35
  summary = "A small fast HTTP library and server that runs Rails, Camping, and Nitro apps."
35
36
  test_file = "test/test_ws.rb"
36
37
  author="Zed A. Shaw"
@@ -39,6 +40,7 @@ scripts=['mongrel_rails']
39
40
 
40
41
  setup_gem(name, version, author, summary, scripts, test_file) do |spec|
41
42
  spec.add_dependency('daemons', '>= 0.4.2')
43
+ spec.add_dependency('gem_plugin', ">= 0.1")
42
44
  end
43
45
 
44
46
  desc "Build a binary gem for Win32"
@@ -48,9 +50,17 @@ scripts_win32 = scripts + ['mongrel_rails_service']
48
50
  task :package_win32 do
49
51
  setup_win32_gem(name, version, version, summary, scripts_win32, test_file) do |spec|
50
52
  spec.add_dependency('win32-service', '>= 0.5.0')
53
+ spec.add_dependency('gem_plugin', ">= 0.1")
51
54
  spec.files << 'ext/http11/http11.so'
52
55
  spec.extensions = []
53
56
  spec.platform = Gem::Platform::WIN32
54
57
  end
55
58
  end
56
59
 
60
+ task :gem_plugin_project do
61
+ sh %{cd projects/gem_plugin; rake gem_test; }
62
+ end
63
+
64
+ task :gem_test => [:gem_plugin_project, :package] do
65
+ sh %{sudo gem install pkg/mongrel-#{version}}
66
+ end
@@ -1,8 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'mongrel/rails'
3
+ require 'yaml'
3
4
 
4
5
 
5
- class Start < Mongrel::Plugin "/commands"
6
+
7
+ class Start < GemPlugin::Plugin "/commands"
6
8
  include Mongrel::Command::Base
7
9
 
8
10
  def configure
@@ -18,7 +20,6 @@ class Start < Mongrel::Plugin "/commands"
18
20
  ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
19
21
  ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
20
22
  ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
21
- ['-L', '--load PATH', "Loads plugins from the given directory", :@load_from, nil],
22
23
  ]
23
24
  end
24
25
 
@@ -34,8 +35,6 @@ class Start < Mongrel::Plugin "/commands"
34
35
  valid_dir? @docroot, "Path to docroot not valid: #@docroot"
35
36
  valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
36
37
 
37
- valid_dir? @load_from, "Plugin directory path does not exist" if @load_from
38
-
39
38
  return @valid
40
39
  end
41
40
 
@@ -87,6 +86,8 @@ class Start < Mongrel::Plugin "/commands"
87
86
 
88
87
  server = Mongrel::HttpServer.new(@address, @port, @num_procs.to_i, @timeout.to_i)
89
88
  server.register("/", rails)
89
+
90
+ # start mongrel processing thread
90
91
  server.run
91
92
 
92
93
  # signal trapping just applies to posix systems
@@ -109,7 +110,10 @@ class Start < Mongrel::Plugin "/commands"
109
110
  @restart = true
110
111
  }
111
112
  end
112
-
113
+
114
+ # hook up any rails specific plugins
115
+ GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE
116
+
113
117
  begin
114
118
  STDERR.puts "Server ready."
115
119
  server.acceptor.join
@@ -123,7 +127,6 @@ class Start < Mongrel::Plugin "/commands"
123
127
  end
124
128
 
125
129
  def run
126
- Mongrel::PluginManager.instance.load(@load_from) if @load_from
127
130
  daemonize
128
131
  rails = configure_rails
129
132
  start_mongrel(rails)
@@ -144,7 +147,7 @@ def send_signal(signal, pid_file)
144
147
  end
145
148
 
146
149
 
147
- class Stop < Mongrel::Plugin "/commands"
150
+ class Stop < GemPlugin::Plugin "/commands"
148
151
  include Mongrel::Command::Base
149
152
 
150
153
  def configure
@@ -179,7 +182,7 @@ end
179
182
 
180
183
 
181
184
 
182
- class Restart < Mongrel::Plugin "/commands"
185
+ class Restart < GemPlugin::Plugin "/commands"
183
186
  include Mongrel::Command::Base
184
187
 
185
188
  def configure
@@ -212,5 +215,6 @@ class Restart < Mongrel::Plugin "/commands"
212
215
  end
213
216
  end
214
217
 
218
+ GemPlugin::Manager.instance.load "mongrel" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE
215
219
 
216
220
  Mongrel::Command::Registry.instance.run ARGV
@@ -58,6 +58,18 @@
58
58
  <a href="../files/lib/mongrel_rb.html">
59
59
  lib/mongrel.rb
60
60
  </a>
61
+ <br />
62
+ <a href="../files/lib/mongrel/cgi_rb.html">
63
+ lib/mongrel/cgi.rb
64
+ </a>
65
+ <br />
66
+ <a href="../files/lib/mongrel/command_rb.html">
67
+ lib/mongrel/command.rb
68
+ </a>
69
+ <br />
70
+ <a href="../files/lib/mongrel/handlers_rb.html">
71
+ lib/mongrel/handlers.rb
72
+ </a>
61
73
  <br />
62
74
  <a href="../files/ext/http11/http11_c.html">
63
75
  ext/http11/http11.c
@@ -100,8 +112,13 @@ to service web application requests fast as possible.
100
112
  <div id="class-list">
101
113
  <h3 class="section-bar">Classes and Modules</h3>
102
114
 
103
- Module <a href="Mongrel/Const.html" class="link">Mongrel::Const</a><br />
115
+ Module <a href="Mongrel/Command.html" class="link">Mongrel::Command</a><br />
116
+ Module <a href="Mongrel/Const.html" class="link">Mongrel::Const</a><br />
117
+ Class <a href="Mongrel/CGIWrapper.html" class="link">Mongrel::CGIWrapper</a><br />
118
+ Class <a href="Mongrel/DirHandler.html" class="link">Mongrel::DirHandler</a><br />
119
+ Class <a href="Mongrel/Error404Handler.html" class="link">Mongrel::Error404Handler</a><br />
104
120
  Class <a href="Mongrel/HeaderOut.html" class="link">Mongrel::HeaderOut</a><br />
121
+ Class <a href="Mongrel/HttpHandler.html" class="link">Mongrel::HttpHandler</a><br />
105
122
  Class <a href="Mongrel/HttpParser.html" class="link">Mongrel::HttpParser</a><br />
106
123
  Class <a href="Mongrel/HttpRequest.html" class="link">Mongrel::HttpRequest</a><br />
107
124
  Class <a href="Mongrel/HttpResponse.html" class="link">Mongrel::HttpResponse</a><br />
@@ -0,0 +1,381 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Class: Mongrel::CGIWrapper</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Class</strong></td>
53
+ <td class="class-name-in-header">Mongrel::CGIWrapper</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../../files/lib/mongrel/cgi_rb.html">
59
+ lib/mongrel/cgi.rb
60
+ </a>
61
+ <br />
62
+ </td>
63
+ </tr>
64
+
65
+ <tr class="top-aligned-row">
66
+ <td><strong>Parent:</strong></td>
67
+ <td>
68
+ ::CGI
69
+ </td>
70
+ </tr>
71
+ </table>
72
+ </div>
73
+ <!-- banner header -->
74
+
75
+ <div id="bodyContent">
76
+
77
+
78
+
79
+ <div id="contextContent">
80
+
81
+ <div id="description">
82
+ <p>
83
+ The beginning of a complete wrapper around <a
84
+ href="../Mongrel.html">Mongrel</a>&#8217;s internal HTTP processing system
85
+ but maintaining the original Ruby CGI module. Use this only as a crutch to
86
+ get existing CGI based systems working. It should handle everything, but
87
+ please notify me if you see special warnings. This work is still very alpha
88
+ so I need testers to help work out the various corner cases.
89
+ </p>
90
+ <p>
91
+ The CGIWrapper.handler attribute is normally not set and is available for
92
+ frameworks that need to get back to the handler. Rails uses this to give
93
+ people access to the RailsHandler#files (<a
94
+ href="DirHandler.html">DirHandler</a> really) so they can look-up paths and
95
+ do other things withthe files managed there.
96
+ </p>
97
+ <p>
98
+ In Rails you can get the real file for a request with:
99
+ </p>
100
+ <pre>
101
+ path = @request.cgi.handler.files.can_serve(@request['PATH_INFO'])
102
+ </pre>
103
+ <p>
104
+ Which is ugly but does the job. Feel free to write a Rails helper for that.
105
+ Refer to <a href="DirHandler.html#M000024">DirHandler#can_serve</a> for
106
+ more information on this.
107
+ </p>
108
+
109
+ </div>
110
+
111
+
112
+ </div>
113
+
114
+ <div id="method-list">
115
+ <h3 class="section-bar">Methods</h3>
116
+
117
+ <div class="name-list">
118
+ <a href="#M000056">args</a>&nbsp;&nbsp;
119
+ <a href="#M000057">env_table</a>&nbsp;&nbsp;
120
+ <a href="#M000052">header</a>&nbsp;&nbsp;
121
+ <a href="#M000051">new</a>&nbsp;&nbsp;
122
+ <a href="#M000054">out</a>&nbsp;&nbsp;
123
+ <a href="#M000053">send_cookies</a>&nbsp;&nbsp;
124
+ <a href="#M000055">status</a>&nbsp;&nbsp;
125
+ <a href="#M000058">stdinput</a>&nbsp;&nbsp;
126
+ <a href="#M000059">stdoutput</a>&nbsp;&nbsp;
127
+ </div>
128
+ </div>
129
+
130
+ </div>
131
+
132
+
133
+ <!-- if includes -->
134
+
135
+ <div id="section">
136
+
137
+
138
+ <div id="constants-list">
139
+ <h3 class="section-bar">Constants</h3>
140
+
141
+ <div class="name-list">
142
+ <table summary="Constants">
143
+ <tr class="top-aligned-row context-row">
144
+ <td class="context-item-name">REMOVED_KEYS</td>
145
+ <td>=</td>
146
+ <td class="context-item-value">[ &quot;nph&quot;,&quot;status&quot;,&quot;server&quot;,&quot;connection&quot;,&quot;type&quot;, &quot;charset&quot;,&quot;length&quot;,&quot;language&quot;,&quot;expires&quot;]</td>
147
+ <td width="3em">&nbsp;</td>
148
+ <td class="context-item-desc">
149
+ these are stripped out of any keys passed to <a
150
+ href="CGIWrapper.html#M000052">CGIWrapper.header</a> function
151
+
152
+ </td>
153
+ </tr>
154
+ </table>
155
+ </div>
156
+ </div>
157
+
158
+
159
+
160
+ <div id="attribute-list">
161
+ <h3 class="section-bar">Attributes</h3>
162
+
163
+ <div class="name-list">
164
+ <table>
165
+ <tr class="top-aligned-row context-row">
166
+ <td class="context-item-name">handler</td>
167
+ <td class="context-item-value">&nbsp;[W]&nbsp;</td>
168
+ <td class="context-item-desc"></td>
169
+ </tr>
170
+ <tr class="top-aligned-row context-row">
171
+ <td class="context-item-name">handler</td>
172
+ <td class="context-item-value">&nbsp;[R]&nbsp;</td>
173
+ <td class="context-item-desc"></td>
174
+ </tr>
175
+ <tr class="top-aligned-row context-row">
176
+ <td class="context-item-name">options</td>
177
+ <td class="context-item-value">&nbsp;[R]&nbsp;</td>
178
+ <td class="context-item-desc"></td>
179
+ </tr>
180
+ </table>
181
+ </div>
182
+ </div>
183
+
184
+
185
+
186
+ <!-- if method_list -->
187
+ <div id="methods">
188
+ <h3 class="section-bar">Public Class methods</h3>
189
+
190
+ <div id="method-M000051" class="method-detail">
191
+ <a name="M000051"></a>
192
+
193
+ <div class="method-heading">
194
+ <a href="CGIWrapper.src/M000051.html" target="Code" class="method-signature"
195
+ onclick="popupCode('CGIWrapper.src/M000051.html');return false;">
196
+ <span class="method-name">new</span><span class="method-args">(request, response, *args)</span>
197
+ </a>
198
+ </div>
199
+
200
+ <div class="method-description">
201
+ <p>
202
+ Takes an <a href="HttpRequest.html">HttpRequest</a> and <a
203
+ href="HttpResponse.html">HttpResponse</a> object, plus any additional
204
+ arguments normally passed to CGI. These are used internally to create a
205
+ wrapper around the real CGI while maintaining <a
206
+ href="../Mongrel.html">Mongrel</a>&#8217;s view of the world.
207
+ </p>
208
+ </div>
209
+ </div>
210
+
211
+ <h3 class="section-bar">Public Instance methods</h3>
212
+
213
+ <div id="method-M000056" class="method-detail">
214
+ <a name="M000056"></a>
215
+
216
+ <div class="method-heading">
217
+ <a href="CGIWrapper.src/M000056.html" target="Code" class="method-signature"
218
+ onclick="popupCode('CGIWrapper.src/M000056.html');return false;">
219
+ <span class="method-name">args</span><span class="method-args">()</span>
220
+ </a>
221
+ </div>
222
+
223
+ <div class="method-description">
224
+ <p>
225
+ Used to wrap the normal args variable used inside CGI.
226
+ </p>
227
+ </div>
228
+ </div>
229
+
230
+ <div id="method-M000057" class="method-detail">
231
+ <a name="M000057"></a>
232
+
233
+ <div class="method-heading">
234
+ <a href="CGIWrapper.src/M000057.html" target="Code" class="method-signature"
235
+ onclick="popupCode('CGIWrapper.src/M000057.html');return false;">
236
+ <span class="method-name">env_table</span><span class="method-args">()</span>
237
+ </a>
238
+ </div>
239
+
240
+ <div class="method-description">
241
+ <p>
242
+ Used to wrap the normal <a href="CGIWrapper.html#M000057">env_table</a>
243
+ variable used inside CGI.
244
+ </p>
245
+ </div>
246
+ </div>
247
+
248
+ <div id="method-M000052" class="method-detail">
249
+ <a name="M000052"></a>
250
+
251
+ <div class="method-heading">
252
+ <a href="CGIWrapper.src/M000052.html" target="Code" class="method-signature"
253
+ onclick="popupCode('CGIWrapper.src/M000052.html');return false;">
254
+ <span class="method-name">header</span><span class="method-args">(options = &quot;text/html&quot;)</span>
255
+ </a>
256
+ </div>
257
+
258
+ <div class="method-description">
259
+ <p>
260
+ The header is typically called to send back the header. In our case we
261
+ collect it into a hash for later usage.
262
+ </p>
263
+ <p>
264
+ nph &#8212; Mostly ignored. It&#8216;ll output the date. connection &#8212;
265
+ Completely ignored. Why is CGI doing this? length &#8212; Ignored since <a
266
+ href="../Mongrel.html">Mongrel</a> figures this out from what you write to
267
+ output.
268
+ </p>
269
+ </div>
270
+ </div>
271
+
272
+ <div id="method-M000054" class="method-detail">
273
+ <a name="M000054"></a>
274
+
275
+ <div class="method-heading">
276
+ <a href="CGIWrapper.src/M000054.html" target="Code" class="method-signature"
277
+ onclick="popupCode('CGIWrapper.src/M000054.html');return false;">
278
+ <span class="method-name">out</span><span class="method-args">(options = &quot;text/html&quot;) {||| &quot;&quot;)| ...}</span>
279
+ </a>
280
+ </div>
281
+
282
+ <div class="method-description">
283
+ <p>
284
+ The dumb thing is people can call header or this or both and in any order.
285
+ So, we just reuse header and then finalize the <a
286
+ href="HttpResponse.html">HttpResponse</a> the right way. Status is taken
287
+ from the various options and converted to what <a
288
+ href="../Mongrel.html">Mongrel</a> needs via the <a
289
+ href="CGIWrapper.html#M000055">CGIWrapper.status</a> function.
290
+ </p>
291
+ </div>
292
+ </div>
293
+
294
+ <div id="method-M000053" class="method-detail">
295
+ <a name="M000053"></a>
296
+
297
+ <div class="method-heading">
298
+ <a href="CGIWrapper.src/M000053.html" target="Code" class="method-signature"
299
+ onclick="popupCode('CGIWrapper.src/M000053.html');return false;">
300
+ <span class="method-name">send_cookies</span><span class="method-args">(to)</span>
301
+ </a>
302
+ </div>
303
+
304
+ <div class="method-description">
305
+ <p>
306
+ Takes any &#8216;cookie&#8217; setting and sends it over the <a
307
+ href="../Mongrel.html">Mongrel</a> header, then removes the setting from
308
+ the options. If cookie is an Array or Hash then it sends those on with
309
+ .to_s, otherwise it just calls .to_s on it and hopefully your
310
+ &quot;cookie&quot; can write itself correctly.
311
+ </p>
312
+ </div>
313
+ </div>
314
+
315
+ <div id="method-M000055" class="method-detail">
316
+ <a name="M000055"></a>
317
+
318
+ <div class="method-heading">
319
+ <a href="CGIWrapper.src/M000055.html" target="Code" class="method-signature"
320
+ onclick="popupCode('CGIWrapper.src/M000055.html');return false;">
321
+ <span class="method-name">status</span><span class="method-args">()</span>
322
+ </a>
323
+ </div>
324
+
325
+ <div class="method-description">
326
+ <p>
327
+ Computes the status once, but lazily so that people who call header twice
328
+ don&#8217;t get penalized. Because CGI insists on including the options
329
+ status message in the status we have to do a bit of parsing.
330
+ </p>
331
+ </div>
332
+ </div>
333
+
334
+ <div id="method-M000058" class="method-detail">
335
+ <a name="M000058"></a>
336
+
337
+ <div class="method-heading">
338
+ <a href="CGIWrapper.src/M000058.html" target="Code" class="method-signature"
339
+ onclick="popupCode('CGIWrapper.src/M000058.html');return false;">
340
+ <span class="method-name">stdinput</span><span class="method-args">()</span>
341
+ </a>
342
+ </div>
343
+
344
+ <div class="method-description">
345
+ <p>
346
+ Used to wrap the normal stdinput variable used inside CGI.
347
+ </p>
348
+ </div>
349
+ </div>
350
+
351
+ <div id="method-M000059" class="method-detail">
352
+ <a name="M000059"></a>
353
+
354
+ <div class="method-heading">
355
+ <a href="CGIWrapper.src/M000059.html" target="Code" class="method-signature"
356
+ onclick="popupCode('CGIWrapper.src/M000059.html');return false;">
357
+ <span class="method-name">stdoutput</span><span class="method-args">()</span>
358
+ </a>
359
+ </div>
360
+
361
+ <div class="method-description">
362
+ <p>
363
+ The stdoutput should be completely bypassed but we&#8217;ll drop a warning
364
+ just in case
365
+ </p>
366
+ </div>
367
+ </div>
368
+
369
+
370
+ </div>
371
+
372
+
373
+ </div>
374
+
375
+
376
+ <div id="validator-badges">
377
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
378
+ </div>
379
+
380
+ </body>
381
+ </html>