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.
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: []