mongrel 0.2.1 → 0.2.2

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 (52) hide show
  1. data/README +10 -2
  2. data/Rakefile +1 -1
  3. data/doc/rdoc/classes/Mongrel.html +11 -1
  4. data/doc/rdoc/classes/Mongrel/Const.html +342 -0
  5. data/doc/rdoc/classes/Mongrel/DirHandler.html +201 -0
  6. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000008.html +20 -0
  7. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000009.html +31 -0
  8. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000010.html +22 -0
  9. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000011.html +39 -0
  10. data/doc/rdoc/classes/Mongrel/Error404Handler.html +10 -10
  11. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000023.html → M000028.html} +4 -4
  12. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000024.html → M000029.html} +4 -4
  13. data/doc/rdoc/classes/Mongrel/HeaderOut.html +28 -10
  14. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000013.html → M000017.html} +4 -4
  15. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000018.html +21 -0
  16. data/doc/rdoc/classes/Mongrel/HttpHandler.html +5 -18
  17. data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000019.html → M000023.html} +3 -3
  18. data/doc/rdoc/classes/Mongrel/HttpRequest.html +8 -8
  19. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000030.html +31 -0
  20. data/doc/rdoc/classes/Mongrel/HttpResponse.html +89 -15
  21. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000020.html → M000024.html} +7 -7
  22. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000021.html → M000025.html} +6 -6
  23. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000026.html +19 -0
  24. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000022.html → M000027.html} +11 -11
  25. data/doc/rdoc/classes/Mongrel/HttpServer.html +32 -76
  26. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000012.html +18 -5
  27. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html +64 -0
  28. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000010.html → M000014.html} +9 -8
  29. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000011.html → M000015.html} +4 -4
  30. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000016.html +18 -0
  31. data/doc/rdoc/classes/Mongrel/URIClassifier.html +25 -23
  32. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000015.html → M000019.html} +0 -0
  33. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000016.html → M000020.html} +3 -2
  34. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000017.html → M000021.html} +0 -0
  35. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000018.html → M000022.html} +1 -1
  36. data/doc/rdoc/created.rid +1 -1
  37. data/doc/rdoc/files/README.html +14 -2
  38. data/doc/rdoc/files/ext/http11/http11_c.html +1 -1
  39. data/doc/rdoc/files/lib/mongrel_rb.html +1 -1
  40. data/doc/rdoc/fr_class_index.html +2 -0
  41. data/doc/rdoc/fr_method_index.html +23 -18
  42. data/examples/simpletest.rb +2 -1
  43. data/ext/http11/http11.c +10 -9
  44. data/ext/http11/http11_parser.c +10 -10
  45. data/ext/http11/http11_parser.h +5 -1
  46. data/lib/#mongrel.rb# +493 -0
  47. data/lib/mongrel.rb +242 -48
  48. metadata +28 -19
  49. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000014.html +0 -21
  50. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000025.html +0 -30
  51. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000008.html +0 -26
  52. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000009.html +0 -58
@@ -8,6 +8,9 @@ require 'stringio'
8
8
  # functionality to service web application requests fast as possible.
9
9
  module Mongrel
10
10
 
11
+ # Every standard HTTP code mapped to the appropriate message. These are
12
+ # used so frequently that they are placed directly in Mongrel for easy
13
+ # access rather than Mongrel::Const.
11
14
  HTTP_STATUS_CODES = {
12
15
  100 => 'Continue',
13
16
  101 => 'Switching Protocols',
@@ -48,19 +51,89 @@ module Mongrel
48
51
  505 => 'HTTP Version not supported'
49
52
  }
50
53
 
54
+ # Frequently used constants when constructing requests or responses. Many times
55
+ # the constant just refers to a string with the same contents. Using these constants
56
+ # gave about a 3% to 10% performance improvement over using the strings directly.
57
+ # Symbols did not really improve things much compared to constants.
58
+ #
59
+ # While Mongrel does try to emulate the CGI/1.2 protocol, it does not use the REMOTE_IDENT,
60
+ # REMOTE_USER, or REMOTE_HOST parameters since those are either a security problem or
61
+ # too taxing on performance.
62
+ module Const
63
+ # This is the part of the path after the SCRIPT_NAME. URIClassifier will determine this.
64
+ PATH_INFO="PATH_INFO"
65
+ # This is the intial part that your handler is identified as by URIClassifier.
66
+ SCRIPT_NAME="SCRIPT_NAME"
67
+ # The original URI requested by the client. Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
68
+ REQUEST_URI='REQUEST_URI'
69
+
70
+ # Content length (also available as HTTP_CONTENT_LENGTH).
71
+ CONTENT_LENGTH='CONTENT_LENGTH'
72
+
73
+ # Content length (also available as CONTENT_LENGTH).
74
+ HTTP_CONTENT_LENGTH='HTTP_CONTENT_LENGTH'
75
+
76
+ # Content type (also available as HTTP_CONTENT_TYPE).
77
+ CONTENT_TYPE='CONTENT_TYPE'
78
+
79
+ # Content type (also available as CONTENT_TYPE).
80
+ HTTP_CONTENT_TYPE='HTTP_CONTENT_TYPE'
81
+
82
+ # Gateway interface key in the HttpRequest parameters.
83
+ GATEWAY_INTERFACE='GATEWAY_INTERFACE'
84
+ # We claim to support CGI/1.2.
85
+ GATEWAY_INTERFACE_VALUE='CGI/1.2'
86
+
87
+ # Hosts remote IP address. Mongrel does not do DNS resolves since that slows
88
+ # processing down considerably.
89
+ REMOTE_ADDR='REMOTE_ADDR'
90
+
91
+ # This is not given since Mongrel does not do DNS resolves. It is only here for
92
+ # completeness for the CGI standard.
93
+ REMOTE_HOST='REMOTE_HOST'
94
+
95
+ # The name/host of our server as given by the HttpServer.new(host,port) call.
96
+ SERVER_NAME='SERVER_NAME'
97
+
98
+ # The port of our server as given by the HttpServer.new(host,port) call.
99
+ SERVER_PORT='SERVER_PORT'
100
+
101
+ # Official server protocol key in the HttpRequest parameters.
102
+ SERVER_PROTOCOL='SERVER_PROTOCOL'
103
+ # Mongrel claims to support HTTP/1.1.
104
+ SERVER_PROTOCOL_VALUE='HTTP/1.1'
105
+
106
+ # The actual server software being used (it's Mongrel man).
107
+ SERVER_SOFTWARE='SERVER_SOFTWARE'
108
+
109
+ # Current Mongrel version (used for SERVER_SOFTWARE and other response headers).
110
+ MONGREL_VERSION='Mongrel 0.2.2'
111
+
112
+ # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
113
+ ERROR_404_RESPONSE="HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: #{MONGREL_VERSION}\r\n\r\nNOT FOUND"
114
+
115
+ # A common header for indicating the server is too busy. Not used yet.
116
+ ERROR_503_RESPONSE="HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY"
117
+
118
+ # The basic max request size we'll try to read.
119
+ CHUNK_SIZE=(16 * 1024)
120
+
121
+ end
122
+
123
+
51
124
  # When a handler is found for a registered URI then this class is constructed
52
125
  # and passed to your HttpHandler::process method. You should assume that
53
126
  # *one* handler processes all requests. Included in the HttpReqeust is a
54
127
  # HttpRequest.params Hash that matches common CGI params, and a HttpRequest.body
55
128
  # which is a string containing the request body (raw for now).
56
129
  #
57
- # Mongrel really only support small-ish request bodies right now since really
130
+ # Mongrel really only supports small-ish request bodies right now since really
58
131
  # huge ones have to be completely read off the wire and put into a string.
59
132
  # Later there will be several options for efficiently handling large file
60
133
  # uploads.
61
134
  class HttpRequest
62
135
  attr_reader :body, :params
63
-
136
+
64
137
  # You don't really call this. It's made for you.
65
138
  # Main thing it does is hook up the params, and store any remaining
66
139
  # body data into the HttpRequest.body attribute.
@@ -68,13 +141,14 @@ module Mongrel
68
141
  @body = initial_body || ""
69
142
  @params = params
70
143
  @socket = socket
71
-
144
+
72
145
  # fix up the CGI requirements
73
- params['CONTENT_LENGTH'] = params['HTTP_CONTENT_LENGTH'] || 0
146
+ params[Const::CONTENT_LENGTH] = params[Const::HTTP_CONTENT_LENGTH] || 0
147
+ params[Const::CONTENT_TYPE] ||= params[Const::HTTP_CONTENT_TYPE]
74
148
 
75
149
  # now, if the initial_body isn't long enough for the content length we have to fill it
76
150
  # TODO: adapt for big ass stuff by writing to a temp file
77
- clen = params['HTTP_CONTENT_LENGTH'].to_i
151
+ clen = params[Const::HTTP_CONTENT_LENGTH].to_i
78
152
  if @body.length < clen
79
153
  @body << @socket.read(clen - @body.length)
80
154
  end
@@ -82,6 +156,13 @@ module Mongrel
82
156
  end
83
157
 
84
158
 
159
+ # This class implements a simple way of constructing the HTTP headers dynamically
160
+ # via a Hash syntax. Think of it as a write-only Hash. Refer to HttpResponse for
161
+ # information on how this is used.
162
+ #
163
+ # One consequence of this write-only nature is that you can write multiple headers
164
+ # by just doing them twice (which is sometimes needed in HTTP), but that the normal
165
+ # semantics for Hash (where doing an insert replaces) is not there.
85
166
  class HeaderOut
86
167
  attr_reader :out
87
168
 
@@ -89,6 +170,7 @@ module Mongrel
89
170
  @out = out
90
171
  end
91
172
 
173
+ # Simply writes "#{key}: #{value}" to an output buffer.
92
174
  def[]=(key,value)
93
175
  @out.write(key)
94
176
  @out.write(": ")
@@ -97,7 +179,35 @@ module Mongrel
97
179
  end
98
180
  end
99
181
 
100
-
182
+ # Writes and controls your response to the client using the HTTP/1.1 specification.
183
+ # You use it by simply doing:
184
+ #
185
+ # response.start(200) do |head,out|
186
+ # head['Content-Type'] = 'text/plain'
187
+ # out.write("hello\n")
188
+ # end
189
+ #
190
+ # The parameter to start is the response code--which Mongrel will translate for you
191
+ # based on HTTP_STATUS_CODES. The head parameter is how you write custom headers.
192
+ # The out parameter is where you write your body. The default status code for
193
+ # HttpResponse.start is 200 so the above example is redundant.
194
+ #
195
+ # As you can see, it's just like using a Hash and as you do this it writes the proper
196
+ # header to the output on the fly. You can even intermix specifying headers and
197
+ # writing content. The HttpResponse class with write the things in the proper order
198
+ # once the HttpResponse.block is ended.
199
+ #
200
+ # You may also work the HttpResponse object directly using the various attributes available
201
+ # for the raw socket, body, header, and status codes. If you do this you're on your own.
202
+ # A design decision was made to force the client to not pipeline requests. HTTP/1.1
203
+ # pipelining really kills the performance due to how it has to be handled and how
204
+ # unclear the standard is. To fix this the HttpResponse gives a "Connection: close"
205
+ # header which forces the client to close right away. The bonus for this is that it
206
+ # gives a pretty nice speed boost to most clients since they can close their connection
207
+ # immediately.
208
+ #
209
+ # One additional caveat is that you don't have to specify the Content-length header
210
+ # as the HttpResponse will write this for you based on the out length.
101
211
  class HttpResponse
102
212
  attr_reader :socket
103
213
  attr_reader :body
@@ -112,12 +222,25 @@ module Mongrel
112
222
  @header = HeaderOut.new(StringIO.new)
113
223
  end
114
224
 
225
+ # Receives a block passing it the header and body for you to work with.
226
+ # When the block is finished it writes everything you've done to
227
+ # the socket in the proper order. This lets you intermix header and
228
+ # body content as needed.
115
229
  def start(status=200)
116
230
  @status = status
117
231
  yield @header, @body
118
232
  finished
119
233
  end
120
-
234
+
235
+ # Primarily used in exception handling to reset the response output in order to write
236
+ # an alternative response.
237
+ def reset
238
+ @header.out.rewind
239
+ @body.rewind
240
+ end
241
+
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.
121
244
  def finished
122
245
  @header.out.rewind
123
246
  @body.rewind
@@ -136,29 +259,8 @@ module Mongrel
136
259
  # a response. Look at the HttpRequest and HttpResponse objects for how
137
260
  # to use them.
138
261
  class HttpHandler
139
- attr_accessor :script_name
140
-
141
- def process(request, response)
142
- end
143
- end
144
-
145
-
146
- # The server normally returns a 404 response if a URI is requested, but it
147
- # also returns a lame empty message. This lets you do a 404 response
148
- # with a custom message for special URIs.
149
- class Error404Handler < HttpHandler
150
-
151
- # Sets the message to return. This is constructed once for the handler
152
- # so it's pretty efficient.
153
- def initialize(msg)
154
- @response = HttpServer::ERROR_404_RESPONSE + msg
155
- end
156
-
157
- # Just kicks back the standard 404 response with your special message.
158
262
  def process(request, response)
159
- response.socket.write(@response)
160
263
  end
161
-
162
264
  end
163
265
 
164
266
 
@@ -183,16 +285,6 @@ module Mongrel
183
285
  class HttpServer
184
286
  attr_reader :acceptor
185
287
 
186
- # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
187
- ERROR_404_RESPONSE="HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Mongrel/0.2\r\n\r\nNOT FOUND"
188
- ERROR_503_RESPONSE="HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY"
189
-
190
- # The basic max request size we'll try to read.
191
- CHUNK_SIZE=(16 * 1024)
192
-
193
- PATH_INFO="PATH_INFO"
194
- SCRIPT_NAME="SCRIPT_NAME"
195
-
196
288
  # Creates a working server on host:port (strange things happen if port isn't a Number).
197
289
  # Use HttpServer::run to start the server.
198
290
  #
@@ -210,8 +302,13 @@ module Mongrel
210
302
  # Future versions of Mongrel will make this more dynamic (hopefully).
211
303
  def initialize(host, port, num_processors=20)
212
304
  @socket = TCPServer.new(host, port)
305
+
213
306
  @classifier = URIClassifier.new
214
307
  @req_queue = Queue.new
308
+ @host = host
309
+ @port = port
310
+ @num_procesors = num_processors
311
+
215
312
  num_processors.times {|i| Thread.new do
216
313
  while client = @req_queue.deq
217
314
  process_client(client)
@@ -223,30 +320,35 @@ module Mongrel
223
320
 
224
321
  # Does the majority of the IO processing. It has been written in Ruby using
225
322
  # about 7 different IO processing strategies and no matter how it's done
226
- # the performance just does not improve. Ruby's use of select to implement
227
- # threads means that it will most likely never improve, so the only remaining
228
- # approach is to write all or some of this function in C. That will be the
229
- # focus of future releases.
323
+ # the performance just does not improve. It is currently carefully constructed
324
+ # to make sure that it gets the best possible performance, but anyone who
325
+ # thinks they can make it faster is more than welcome to take a crack at it.
230
326
  def process_client(client)
231
327
  begin
232
328
  parser = HttpParser.new
233
329
  params = {}
234
- data = client.readpartial(CHUNK_SIZE)
330
+ data = client.readpartial(Const::CHUNK_SIZE)
235
331
 
236
332
  while true
237
333
  nread = parser.execute(params, data)
238
334
  if parser.finished?
239
- script_name, path_info, handler = @classifier.resolve(params[PATH_INFO])
335
+ script_name, path_info, handler = @classifier.resolve(params[Const::REQUEST_URI])
240
336
 
241
337
  if handler
242
- params[PATH_INFO] = path_info
243
- params[SCRIPT_NAME] = script_name
338
+ params[Const::PATH_INFO] = path_info
339
+ params[Const::SCRIPT_NAME] = script_name
340
+ params[Const::GATEWAY_INTERFACE]=Const::GATEWAY_INTERFACE_VALUE
341
+ params[Const::REMOTE_ADDR]=client.peeraddr
342
+ params[Const::SERVER_NAME]=@host
343
+ params[Const::SERVER_PORT]=@port
344
+ params[Const::SERVER_PROTOCOL]=Const::SERVER_PROTOCOL_VALUE
345
+ params[Const::SERVER_SOFTWARE]=Const::MONGREL_VERSION
244
346
 
245
347
  request = HttpRequest.new(params, data[nread ... data.length], client)
246
348
  response = HttpResponse.new(client)
247
349
  handler.process(request, response)
248
350
  else
249
- client.write(ERROR_404_RESPONSE)
351
+ client.write(Const::ERROR_404_RESPONSE)
250
352
  end
251
353
 
252
354
  break
@@ -254,7 +356,7 @@ module Mongrel
254
356
  # gotta stream and read again until we can get the parser to be character safe
255
357
  # TODO: make this more efficient since this means we're parsing a lot repeatedly
256
358
  parser.reset
257
- data << client.readpartial(CHUNK_SIZE)
359
+ data << client.readpartial(Const::CHUNK_SIZE)
258
360
  end
259
361
  end
260
362
  rescue EOFError
@@ -274,6 +376,7 @@ module Mongrel
274
376
  # Runs the thing. It returns the thread used so you can "join" it. You can also
275
377
  # access the HttpServer::acceptor attribute to get the thread later.
276
378
  def run
379
+ BasicSocket.do_not_reverse_lookup=true
277
380
  @acceptor = Thread.new do
278
381
  while true
279
382
  @req_queue << @socket.accept
@@ -295,4 +398,95 @@ module Mongrel
295
398
  @classifier.unregister(uri)
296
399
  end
297
400
  end
401
+
402
+
403
+ # The server normally returns a 404 response if a URI is requested, but it
404
+ # also returns a lame empty message. This lets you do a 404 response
405
+ # with a custom message for special URIs.
406
+ class Error404Handler < HttpHandler
407
+
408
+ # Sets the message to return. This is constructed once for the handler
409
+ # so it's pretty efficient.
410
+ def initialize(msg)
411
+ @response = HttpServer::ERROR_404_RESPONSE + msg
412
+ end
413
+
414
+ # Just kicks back the standard 404 response with your special message.
415
+ def process(request, response)
416
+ response.socket.write(@response)
417
+ end
418
+
419
+ end
420
+
421
+
422
+ # Serves the contents of a directory. You give it the path to the root
423
+ # where the files are located, and it tries to find the files based on
424
+ # the PATH_INFO inside the directory. If the requested path is a
425
+ # directory then it returns a simple directory listing.
426
+ #
427
+ # It does a simple protection against going outside it's root path by
428
+ # converting all paths to an absolute expanded path, and then making sure
429
+ # that the final expanded path includes the root path. If it doesn't
430
+ # than it simply gives a 404.
431
+ class DirHandler < HttpHandler
432
+
433
+ def initialize(path, listing_allowed=true)
434
+ @path = File.expand_path(path)
435
+ @listing_allowed=listing_allowed
436
+ puts "DIR: #@path"
437
+ end
438
+
439
+ def send_dir_listing(base, dir, response)
440
+ if @listing_allowed
441
+ response.start(200) do |head,out|
442
+ head['Content-Type'] = "text/html"
443
+ out << "<html><head><title>Directory Listing</title></head><body>"
444
+ Dir.entries(dir).each do |child|
445
+ out << "<a href=\"#{base}/#{child}\">#{child}</a><br/>"
446
+ end
447
+ out << "</body></html>"
448
+ end
449
+ else
450
+ response.start(403) do |head,out|
451
+ out.write("Directory listings not allowed")
452
+ end
453
+ end
454
+ end
455
+
456
+
457
+ def send_file(req, response)
458
+ response.start(200) do |head,out|
459
+ open(req, "r") do |f|
460
+ out.write(f.read)
461
+ end
462
+ end
463
+ end
464
+
465
+
466
+ 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
470
+ # not found, return a 404
471
+ response.start(404) do |head,out|
472
+ out << "File not found"
473
+ end
474
+ else
475
+ begin
476
+ if File.directory? req
477
+ send_dir_listing(request.params["REQUEST_URI"],req, response)
478
+ else
479
+ send_file(req, response)
480
+ end
481
+ rescue => details
482
+ response.reset
483
+ response.start(403) do |head,out|
484
+ out << "Error accessing file"
485
+ end
486
+ STDERR.puts "ERROR: #{details}"
487
+ end
488
+ end
489
+ end
490
+ end
491
+
298
492
  end
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.1
7
- date: 2006-02-02 00:00:00 -05:00
6
+ version: 0.2.2
7
+ date: 2006-02-03 00:00:00 -05:00
8
8
  summary: An experimental fast simple web server for Ruby.
9
9
  require_paths:
10
10
  - lib
@@ -45,6 +45,9 @@ files:
45
45
  - doc/rdoc/rdoc-style.css
46
46
  - doc/rdoc/classes/Mongrel
47
47
  - doc/rdoc/classes/Mongrel.html
48
+ - doc/rdoc/classes/Mongrel/Const.html
49
+ - doc/rdoc/classes/Mongrel/DirHandler.html
50
+ - doc/rdoc/classes/Mongrel/DirHandler.src
48
51
  - doc/rdoc/classes/Mongrel/Error404Handler.html
49
52
  - doc/rdoc/classes/Mongrel/Error404Handler.src
50
53
  - doc/rdoc/classes/Mongrel/HeaderOut.html
@@ -61,11 +64,15 @@ files:
61
64
  - doc/rdoc/classes/Mongrel/HttpServer.src
62
65
  - doc/rdoc/classes/Mongrel/URIClassifier.html
63
66
  - doc/rdoc/classes/Mongrel/URIClassifier.src
64
- - doc/rdoc/classes/Mongrel/Error404Handler.src/M000023.html
65
- - doc/rdoc/classes/Mongrel/Error404Handler.src/M000024.html
66
- - doc/rdoc/classes/Mongrel/HeaderOut.src/M000013.html
67
- - doc/rdoc/classes/Mongrel/HeaderOut.src/M000014.html
68
- - doc/rdoc/classes/Mongrel/HttpHandler.src/M000019.html
67
+ - doc/rdoc/classes/Mongrel/DirHandler.src/M000008.html
68
+ - doc/rdoc/classes/Mongrel/DirHandler.src/M000009.html
69
+ - doc/rdoc/classes/Mongrel/DirHandler.src/M000010.html
70
+ - 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
69
76
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000001.html
70
77
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000002.html
71
78
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000003.html
@@ -73,19 +80,20 @@ files:
73
80
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000005.html
74
81
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000006.html
75
82
  - doc/rdoc/classes/Mongrel/HttpParser.src/M000007.html
76
- - doc/rdoc/classes/Mongrel/HttpRequest.src/M000025.html
77
- - doc/rdoc/classes/Mongrel/HttpResponse.src/M000020.html
78
- - doc/rdoc/classes/Mongrel/HttpResponse.src/M000021.html
79
- - doc/rdoc/classes/Mongrel/HttpResponse.src/M000022.html
80
- - doc/rdoc/classes/Mongrel/HttpServer.src/M000008.html
81
- - doc/rdoc/classes/Mongrel/HttpServer.src/M000009.html
82
- - doc/rdoc/classes/Mongrel/HttpServer.src/M000010.html
83
- - doc/rdoc/classes/Mongrel/HttpServer.src/M000011.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
86
+ - doc/rdoc/classes/Mongrel/HttpResponse.src/M000026.html
87
+ - doc/rdoc/classes/Mongrel/HttpResponse.src/M000027.html
84
88
  - doc/rdoc/classes/Mongrel/HttpServer.src/M000012.html
85
- - doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html
86
- - doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html
87
- - doc/rdoc/classes/Mongrel/URIClassifier.src/M000017.html
88
- - doc/rdoc/classes/Mongrel/URIClassifier.src/M000018.html
89
+ - doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html
90
+ - doc/rdoc/classes/Mongrel/HttpServer.src/M000014.html
91
+ - doc/rdoc/classes/Mongrel/HttpServer.src/M000015.html
92
+ - 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
95
+ - doc/rdoc/classes/Mongrel/URIClassifier.src/M000021.html
96
+ - doc/rdoc/classes/Mongrel/URIClassifier.src/M000022.html
89
97
  - doc/rdoc/files/COPYING.html
90
98
  - doc/rdoc/files/ext
91
99
  - doc/rdoc/files/lib
@@ -98,6 +106,7 @@ files:
98
106
  - test/test_response.rb
99
107
  - test/test_uriclassifier.rb
100
108
  - test/test_ws.rb
109
+ - lib/#mongrel.rb#
101
110
  - lib/mongrel.rb
102
111
  - ext/http11/ext_help.h
103
112
  - ext/http11/http11_parser.h