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
@@ -56,7 +56,7 @@
56
56
  </tr>
57
57
  <tr class="top-aligned-row">
58
58
  <td><strong>Last Update:</strong></td>
59
- <td>Fri Feb 03 00:55:27 EST 2006</td>
59
+ <td>Thu Feb 09 21:52:36 EST 2006</td>
60
60
  </tr>
61
61
  </table>
62
62
  </div>
@@ -56,7 +56,7 @@
56
56
  </tr>
57
57
  <tr class="top-aligned-row">
58
58
  <td><strong>Last Update:</strong></td>
59
- <td>Fri Feb 03 00:55:27 EST 2006</td>
59
+ <td>Fri Feb 10 00:03:40 EST 2006</td>
60
60
  </tr>
61
61
  </table>
62
62
  </div>
@@ -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#M000018">[]= (Mongrel::HeaderOut)</a><br />
24
- <a href="classes/Mongrel/HttpParser.html#M000005">error? (Mongrel::HttpParser)</a><br />
25
- <a href="classes/Mongrel/HttpParser.html#M000004">execute (Mongrel::HttpParser)</a><br />
26
- <a href="classes/Mongrel/HttpParser.html#M000003">finish (Mongrel::HttpParser)</a><br />
27
- <a href="classes/Mongrel/HttpResponse.html#M000027">finished (Mongrel::HttpResponse)</a><br />
28
- <a href="classes/Mongrel/HttpParser.html#M000006">finished? (Mongrel::HttpParser)</a><br />
29
- <a href="classes/Mongrel/HttpParser.html#M000001">new (Mongrel::HttpParser)</a><br />
30
- <a href="classes/Mongrel/DirHandler.html#M000008">new (Mongrel::DirHandler)</a><br />
31
- <a href="classes/Mongrel/HttpResponse.html#M000024">new (Mongrel::HttpResponse)</a><br />
32
- <a href="classes/Mongrel/URIClassifier.html#M000019">new (Mongrel::URIClassifier)</a><br />
33
- <a href="classes/Mongrel/Error404Handler.html#M000028">new (Mongrel::Error404Handler)</a><br />
34
- <a href="classes/Mongrel/HttpServer.html#M000012">new (Mongrel::HttpServer)</a><br />
35
- <a href="classes/Mongrel/HeaderOut.html#M000017">new (Mongrel::HeaderOut)</a><br />
36
- <a href="classes/Mongrel/HttpRequest.html#M000030">new (Mongrel::HttpRequest)</a><br />
37
- <a href="classes/Mongrel/HttpParser.html#M000007">nread (Mongrel::HttpParser)</a><br />
38
- <a href="classes/Mongrel/Error404Handler.html#M000029">process (Mongrel::Error404Handler)</a><br />
39
- <a href="classes/Mongrel/DirHandler.html#M000011">process (Mongrel::DirHandler)</a><br />
40
- <a href="classes/Mongrel/HttpHandler.html#M000023">process (Mongrel::HttpHandler)</a><br />
41
- <a href="classes/Mongrel/HttpServer.html#M000013">process_client (Mongrel::HttpServer)</a><br />
42
- <a href="classes/Mongrel/HttpServer.html#M000015">register (Mongrel::HttpServer)</a><br />
43
- <a href="classes/Mongrel/URIClassifier.html#M000020">register (Mongrel::URIClassifier)</a><br />
44
- <a href="classes/Mongrel/HttpResponse.html#M000026">reset (Mongrel::HttpResponse)</a><br />
45
- <a href="classes/Mongrel/HttpParser.html#M000002">reset (Mongrel::HttpParser)</a><br />
46
- <a href="classes/Mongrel/URIClassifier.html#M000022">resolve (Mongrel::URIClassifier)</a><br />
47
- <a href="classes/Mongrel/HttpServer.html#M000014">run (Mongrel::HttpServer)</a><br />
48
- <a href="classes/Mongrel/DirHandler.html#M000009">send_dir_listing (Mongrel::DirHandler)</a><br />
49
- <a href="classes/Mongrel/DirHandler.html#M000010">send_file (Mongrel::DirHandler)</a><br />
50
- <a href="classes/Mongrel/HttpResponse.html#M000025">start (Mongrel::HttpResponse)</a><br />
51
- <a href="classes/Mongrel/URIClassifier.html#M000021">unregister (Mongrel::URIClassifier)</a><br />
52
- <a href="classes/Mongrel/HttpServer.html#M000016">unregister (Mongrel::HttpServer)</a><br />
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>
@@ -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/plain"
8
- out.write("hello!\n")
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
- h = Mongrel::HttpServer.new("0.0.0.0", "3000")
14
- h.register("/test;mystuff;thosestuffs", SimpleHandler.new)
15
- h.register("/files", Mongrel::DirHandler.new("."))
16
- h.run.join
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
@@ -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
- * It expects strings with no embedded '\0' characters. Don't try other string-line stuff yet.
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
- rb_ary_push(result, rb_str_substr(uri, pref_len, RSTRING(uri)->len));
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
@@ -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->left && current_node->value == 0) {
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->right && current_node->value == 0) {
58
+ if(current_node->value == 0) {
60
59
  if(prefix_len) *prefix_len = key_index;
61
60
  longest_match = current_node->middle;
62
61
  }
@@ -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
- # This takes whatever has been done to header and body and then writes it in the
243
- # proper format to make an HTTP/1.1 response.
244
- def finished
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
- @num_procesors = num_processors
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 = HttpServer::ERROR_404_RESPONSE + msg
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
- def initialize(path, listing_allowed=true)
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
- puts "DIR: #@path"
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
- out << "<a href=\"#{base}/#{child}\">#{child}</a><br/>"
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 = File.expand_path("." + request.params['PATH_INFO'], @path)
468
- puts "FIND: #{req}"
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
@@ -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.2.2
7
- date: 2006-02-03 00:00:00 -05:00
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/Error404Handler.src/M000028.html
72
- - doc/rdoc/classes/Mongrel/Error404Handler.src/M000029.html
73
- - doc/rdoc/classes/Mongrel/HeaderOut.src/M000017.html
74
- - doc/rdoc/classes/Mongrel/HeaderOut.src/M000018.html
75
- - doc/rdoc/classes/Mongrel/HttpHandler.src/M000023.html
76
- - doc/rdoc/classes/Mongrel/HttpParser.src/M000001.html
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/HttpRequest.src/M000030.html
84
- - doc/rdoc/classes/Mongrel/HttpResponse.src/M000024.html
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/HttpServer.src/M000012.html
89
- - doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html
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/URIClassifier.src/M000019.html
94
- - doc/rdoc/classes/Mongrel/URIClassifier.src/M000020.html
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: []