mongrel 0.2.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|