mongrel 0.2.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/README +27 -25
  2. data/Rakefile +2 -3
  3. data/bin/mongrel_rails +114 -0
  4. data/doc/rdoc/classes/Mongrel.html +30 -0
  5. data/doc/rdoc/classes/Mongrel.src/M000001.html +18 -0
  6. data/doc/rdoc/classes/Mongrel/Const.html +2 -2
  7. data/doc/rdoc/classes/Mongrel/DirHandler.html +84 -21
  8. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000009.html +7 -18
  9. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000010.html +26 -9
  10. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000011.html +27 -26
  11. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000012.html +31 -0
  12. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000013.html +38 -0
  13. data/doc/rdoc/classes/Mongrel/Error404Handler.html +10 -10
  14. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000028.html → M000033.html} +4 -4
  15. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000029.html → M000034.html} +4 -4
  16. data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
  17. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000017.html → M000019.html} +4 -4
  18. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000018.html → M000020.html} +7 -7
  19. data/doc/rdoc/classes/Mongrel/HttpHandler.html +5 -5
  20. data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000023.html → M000025.html} +3 -3
  21. data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
  22. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000002.html +5 -6
  23. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000003.html +7 -7
  24. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000004.html +8 -20
  25. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000005.html +20 -6
  26. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000006.html +5 -5
  27. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000007.html +5 -6
  28. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000001.html → M000008.html} +6 -6
  29. data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
  30. data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000030.html → M000035.html} +17 -17
  31. data/doc/rdoc/classes/Mongrel/HttpResponse.html +66 -21
  32. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000026.html +8 -6
  33. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000027.html +7 -12
  34. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000028.html +19 -0
  35. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000029.html +18 -0
  36. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000030.html +20 -0
  37. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000031.html +21 -0
  38. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000032.html +20 -0
  39. data/doc/rdoc/classes/Mongrel/HttpServer.html +28 -28
  40. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000014.html +18 -10
  41. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000015.html +51 -5
  42. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000016.html +9 -4
  43. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000017.html +18 -0
  44. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000018.html +18 -0
  45. data/doc/rdoc/classes/Mongrel/URIClassifier.html +31 -21
  46. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000021.html +18 -15
  47. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000022.html +25 -42
  48. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000023.html +36 -0
  49. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000024.html +84 -0
  50. data/doc/rdoc/created.rid +1 -1
  51. data/doc/rdoc/files/README.html +32 -42
  52. data/doc/rdoc/files/ext/http11/http11_c.html +1 -1
  53. data/doc/rdoc/files/lib/mongrel_rb.html +1 -1
  54. data/doc/rdoc/fr_method_index.html +35 -30
  55. data/examples/simpletest.rb +16 -6
  56. data/ext/http11/http11.c +19 -3
  57. data/ext/http11/tst_search.c +2 -3
  58. data/lib/mongrel.rb +108 -20
  59. data/test/test_uriclassifier.rb +22 -1
  60. metadata +25 -19
  61. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000008.html +0 -20
  62. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000024.html +0 -21
  63. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000025.html +0 -20
  64. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000012.html +0 -31
  65. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html +0 -64
  66. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000019.html +0 -39
  67. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000020.html +0 -51
  68. data/lib/#mongrel.rb# +0 -493
data/README CHANGED
@@ -11,26 +11,31 @@ scream without too many portability issues.
11
11
 
12
12
  == Status
13
13
 
14
- The 0.2.2 release of Mongrel features an HTTP core server that is the fastest possible
15
- thing I could get without using something other than Ruby. It features a few bug fixes,
16
- but mostly just a change to the Mongrel::HttpResponse class to make it more feature
17
- complete. The remaining development will be spent getting Mongrel to work with
18
- other frameworks, adding additional needed features, and improving the concurrency
19
- and speed.
20
-
21
- The current release has samples from "why the lucky stiff" for his Camping
22
- framework in the examples directory. Camping is a small micro framework
23
- (http://rubyforge.org/projects/camping) which should work with Mongrel if
24
- you use the subversion source for Camping.
25
-
26
- This is also the first release onto the new Mongrel RubyForge project
27
- page found at http://rubyforge.org/projects/mongrel/ thanks to Tom Copland.
28
- I'll be looking to automate management of this, but feel free to use
29
- rubyforge to post feature requests, bugs, and join the mailing list.
30
-
31
- Finally, it now supports all CGI parameters that don't cause a performance hit,
32
- and it has a Mongrel::DirHandler which can serve files out of a directory and
33
- do (optional) directory listings.
14
+ The 0.3 release is the first official release to start supporting Ruby on Rails
15
+ and to have a more complete DirHandler for serving directories of files. This release
16
+ is actually closer to a full functioning web server than the previous releases.
17
+
18
+ The Rails support is pretty rough right now, but check out the bin/mongrel_rails file,
19
+ which should be installed into your PATH if you use a gem. You should be able to
20
+ do the following to run your Rails applications:
21
+
22
+ > cd myrailsapp
23
+ > mongrel_rails 0.0.0.0 3000
24
+
25
+ And then hit http://localhost:3000/ to see your app. One thing is that if you have
26
+ a public/index.html file then you'll get that served instead of your Rails application.
27
+
28
+ People with the daemons gem installed will see that mongrel_rails will go into the
29
+ background. You can kill it with:
30
+
31
+ > kill -TERM `cat log/mongrel-3000.pid`
32
+
33
+ Where "3000" is whatever port you told it to listen on when you ran it.
34
+
35
+ The file serving is still a little rough and the redirects might not work well, but
36
+ try it out and tell me about any weird errors. File uploads will definitely have some
37
+ problems.
38
+
34
39
 
35
40
  == Install
36
41
 
@@ -43,6 +48,7 @@ who can build it for you.
43
48
 
44
49
  Finally, the source includes a setup.rb for those who hate RubyGems.
45
50
 
51
+
46
52
  == Usage
47
53
 
48
54
  The examples/simpletest.rb file has the following code as the simplest
@@ -104,12 +110,8 @@ With the core of Mongrel completed I'm now turning to the next set of features
104
110
  to make Mongrel useful for hosting web applications in a heavily utilized
105
111
  production environment. Right now I'm looking at:
106
112
 
107
- * Fast static file handling with directory listings.
108
- * More testing on more platforms.
109
113
  * An idea I've had for an insane caching handler which could speed up quite a
110
114
  few deployments.
111
- * General little things most web servers need.
112
- * A nice management system or interface for controlling mongrel servers.
113
115
 
114
116
  Overall though the goal of Mongrel is to be just enough HTTP to serve a Ruby
115
117
  web application that sits behind a more complete web server. Everything
@@ -117,7 +119,7 @@ in the next will focus on actually hosting the major web frameworks for Ruby:
117
119
 
118
120
  * Camping -- because it's already done (thanks Why).
119
121
  * Ruby on Rails -- that's where my bread is buttered right now.
120
- * Nitro -- George is a nice guy, and Nitro is thread safe. Might be fun.
122
+ * Nitro -- Nitro folks have already hooked this up and started using it. Nice.
121
123
  * ????? -- Others people might be interested in.
122
124
 
123
125
  == Contact
data/Rakefile CHANGED
@@ -9,8 +9,7 @@ include FileUtils
9
9
 
10
10
  setup_tests
11
11
  setup_clean ["ext/http11/Makefile", "pkg", "lib/*.bundle", "ext/http11/*.bundle"]
12
- setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/*.rb',
13
- 'doc/**/*.rdoc', 'ext/http11/http11.c']
12
+ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/*.rb', 'doc/**/*.rdoc', 'ext/http11/http11.c']
14
13
 
15
14
  desc "Does a full compile, test run"
16
15
  task :default => [:compile, :test]
@@ -27,4 +26,4 @@ setup_extension("http11", "http11")
27
26
 
28
27
  summary = "An experimental fast simple web server for Ruby."
29
28
  test_file = "test/test_ws.rb"
30
- setup_gem("mongrel", "0.2.2", "Zed A. Shaw", summary, [], test_file)
29
+ setup_gem("mongrel", "0.3", "Zed A. Shaw", summary, ['mongrel_rails'], test_file)
@@ -0,0 +1,114 @@
1
+ require 'rubygems'
2
+ require 'mongrel'
3
+ require 'cgi'
4
+ begin
5
+ require 'daemons/daemonize'
6
+ HAVE_DAEMONS=true
7
+ rescue
8
+ HAVE_DAEMONS=false
9
+ end
10
+
11
+
12
+ class CGIFixed < ::CGI
13
+ public :env_table
14
+ attr_reader :options
15
+
16
+ def initialize(params, data, out, *args)
17
+ @env_table = params
18
+ @args = *args
19
+ @input = StringIO.new(data)
20
+ @out = out
21
+ @options = {}
22
+ super(*args)
23
+ end
24
+
25
+ def header(options = "text/html")
26
+ if options.class == Hash
27
+ # passing in a header so need to keep the status around and other options
28
+ @options = options
29
+ end
30
+
31
+ super(options)
32
+ end
33
+
34
+ def status
35
+ s = @options["Status"] || @options["status"]
36
+ s[0 .. s.index(' ')] || "200"
37
+ end
38
+
39
+ def args
40
+ @args
41
+ end
42
+
43
+ def env_table
44
+ @env_table
45
+ end
46
+
47
+ def stdinput
48
+ @input
49
+ end
50
+
51
+ def stdoutput
52
+ @out
53
+ end
54
+ end
55
+
56
+
57
+ class RailsHandler < Mongrel::HttpHandler
58
+ def initialize(dir)
59
+ @files = Mongrel::DirHandler.new(dir,false)
60
+ @guard = Mutex.new
61
+ end
62
+
63
+ def process(request, response)
64
+ # not static, need to talk to rails
65
+ return if response.socket.closed?
66
+
67
+ if @files.can_serve(request.params["PATH_INFO"])
68
+ @files.process(request,response)
69
+ else
70
+ cgi = CGIFixed.new(request.params, request.body, response.socket)
71
+ begin
72
+
73
+ @guard.synchronize do
74
+ # Rails is not thread safe so must be run entirely within synchronize
75
+ Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
76
+ end
77
+
78
+ response.status = cgi.status
79
+ response.send_status
80
+ response.send_body
81
+ rescue Object => rails_error
82
+ STDERR.puts "calling Dispatcher.dispatch #{rails_error}"
83
+ STDERR.puts rails_error.backtrace.join("\n")
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ if ARGV.length != 2
91
+ STDERR.puts "usage: mongrel_rails <host> <port>"
92
+ exit(1)
93
+ end
94
+
95
+ # store this for later since Daemonize insists on going to the / root
96
+ cwd = Dir.pwd
97
+
98
+ if HAVE_DAEMONS
99
+ STDERR.puts "Running Mongrel in the background. See log/mongrel.log for errors."
100
+ Daemonize.daemonize(log_file=File.join(cwd,"log","mongrel.log"))
101
+ else
102
+ STDERR.puts "Unable to daemonize. Running in foreground. Use CTRL-C to stop."
103
+ end
104
+
105
+ # and go back
106
+ Dir.chdir(cwd) do
107
+ require 'config/environment'
108
+ open(File.join(cwd,"log/mongrel-#{ARGV[1]}.pid"),"w") {|f| f.write(Process.pid) }
109
+ h = Mongrel::HttpServer.new(ARGV[0], ARGV[1])
110
+ h.register("/", RailsHandler.new(File.join(cwd,"public")))
111
+ h.run
112
+
113
+ h.acceptor.join
114
+ end
@@ -89,6 +89,13 @@ to service web application requests fast as possible.
89
89
 
90
90
  </div>
91
91
 
92
+ <div id="method-list">
93
+ <h3 class="section-bar">Methods</h3>
94
+
95
+ <div class="name-list">
96
+ <a href="#M000001">add_mime_type</a>&nbsp;&nbsp;
97
+ </div>
98
+ </div>
92
99
 
93
100
  </div>
94
101
 
@@ -141,6 +148,29 @@ href="Mongrel/Const.html">Mongrel::Const</a>.
141
148
 
142
149
 
143
150
  <!-- if method_list -->
151
+ <div id="methods">
152
+ <h3 class="section-bar">Public Instance methods</h3>
153
+
154
+ <div id="method-M000001" class="method-detail">
155
+ <a name="M000001"></a>
156
+
157
+ <div class="method-heading">
158
+ <a href="Mongrel.src/M000001.html" target="Code" class="method-signature"
159
+ onclick="popupCode('Mongrel.src/M000001.html');return false;">
160
+ <span class="method-name">add_mime_type</span><span class="method-args">(extension, type)</span>
161
+ </a>
162
+ </div>
163
+
164
+ <div class="method-description">
165
+ <p>
166
+ There is a small number of default mime types for extensions, but this lets
167
+ you add any others you&#8217;ll need when serving content.
168
+ </p>
169
+ </div>
170
+ </div>
171
+
172
+
173
+ </div>
144
174
 
145
175
 
146
176
  </div>
@@ -0,0 +1,18 @@
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>
7
+ <head>
8
+ <title>add_mime_type (Mongrel)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre> <span class="ruby-comment cmt"># File lib/mongrel.rb, line 577</span>
14
+ 577: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">add_mime_type</span>(<span class="ruby-identifier">extension</span>, <span class="ruby-identifier">type</span>)
15
+ 578: <span class="ruby-constant">MIME_TYPES</span>[<span class="ruby-identifier">extension</span>] = <span class="ruby-identifier">type</span>
16
+ 579: <span class="ruby-keyword kw">end</span></pre>
17
+ </body>
18
+ </html>
@@ -230,7 +230,7 @@ DNS resolves. It is only here for completeness for the CGI standard.
230
230
  <td width="3em">&nbsp;</td>
231
231
  <td class="context-item-desc">
232
232
  The name/host of our server as given by the <a
233
- href="HttpServer.html#M000012">HttpServer.new</a>(host,port) call.
233
+ href="HttpServer.html#M000014">HttpServer.new</a>(host,port) call.
234
234
 
235
235
  </td>
236
236
  </tr>
@@ -241,7 +241,7 @@ href="HttpServer.html#M000012">HttpServer.new</a>(host,port) call.
241
241
  <td width="3em">&nbsp;</td>
242
242
  <td class="context-item-desc">
243
243
  The port of our server as given by the <a
244
- href="HttpServer.html#M000012">HttpServer.new</a>(host,port) call.
244
+ href="HttpServer.html#M000014">HttpServer.new</a>(host,port) call.
245
245
 
246
246
  </td>
247
247
  </tr>
@@ -103,10 +103,11 @@ than it simply gives a 404.
103
103
  <h3 class="section-bar">Methods</h3>
104
104
 
105
105
  <div class="name-list">
106
- <a href="#M000008">new</a>&nbsp;&nbsp;
107
- <a href="#M000011">process</a>&nbsp;&nbsp;
108
- <a href="#M000009">send_dir_listing</a>&nbsp;&nbsp;
109
- <a href="#M000010">send_file</a>&nbsp;&nbsp;
106
+ <a href="#M000010">can_serve</a>&nbsp;&nbsp;
107
+ <a href="#M000009">new</a>&nbsp;&nbsp;
108
+ <a href="#M000013">process</a>&nbsp;&nbsp;
109
+ <a href="#M000011">send_dir_listing</a>&nbsp;&nbsp;
110
+ <a href="#M000012">send_file</a>&nbsp;&nbsp;
110
111
  </div>
111
112
  </div>
112
113
 
@@ -118,9 +119,35 @@ than it simply gives a 404.
118
119
  <div id="section">
119
120
 
120
121
 
122
+ <div id="constants-list">
123
+ <h3 class="section-bar">Constants</h3>
124
+
125
+ <div class="name-list">
126
+ <table summary="Constants">
127
+ <tr class="top-aligned-row context-row">
128
+ <td class="context-item-name">MIME_TYPES</td>
129
+ <td>=</td>
130
+ <td class="context-item-value">{ &quot;.css&quot; =&gt; &quot;text/css&quot;, &quot;.gif&quot; =&gt; &quot;image/gif&quot;, &quot;.htm&quot; =&gt; &quot;text/html&quot;, &quot;.html&quot; =&gt; &quot;text/html&quot;, &quot;.jpeg&quot; =&gt; &quot;image/jpeg&quot;, &quot;.jpg&quot; =&gt; &quot;image/jpeg&quot;, &quot;.js&quot; =&gt; &quot;text/javascript&quot;, &quot;.png&quot; =&gt; &quot;image/png&quot;, &quot;.swf&quot; =&gt; &quot;application/x-shockwave-flash&quot;, &quot;.txt&quot; =&gt; &quot;text/plain&quot;</td>
131
+ </tr>
132
+ </table>
133
+ </div>
134
+ </div>
135
+
121
136
 
122
137
 
138
+ <div id="attribute-list">
139
+ <h3 class="section-bar">Attributes</h3>
123
140
 
141
+ <div class="name-list">
142
+ <table>
143
+ <tr class="top-aligned-row context-row">
144
+ <td class="context-item-name">path</td>
145
+ <td class="context-item-value">&nbsp;[R]&nbsp;</td>
146
+ <td class="context-item-desc"></td>
147
+ </tr>
148
+ </table>
149
+ </div>
150
+ </div>
124
151
 
125
152
 
126
153
 
@@ -128,61 +155,97 @@ than it simply gives a 404.
128
155
  <div id="methods">
129
156
  <h3 class="section-bar">Public Class methods</h3>
130
157
 
131
- <div id="method-M000008" class="method-detail">
132
- <a name="M000008"></a>
158
+ <div id="method-M000009" class="method-detail">
159
+ <a name="M000009"></a>
133
160
 
134
161
  <div class="method-heading">
135
- <a href="DirHandler.src/M000008.html" target="Code" class="method-signature"
136
- onclick="popupCode('DirHandler.src/M000008.html');return false;">
137
- <span class="method-name">new</span><span class="method-args">(path, listing_allowed=true)</span>
162
+ <a href="DirHandler.src/M000009.html" target="Code" class="method-signature"
163
+ onclick="popupCode('DirHandler.src/M000009.html');return false;">
164
+ <span class="method-name">new</span><span class="method-args">(path, listing_allowed=true, index_html=&quot;index.html&quot;)</span>
138
165
  </a>
139
166
  </div>
140
167
 
141
168
  <div class="method-description">
169
+ <p>
170
+ You give it the path to the directory root and an (optional)
171
+ </p>
142
172
  </div>
143
173
  </div>
144
174
 
145
175
  <h3 class="section-bar">Public Instance methods</h3>
146
176
 
147
- <div id="method-M000011" class="method-detail">
148
- <a name="M000011"></a>
177
+ <div id="method-M000010" class="method-detail">
178
+ <a name="M000010"></a>
149
179
 
150
180
  <div class="method-heading">
151
- <a href="DirHandler.src/M000011.html" target="Code" class="method-signature"
152
- onclick="popupCode('DirHandler.src/M000011.html');return false;">
181
+ <a href="DirHandler.src/M000010.html" target="Code" class="method-signature"
182
+ onclick="popupCode('DirHandler.src/M000010.html');return false;">
183
+ <span class="method-name">can_serve</span><span class="method-args">(path_info)</span>
184
+ </a>
185
+ </div>
186
+
187
+ <div class="method-description">
188
+ <p>
189
+ Checks if the given path can be served and returns the full path (or nil if
190
+ not).
191
+ </p>
192
+ </div>
193
+ </div>
194
+
195
+ <div id="method-M000013" class="method-detail">
196
+ <a name="M000013"></a>
197
+
198
+ <div class="method-heading">
199
+ <a href="DirHandler.src/M000013.html" target="Code" class="method-signature"
200
+ onclick="popupCode('DirHandler.src/M000013.html');return false;">
153
201
  <span class="method-name">process</span><span class="method-args">(request, response)</span>
154
202
  </a>
155
203
  </div>
156
204
 
157
205
  <div class="method-description">
206
+ <p>
207
+ Process the request to either serve a file or a directory listing if
208
+ allowed (based on the listing_allowed paramter to the constructor).
209
+ </p>
158
210
  </div>
159
211
  </div>
160
212
 
161
- <div id="method-M000009" class="method-detail">
162
- <a name="M000009"></a>
213
+ <div id="method-M000011" class="method-detail">
214
+ <a name="M000011"></a>
163
215
 
164
216
  <div class="method-heading">
165
- <a href="DirHandler.src/M000009.html" target="Code" class="method-signature"
166
- onclick="popupCode('DirHandler.src/M000009.html');return false;">
217
+ <a href="DirHandler.src/M000011.html" target="Code" class="method-signature"
218
+ onclick="popupCode('DirHandler.src/M000011.html');return false;">
167
219
  <span class="method-name">send_dir_listing</span><span class="method-args">(base, dir, response)</span>
168
220
  </a>
169
221
  </div>
170
222
 
171
223
  <div class="method-description">
224
+ <p>
225
+ Returns a simplistic directory listing if they&#8217;re enabled, otherwise
226
+ a 403. Base is the base URI from the REQUEST_URI, dir is the directory to
227
+ serve on the file system (comes from <a
228
+ href="DirHandler.html#M000010">can_serve</a>()), and response is the <a
229
+ href="HttpResponse.html">HttpResponse</a> object to send the results on.
230
+ </p>
172
231
  </div>
173
232
  </div>
174
233
 
175
- <div id="method-M000010" class="method-detail">
176
- <a name="M000010"></a>
234
+ <div id="method-M000012" class="method-detail">
235
+ <a name="M000012"></a>
177
236
 
178
237
  <div class="method-heading">
179
- <a href="DirHandler.src/M000010.html" target="Code" class="method-signature"
180
- onclick="popupCode('DirHandler.src/M000010.html');return false;">
238
+ <a href="DirHandler.src/M000012.html" target="Code" class="method-signature"
239
+ onclick="popupCode('DirHandler.src/M000012.html');return false;">
181
240
  <span class="method-name">send_file</span><span class="method-args">(req, response)</span>
182
241
  </a>
183
242
  </div>
184
243
 
185
244
  <div class="method-description">
245
+ <p>
246
+ Sends the contents of a file back to the user. Not terribly efficient since
247
+ it&#8217;s opening and closing the file for each read.
248
+ </p>
186
249
  </div>
187
250
  </div>
188
251