mongrel 0.2.2 → 0.3
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/README +27 -25
- data/Rakefile +2 -3
- data/bin/mongrel_rails +114 -0
- data/doc/rdoc/classes/Mongrel.html +30 -0
- data/doc/rdoc/classes/Mongrel.src/M000001.html +18 -0
- data/doc/rdoc/classes/Mongrel/Const.html +2 -2
- data/doc/rdoc/classes/Mongrel/DirHandler.html +84 -21
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000009.html +7 -18
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000010.html +26 -9
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000011.html +27 -26
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000012.html +31 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000013.html +38 -0
- data/doc/rdoc/classes/Mongrel/Error404Handler.html +10 -10
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000028.html → M000033.html} +4 -4
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000029.html → M000034.html} +4 -4
- data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000017.html → M000019.html} +4 -4
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000018.html → M000020.html} +7 -7
- data/doc/rdoc/classes/Mongrel/HttpHandler.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000023.html → M000025.html} +3 -3
- data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000002.html +5 -6
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000003.html +7 -7
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000004.html +8 -20
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000005.html +20 -6
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000006.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000007.html +5 -6
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000001.html → M000008.html} +6 -6
- data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000030.html → M000035.html} +17 -17
- data/doc/rdoc/classes/Mongrel/HttpResponse.html +66 -21
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000026.html +8 -6
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000027.html +7 -12
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000028.html +19 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000029.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000030.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000031.html +21 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000032.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.html +28 -28
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000014.html +18 -10
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000015.html +51 -5
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000016.html +9 -4
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000017.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000018.html +18 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.html +31 -21
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000021.html +18 -15
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000022.html +25 -42
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000023.html +36 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000024.html +84 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/README.html +32 -42
- data/doc/rdoc/files/ext/http11/http11_c.html +1 -1
- data/doc/rdoc/files/lib/mongrel_rb.html +1 -1
- data/doc/rdoc/fr_method_index.html +35 -30
- data/examples/simpletest.rb +16 -6
- data/ext/http11/http11.c +19 -3
- data/ext/http11/tst_search.c +2 -3
- data/lib/mongrel.rb +108 -20
- data/test/test_uriclassifier.rb +22 -1
- metadata +25 -19
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000008.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000024.html +0 -21
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000025.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000012.html +0 -31
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html +0 -64
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000019.html +0 -39
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000020.html +0 -51
- data/lib/#mongrel.rb# +0 -493
|
@@ -20,36 +20,41 @@
|
|
|
20
20
|
<div id="index">
|
|
21
21
|
<h1 class="section-bar">Methods</h1>
|
|
22
22
|
<div id="index-entries">
|
|
23
|
-
<a href="classes/Mongrel/HeaderOut.html#
|
|
24
|
-
<a href="classes/Mongrel
|
|
25
|
-
<a href="classes/Mongrel/
|
|
26
|
-
<a href="classes/Mongrel/HttpParser.html#
|
|
27
|
-
<a href="classes/Mongrel/
|
|
28
|
-
<a href="classes/Mongrel/HttpParser.html#
|
|
29
|
-
<a href="classes/Mongrel/
|
|
30
|
-
<a href="classes/Mongrel/
|
|
31
|
-
<a href="classes/Mongrel/
|
|
32
|
-
<a href="classes/Mongrel/
|
|
33
|
-
<a href="classes/Mongrel/
|
|
34
|
-
<a href="classes/Mongrel/
|
|
35
|
-
<a href="classes/Mongrel/
|
|
36
|
-
<a href="classes/Mongrel/
|
|
37
|
-
<a href="classes/Mongrel/
|
|
38
|
-
<a href="classes/Mongrel/
|
|
39
|
-
<a href="classes/Mongrel/
|
|
40
|
-
<a href="classes/Mongrel/HttpHandler.html#
|
|
41
|
-
<a href="classes/Mongrel/
|
|
42
|
-
<a href="classes/Mongrel/
|
|
43
|
-
<a href="classes/Mongrel/
|
|
44
|
-
<a href="classes/Mongrel/
|
|
45
|
-
<a href="classes/Mongrel/
|
|
46
|
-
<a href="classes/Mongrel/
|
|
47
|
-
<a href="classes/Mongrel/
|
|
48
|
-
<a href="classes/Mongrel/
|
|
49
|
-
<a href="classes/Mongrel/
|
|
50
|
-
<a href="classes/Mongrel/HttpResponse.html#
|
|
51
|
-
<a href="classes/Mongrel/
|
|
52
|
-
<a href="classes/Mongrel/
|
|
23
|
+
<a href="classes/Mongrel/HeaderOut.html#M000020">[]= (Mongrel::HeaderOut)</a><br />
|
|
24
|
+
<a href="classes/Mongrel.html#M000001">add_mime_type (Mongrel)</a><br />
|
|
25
|
+
<a href="classes/Mongrel/DirHandler.html#M000010">can_serve (Mongrel::DirHandler)</a><br />
|
|
26
|
+
<a href="classes/Mongrel/HttpParser.html#M000006">error? (Mongrel::HttpParser)</a><br />
|
|
27
|
+
<a href="classes/Mongrel/HttpParser.html#M000005">execute (Mongrel::HttpParser)</a><br />
|
|
28
|
+
<a href="classes/Mongrel/HttpParser.html#M000004">finish (Mongrel::HttpParser)</a><br />
|
|
29
|
+
<a href="classes/Mongrel/HttpResponse.html#M000032">finished (Mongrel::HttpResponse)</a><br />
|
|
30
|
+
<a href="classes/Mongrel/HttpParser.html#M000007">finished? (Mongrel::HttpParser)</a><br />
|
|
31
|
+
<a href="classes/Mongrel/URIClassifier.html#M000021">new (Mongrel::URIClassifier)</a><br />
|
|
32
|
+
<a href="classes/Mongrel/Error404Handler.html#M000033">new (Mongrel::Error404Handler)</a><br />
|
|
33
|
+
<a href="classes/Mongrel/HttpResponse.html#M000026">new (Mongrel::HttpResponse)</a><br />
|
|
34
|
+
<a href="classes/Mongrel/DirHandler.html#M000009">new (Mongrel::DirHandler)</a><br />
|
|
35
|
+
<a href="classes/Mongrel/HttpParser.html#M000002">new (Mongrel::HttpParser)</a><br />
|
|
36
|
+
<a href="classes/Mongrel/HttpServer.html#M000014">new (Mongrel::HttpServer)</a><br />
|
|
37
|
+
<a href="classes/Mongrel/HeaderOut.html#M000019">new (Mongrel::HeaderOut)</a><br />
|
|
38
|
+
<a href="classes/Mongrel/HttpRequest.html#M000035">new (Mongrel::HttpRequest)</a><br />
|
|
39
|
+
<a href="classes/Mongrel/HttpParser.html#M000008">nread (Mongrel::HttpParser)</a><br />
|
|
40
|
+
<a href="classes/Mongrel/HttpHandler.html#M000025">process (Mongrel::HttpHandler)</a><br />
|
|
41
|
+
<a href="classes/Mongrel/Error404Handler.html#M000034">process (Mongrel::Error404Handler)</a><br />
|
|
42
|
+
<a href="classes/Mongrel/DirHandler.html#M000013">process (Mongrel::DirHandler)</a><br />
|
|
43
|
+
<a href="classes/Mongrel/HttpServer.html#M000015">process_client (Mongrel::HttpServer)</a><br />
|
|
44
|
+
<a href="classes/Mongrel/URIClassifier.html#M000022">register (Mongrel::URIClassifier)</a><br />
|
|
45
|
+
<a href="classes/Mongrel/HttpServer.html#M000017">register (Mongrel::HttpServer)</a><br />
|
|
46
|
+
<a href="classes/Mongrel/HttpParser.html#M000003">reset (Mongrel::HttpParser)</a><br />
|
|
47
|
+
<a href="classes/Mongrel/HttpResponse.html#M000028">reset (Mongrel::HttpResponse)</a><br />
|
|
48
|
+
<a href="classes/Mongrel/URIClassifier.html#M000024">resolve (Mongrel::URIClassifier)</a><br />
|
|
49
|
+
<a href="classes/Mongrel/HttpServer.html#M000016">run (Mongrel::HttpServer)</a><br />
|
|
50
|
+
<a href="classes/Mongrel/HttpResponse.html#M000031">send_body (Mongrel::HttpResponse)</a><br />
|
|
51
|
+
<a href="classes/Mongrel/DirHandler.html#M000011">send_dir_listing (Mongrel::DirHandler)</a><br />
|
|
52
|
+
<a href="classes/Mongrel/DirHandler.html#M000012">send_file (Mongrel::DirHandler)</a><br />
|
|
53
|
+
<a href="classes/Mongrel/HttpResponse.html#M000030">send_header (Mongrel::HttpResponse)</a><br />
|
|
54
|
+
<a href="classes/Mongrel/HttpResponse.html#M000029">send_status (Mongrel::HttpResponse)</a><br />
|
|
55
|
+
<a href="classes/Mongrel/HttpResponse.html#M000027">start (Mongrel::HttpResponse)</a><br />
|
|
56
|
+
<a href="classes/Mongrel/URIClassifier.html#M000023">unregister (Mongrel::URIClassifier)</a><br />
|
|
57
|
+
<a href="classes/Mongrel/HttpServer.html#M000018">unregister (Mongrel::HttpServer)</a><br />
|
|
53
58
|
</div>
|
|
54
59
|
</div>
|
|
55
60
|
</body>
|
data/examples/simpletest.rb
CHANGED
|
@@ -4,14 +4,24 @@ require 'yaml'
|
|
|
4
4
|
class SimpleHandler < Mongrel::HttpHandler
|
|
5
5
|
def process(request, response)
|
|
6
6
|
response.start do |head,out|
|
|
7
|
-
head["Content-Type"] = "text/
|
|
8
|
-
out
|
|
7
|
+
head["Content-Type"] = "text/html"
|
|
8
|
+
out << "<html><body>Your request:<br />"
|
|
9
|
+
out << "<pre>#{request.params.to_yaml}</pre>"
|
|
10
|
+
out << "<a href=\"/files\">View the files.</a></body></html>"
|
|
9
11
|
end
|
|
10
12
|
end
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if ARGV.length != 3
|
|
16
|
+
STDERR.puts "usage: simpletest.rb <host> <port> <docroot>"
|
|
17
|
+
exit(1)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
h = Mongrel::HttpServer.new(ARGV[0], ARGV[1])
|
|
21
|
+
h.register("/", SimpleHandler.new)
|
|
22
|
+
h.register("/files", Mongrel::DirHandler.new(ARGV[2]))
|
|
23
|
+
h.run
|
|
24
|
+
|
|
25
|
+
puts "Mongrel running on #{ARGV[0]}:#{ARGV[1]} with docroot #{ARGV[2]}"
|
|
17
26
|
|
|
27
|
+
h.acceptor.join
|
data/ext/http11/http11.c
CHANGED
|
@@ -341,7 +341,9 @@ VALUE URIClassifier_unregister(VALUE self, VALUE uri)
|
|
|
341
341
|
* uc.resolve("/someuri") -> "/someuri", "", handler
|
|
342
342
|
* uc.resolve("/someuri/pathinfo") -> "/someuri", "/pathinfo", handler
|
|
343
343
|
* uc.resolve("/notfound/orhere") -> nil, nil, nil
|
|
344
|
-
*
|
|
344
|
+
* uc.resolve("/") -> "/", "/", handler # if uc.register("/", handler)
|
|
345
|
+
* uc.resolve("/path/from/root") -> "/", "/path/from/root", handler # if uc.register("/", handler)
|
|
346
|
+
*
|
|
345
347
|
* Attempts to resolve either the whole URI or at the longest prefix, returning
|
|
346
348
|
* the prefix (as script_info), path (as path_info), and registered handler
|
|
347
349
|
* (usually an HttpHandler). If it doesn't find a handler registered at the longest
|
|
@@ -358,7 +360,13 @@ VALUE URIClassifier_unregister(VALUE self, VALUE uri)
|
|
|
358
360
|
* It also means that it's very efficient to do this only taking as long as the URI has
|
|
359
361
|
* characters.
|
|
360
362
|
*
|
|
361
|
-
*
|
|
363
|
+
* A slight modification to the CGI 1.2 standard is given for handlers registered to "/".
|
|
364
|
+
* CGI expects all CGI scripts to be at some script path, so it doesn't really say anything
|
|
365
|
+
* about a script that handles the root. To make this work, the resolver will detect that
|
|
366
|
+
* the requested handler is at "/", and return that for script_name, and then simply return
|
|
367
|
+
* the full URI back as path_info.
|
|
368
|
+
*
|
|
369
|
+
* It expects strings with no embedded '\0' characters. Don't try other string-like stuff yet.
|
|
362
370
|
*/
|
|
363
371
|
VALUE URIClassifier_resolve(VALUE self, VALUE uri)
|
|
364
372
|
{
|
|
@@ -379,7 +387,15 @@ VALUE URIClassifier_resolve(VALUE self, VALUE uri)
|
|
|
379
387
|
|
|
380
388
|
if(handler) {
|
|
381
389
|
rb_ary_push(result, rb_str_substr (uri, 0, pref_len));
|
|
382
|
-
|
|
390
|
+
// compensate for a script_name="/" where we need to add the "/" to path_info to keep it consistent
|
|
391
|
+
if(pref_len == 1 && uri_str[0] == '/') {
|
|
392
|
+
// matches the root URI so we have to use the whole URI as the path_info
|
|
393
|
+
rb_ary_push(result, uri);
|
|
394
|
+
} else {
|
|
395
|
+
// matches a script so process like normal
|
|
396
|
+
rb_ary_push(result, rb_str_substr(uri, pref_len, RSTRING(uri)->len));
|
|
397
|
+
}
|
|
398
|
+
|
|
383
399
|
rb_ary_push(result, (VALUE)handler);
|
|
384
400
|
} else {
|
|
385
401
|
// not found so push back nothing
|
data/ext/http11/tst_search.c
CHANGED
|
@@ -32,7 +32,6 @@ void *tst_search(unsigned char *key, struct tst *tst, int *prefix_len)
|
|
|
32
32
|
if(prefix_len) *prefix_len = key_index;
|
|
33
33
|
return current_node->middle;
|
|
34
34
|
} else {
|
|
35
|
-
|
|
36
35
|
current_node = current_node->middle;
|
|
37
36
|
if(current_node && current_node->value == 0) {
|
|
38
37
|
if(prefix_len) *prefix_len = key_index+1;
|
|
@@ -47,7 +46,7 @@ void *tst_search(unsigned char *key, struct tst *tst, int *prefix_len)
|
|
|
47
46
|
((current_node->value != 0) && (key[key_index] <
|
|
48
47
|
current_node->value)) )
|
|
49
48
|
{
|
|
50
|
-
if(current_node->
|
|
49
|
+
if(current_node->value == 0) {
|
|
51
50
|
if(prefix_len) *prefix_len = key_index;
|
|
52
51
|
longest_match = current_node->middle;
|
|
53
52
|
}
|
|
@@ -56,7 +55,7 @@ void *tst_search(unsigned char *key, struct tst *tst, int *prefix_len)
|
|
|
56
55
|
}
|
|
57
56
|
else
|
|
58
57
|
{
|
|
59
|
-
if(current_node->
|
|
58
|
+
if(current_node->value == 0) {
|
|
60
59
|
if(prefix_len) *prefix_len = key_index;
|
|
61
60
|
longest_match = current_node->middle;
|
|
62
61
|
}
|
data/lib/mongrel.rb
CHANGED
|
@@ -51,6 +51,8 @@ module Mongrel
|
|
|
51
51
|
505 => 'HTTP Version not supported'
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
|
|
55
|
+
|
|
54
56
|
# Frequently used constants when constructing requests or responses. Many times
|
|
55
57
|
# the constant just refers to a string with the same contents. Using these constants
|
|
56
58
|
# gave about a 3% to 10% performance improvement over using the strings directly.
|
|
@@ -239,17 +241,29 @@ module Mongrel
|
|
|
239
241
|
@body.rewind
|
|
240
242
|
end
|
|
241
243
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
def send_status
|
|
245
|
+
@socket.write("HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n")
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def send_header
|
|
245
249
|
@header.out.rewind
|
|
250
|
+
@socket.write(@header.out.read)
|
|
251
|
+
@socket.write("\r\n")
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def send_body
|
|
246
255
|
@body.rewind
|
|
247
256
|
|
|
248
257
|
# connection: close is also added to ensure that the client does not pipeline.
|
|
249
|
-
@socket.write("HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n")
|
|
250
|
-
@socket.write(@header.out.read)
|
|
251
|
-
@socket.write("\r\n")
|
|
252
258
|
@socket.write(@body.read)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# This takes whatever has been done to header and body and then writes it in the
|
|
262
|
+
# proper format to make an HTTP/1.1 response.
|
|
263
|
+
def finished
|
|
264
|
+
send_status
|
|
265
|
+
send_header
|
|
266
|
+
send_body
|
|
253
267
|
end
|
|
254
268
|
end
|
|
255
269
|
|
|
@@ -307,9 +321,9 @@ module Mongrel
|
|
|
307
321
|
@req_queue = Queue.new
|
|
308
322
|
@host = host
|
|
309
323
|
@port = port
|
|
310
|
-
@
|
|
324
|
+
@num_processors = num_processors
|
|
311
325
|
|
|
312
|
-
num_processors.times {|i| Thread.new do
|
|
326
|
+
@num_processors.times {|i| Thread.new do
|
|
313
327
|
while client = @req_queue.deq
|
|
314
328
|
process_client(client)
|
|
315
329
|
end
|
|
@@ -338,7 +352,7 @@ module Mongrel
|
|
|
338
352
|
params[Const::PATH_INFO] = path_info
|
|
339
353
|
params[Const::SCRIPT_NAME] = script_name
|
|
340
354
|
params[Const::GATEWAY_INTERFACE]=Const::GATEWAY_INTERFACE_VALUE
|
|
341
|
-
params[Const::REMOTE_ADDR]=client.peeraddr
|
|
355
|
+
params[Const::REMOTE_ADDR]=client.peeraddr[3]
|
|
342
356
|
params[Const::SERVER_NAME]=@host
|
|
343
357
|
params[Const::SERVER_PORT]=@port
|
|
344
358
|
params[Const::SERVER_PROTOCOL]=Const::SERVER_PROTOCOL_VALUE
|
|
@@ -408,7 +422,7 @@ module Mongrel
|
|
|
408
422
|
# Sets the message to return. This is constructed once for the handler
|
|
409
423
|
# so it's pretty efficient.
|
|
410
424
|
def initialize(msg)
|
|
411
|
-
@response =
|
|
425
|
+
@response = Const::ERROR_404_RESPONSE + msg
|
|
412
426
|
end
|
|
413
427
|
|
|
414
428
|
# Just kicks back the standard 404 response with your special message.
|
|
@@ -429,20 +443,76 @@ module Mongrel
|
|
|
429
443
|
# that the final expanded path includes the root path. If it doesn't
|
|
430
444
|
# than it simply gives a 404.
|
|
431
445
|
class DirHandler < HttpHandler
|
|
432
|
-
|
|
433
|
-
|
|
446
|
+
MIME_TYPES = {
|
|
447
|
+
".css" => "text/css",
|
|
448
|
+
".gif" => "image/gif",
|
|
449
|
+
".htm" => "text/html",
|
|
450
|
+
".html" => "text/html",
|
|
451
|
+
".jpeg" => "image/jpeg",
|
|
452
|
+
".jpg" => "image/jpeg",
|
|
453
|
+
".js" => "text/javascript",
|
|
454
|
+
".png" => "image/png",
|
|
455
|
+
".swf" => "application/x-shockwave-flash",
|
|
456
|
+
".txt" => "text/plain"
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
attr_reader :path
|
|
461
|
+
|
|
462
|
+
# You give it the path to the directory root and an (optional)
|
|
463
|
+
def initialize(path, listing_allowed=true, index_html="index.html")
|
|
434
464
|
@path = File.expand_path(path)
|
|
435
465
|
@listing_allowed=listing_allowed
|
|
436
|
-
|
|
466
|
+
@index_html = index_html
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
# Checks if the given path can be served and returns the full path (or nil if not).
|
|
470
|
+
def can_serve(path_info)
|
|
471
|
+
req = File.expand_path(File.join(@path,path_info), @path)
|
|
472
|
+
|
|
473
|
+
if req.index(@path) == 0 and File.exist? req
|
|
474
|
+
# it exists and it's in the right location
|
|
475
|
+
if File.directory? req
|
|
476
|
+
# the request is for a directory
|
|
477
|
+
index = File.join(req, @index_html)
|
|
478
|
+
if File.exist? index
|
|
479
|
+
# serve the index
|
|
480
|
+
return index
|
|
481
|
+
elsif @listing_allows
|
|
482
|
+
# serve the directory
|
|
483
|
+
req
|
|
484
|
+
else
|
|
485
|
+
# do not serve anything
|
|
486
|
+
return nil
|
|
487
|
+
end
|
|
488
|
+
else
|
|
489
|
+
# it's a file and it's there
|
|
490
|
+
return req
|
|
491
|
+
end
|
|
492
|
+
end
|
|
437
493
|
end
|
|
438
494
|
|
|
495
|
+
|
|
496
|
+
# Returns a simplistic directory listing if they're enabled, otherwise a 403.
|
|
497
|
+
# Base is the base URI from the REQUEST_URI, dir is the directory to serve
|
|
498
|
+
# on the file system (comes from can_serve()), and response is the HttpResponse
|
|
499
|
+
# object to send the results on.
|
|
439
500
|
def send_dir_listing(base, dir, response)
|
|
501
|
+
# take off any trailing / so the links come out right
|
|
502
|
+
base.chop! if base[-1] == "/"[-1]
|
|
503
|
+
|
|
440
504
|
if @listing_allowed
|
|
441
505
|
response.start(200) do |head,out|
|
|
442
506
|
head['Content-Type'] = "text/html"
|
|
443
507
|
out << "<html><head><title>Directory Listing</title></head><body>"
|
|
444
508
|
Dir.entries(dir).each do |child|
|
|
445
|
-
|
|
509
|
+
next if child == "."
|
|
510
|
+
|
|
511
|
+
if child == ".."
|
|
512
|
+
out << "<a href=\"#{base}/#{child}\">Up to parent..</a><br/>"
|
|
513
|
+
else
|
|
514
|
+
out << "<a href=\"#{base}/#{child}\">#{child}</a><br/>"
|
|
515
|
+
end
|
|
446
516
|
end
|
|
447
517
|
out << "</body></html>"
|
|
448
518
|
end
|
|
@@ -453,9 +523,20 @@ module Mongrel
|
|
|
453
523
|
end
|
|
454
524
|
end
|
|
455
525
|
|
|
456
|
-
|
|
526
|
+
|
|
527
|
+
# Sends the contents of a file back to the user. Not terribly efficient since it's
|
|
528
|
+
# opening and closing the file for each read.
|
|
457
529
|
def send_file(req, response)
|
|
458
530
|
response.start(200) do |head,out|
|
|
531
|
+
# set the mime type from our map based on the ending
|
|
532
|
+
dot_at = req.rindex(".")
|
|
533
|
+
if dot_at
|
|
534
|
+
ext = req[dot_at .. -1]
|
|
535
|
+
if MIME_TYPES[ext]
|
|
536
|
+
head['Content-Type'] = MIME_TYPES[ext]
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
|
|
459
540
|
open(req, "r") do |f|
|
|
460
541
|
out.write(f.read)
|
|
461
542
|
end
|
|
@@ -463,10 +544,11 @@ module Mongrel
|
|
|
463
544
|
end
|
|
464
545
|
|
|
465
546
|
|
|
547
|
+
# Process the request to either serve a file or a directory listing
|
|
548
|
+
# if allowed (based on the listing_allowed paramter to the constructor).
|
|
466
549
|
def process(request, response)
|
|
467
|
-
req =
|
|
468
|
-
|
|
469
|
-
if req.index(@path) != 0 or !File.exist? req
|
|
550
|
+
req = can_serve request.params['PATH_INFO']
|
|
551
|
+
if not req
|
|
470
552
|
# not found, return a 404
|
|
471
553
|
response.start(404) do |head,out|
|
|
472
554
|
out << "File not found"
|
|
@@ -481,12 +563,18 @@ module Mongrel
|
|
|
481
563
|
rescue => details
|
|
482
564
|
response.reset
|
|
483
565
|
response.start(403) do |head,out|
|
|
484
|
-
out << "Error accessing file"
|
|
566
|
+
out << "Error accessing file: #{details}"
|
|
567
|
+
out << details.backtrace.join("\n")
|
|
485
568
|
end
|
|
486
|
-
STDERR.puts "ERROR: #{details}"
|
|
487
569
|
end
|
|
488
570
|
end
|
|
489
571
|
end
|
|
490
572
|
end
|
|
491
573
|
|
|
574
|
+
|
|
575
|
+
# There is a small number of default mime types for extensions, but
|
|
576
|
+
# this lets you add any others you'll need when serving content.
|
|
577
|
+
def add_mime_type(extension, type)
|
|
578
|
+
MIME_TYPES[extension] = type
|
|
579
|
+
end
|
|
492
580
|
end
|
data/test/test_uriclassifier.rb
CHANGED
|
@@ -115,7 +115,6 @@ class URIClassifierTest < Test::Unit::TestCase
|
|
|
115
115
|
assert_equal 1, h, "wrong result for branching uri"
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
|
|
119
118
|
def test_all_prefixing
|
|
120
119
|
tests = ["/test","/test/that","/test/this"]
|
|
121
120
|
uri = "/test/this/that"
|
|
@@ -151,5 +150,27 @@ class URIClassifierTest < Test::Unit::TestCase
|
|
|
151
150
|
assert_nil sn, "shoulnd't find anything"
|
|
152
151
|
assert_nil pi, "shoulnd't find anything"
|
|
153
152
|
end
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# Verifies that a root mounted ("/") handler resolves
|
|
156
|
+
# such that path info matches the original URI.
|
|
157
|
+
# This is needed to accomodate real usage of handlers.
|
|
158
|
+
def test_root_mounted
|
|
159
|
+
u = URIClassifier.new
|
|
160
|
+
root = "/"
|
|
161
|
+
path = "/this/is/a/test"
|
|
162
|
+
|
|
163
|
+
u.register(root, 1)
|
|
164
|
+
|
|
165
|
+
sn, pi, h = u.resolve(root)
|
|
166
|
+
assert_equal 1,h, "didn't find handler"
|
|
167
|
+
assert_equal root,pi, "didn't get right path info"
|
|
168
|
+
assert_equal root,sn, "didn't get right script name"
|
|
169
|
+
|
|
170
|
+
sn, pi, h = u.resolve(path)
|
|
171
|
+
assert_equal path,pi, "didn't get right path info"
|
|
172
|
+
assert_equal root,sn, "didn't get right script name"
|
|
173
|
+
assert_equal 1,h, "didn't find handler"
|
|
174
|
+
end
|
|
154
175
|
end
|
|
155
176
|
|
metadata
CHANGED
|
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
|
3
3
|
specification_version: 1
|
|
4
4
|
name: mongrel
|
|
5
5
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 0.
|
|
7
|
-
date: 2006-02-
|
|
6
|
+
version: "0.3"
|
|
7
|
+
date: 2006-02-10 00:00:00 -05:00
|
|
8
8
|
summary: An experimental fast simple web server for Ruby.
|
|
9
9
|
require_paths:
|
|
10
10
|
- lib
|
|
@@ -34,6 +34,7 @@ files:
|
|
|
34
34
|
- README
|
|
35
35
|
- Rakefile
|
|
36
36
|
- setup.rb
|
|
37
|
+
- bin/mongrel_rails
|
|
37
38
|
- doc/rdoc
|
|
38
39
|
- doc/rdoc/classes
|
|
39
40
|
- doc/rdoc/created.rid
|
|
@@ -45,6 +46,7 @@ files:
|
|
|
45
46
|
- doc/rdoc/rdoc-style.css
|
|
46
47
|
- doc/rdoc/classes/Mongrel
|
|
47
48
|
- doc/rdoc/classes/Mongrel.html
|
|
49
|
+
- doc/rdoc/classes/Mongrel.src
|
|
48
50
|
- doc/rdoc/classes/Mongrel/Const.html
|
|
49
51
|
- doc/rdoc/classes/Mongrel/DirHandler.html
|
|
50
52
|
- doc/rdoc/classes/Mongrel/DirHandler.src
|
|
@@ -64,36 +66,41 @@ files:
|
|
|
64
66
|
- doc/rdoc/classes/Mongrel/HttpServer.src
|
|
65
67
|
- doc/rdoc/classes/Mongrel/URIClassifier.html
|
|
66
68
|
- doc/rdoc/classes/Mongrel/URIClassifier.src
|
|
67
|
-
- doc/rdoc/classes/Mongrel/DirHandler.src/M000008.html
|
|
68
69
|
- doc/rdoc/classes/Mongrel/DirHandler.src/M000009.html
|
|
69
70
|
- doc/rdoc/classes/Mongrel/DirHandler.src/M000010.html
|
|
70
71
|
- doc/rdoc/classes/Mongrel/DirHandler.src/M000011.html
|
|
71
|
-
- doc/rdoc/classes/Mongrel/
|
|
72
|
-
- doc/rdoc/classes/Mongrel/
|
|
73
|
-
- doc/rdoc/classes/Mongrel/
|
|
74
|
-
- doc/rdoc/classes/Mongrel/
|
|
75
|
-
- doc/rdoc/classes/Mongrel/
|
|
76
|
-
- doc/rdoc/classes/Mongrel/
|
|
72
|
+
- doc/rdoc/classes/Mongrel/DirHandler.src/M000012.html
|
|
73
|
+
- doc/rdoc/classes/Mongrel/DirHandler.src/M000013.html
|
|
74
|
+
- doc/rdoc/classes/Mongrel/Error404Handler.src/M000033.html
|
|
75
|
+
- doc/rdoc/classes/Mongrel/Error404Handler.src/M000034.html
|
|
76
|
+
- doc/rdoc/classes/Mongrel/HeaderOut.src/M000019.html
|
|
77
|
+
- doc/rdoc/classes/Mongrel/HeaderOut.src/M000020.html
|
|
78
|
+
- doc/rdoc/classes/Mongrel/HttpHandler.src/M000025.html
|
|
77
79
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000002.html
|
|
78
80
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000003.html
|
|
79
81
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000004.html
|
|
80
82
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000005.html
|
|
81
83
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000006.html
|
|
82
84
|
- doc/rdoc/classes/Mongrel/HttpParser.src/M000007.html
|
|
83
|
-
- doc/rdoc/classes/Mongrel/
|
|
84
|
-
- doc/rdoc/classes/Mongrel/
|
|
85
|
-
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000025.html
|
|
85
|
+
- doc/rdoc/classes/Mongrel/HttpParser.src/M000008.html
|
|
86
|
+
- doc/rdoc/classes/Mongrel/HttpRequest.src/M000035.html
|
|
86
87
|
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000026.html
|
|
87
88
|
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000027.html
|
|
88
|
-
- doc/rdoc/classes/Mongrel/
|
|
89
|
-
- doc/rdoc/classes/Mongrel/
|
|
89
|
+
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000028.html
|
|
90
|
+
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000029.html
|
|
91
|
+
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000030.html
|
|
92
|
+
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000031.html
|
|
93
|
+
- doc/rdoc/classes/Mongrel/HttpResponse.src/M000032.html
|
|
90
94
|
- doc/rdoc/classes/Mongrel/HttpServer.src/M000014.html
|
|
91
95
|
- doc/rdoc/classes/Mongrel/HttpServer.src/M000015.html
|
|
92
96
|
- doc/rdoc/classes/Mongrel/HttpServer.src/M000016.html
|
|
93
|
-
- doc/rdoc/classes/Mongrel/
|
|
94
|
-
- doc/rdoc/classes/Mongrel/
|
|
97
|
+
- doc/rdoc/classes/Mongrel/HttpServer.src/M000017.html
|
|
98
|
+
- doc/rdoc/classes/Mongrel/HttpServer.src/M000018.html
|
|
95
99
|
- doc/rdoc/classes/Mongrel/URIClassifier.src/M000021.html
|
|
96
100
|
- doc/rdoc/classes/Mongrel/URIClassifier.src/M000022.html
|
|
101
|
+
- doc/rdoc/classes/Mongrel/URIClassifier.src/M000023.html
|
|
102
|
+
- doc/rdoc/classes/Mongrel/URIClassifier.src/M000024.html
|
|
103
|
+
- doc/rdoc/classes/Mongrel.src/M000001.html
|
|
97
104
|
- doc/rdoc/files/COPYING.html
|
|
98
105
|
- doc/rdoc/files/ext
|
|
99
106
|
- doc/rdoc/files/lib
|
|
@@ -106,7 +113,6 @@ files:
|
|
|
106
113
|
- test/test_response.rb
|
|
107
114
|
- test/test_uriclassifier.rb
|
|
108
115
|
- test/test_ws.rb
|
|
109
|
-
- lib/#mongrel.rb#
|
|
110
116
|
- lib/mongrel.rb
|
|
111
117
|
- ext/http11/ext_help.h
|
|
112
118
|
- ext/http11/http11_parser.h
|
|
@@ -131,8 +137,8 @@ rdoc_options: []
|
|
|
131
137
|
|
|
132
138
|
extra_rdoc_files:
|
|
133
139
|
- README
|
|
134
|
-
executables:
|
|
135
|
-
|
|
140
|
+
executables:
|
|
141
|
+
- mongrel_rails
|
|
136
142
|
extensions:
|
|
137
143
|
- ext/http11/extconf.rb
|
|
138
144
|
requirements: []
|