mongrel 0.3.13.1 → 0.3.13.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. data/Rakefile +3 -1
  2. data/doc/rdoc/classes/Mongrel.html +3 -2
  3. data/doc/rdoc/classes/Mongrel/CGIWrapper.html +49 -49
  4. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000101.html +11 -14
  5. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000102.html +34 -12
  6. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000103.html +21 -5
  7. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000104.html +14 -5
  8. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000105.html +12 -5
  9. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000106.html +5 -6
  10. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000107.html +18 -0
  11. data/doc/rdoc/classes/Mongrel/{URIClassifier.src/M000090.html → CGIWrapper.src/M000108.html} +5 -5
  12. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000109.html +19 -0
  13. data/doc/rdoc/classes/Mongrel/Camping.html +5 -5
  14. data/doc/rdoc/classes/Mongrel/Camping.src/{M000047.html → M000048.html} +0 -0
  15. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.html +10 -10
  16. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000049.html +5 -38
  17. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000050.html +51 -0
  18. data/doc/rdoc/classes/Mongrel/Command/Base.html +65 -65
  19. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000026.html +11 -29
  20. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000027.html +29 -5
  21. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000028.html +5 -5
  22. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000029.html +5 -5
  23. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000030.html +5 -5
  24. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000031.html +5 -9
  25. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000032.html +9 -5
  26. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000033.html +5 -5
  27. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000034.html +5 -5
  28. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000035.html +5 -11
  29. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000036.html +11 -11
  30. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000037.html +11 -5
  31. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000038.html +18 -0
  32. data/doc/rdoc/classes/Mongrel/Command/Registry.html +15 -15
  33. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000039.html +7 -12
  34. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000040.html +12 -37
  35. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000041.html +50 -0
  36. data/doc/rdoc/classes/Mongrel/Configurator.html +120 -114
  37. data/doc/rdoc/classes/Mongrel/Configurator.src/M000110.html +14 -7
  38. data/doc/rdoc/classes/Mongrel/Configurator.src/M000111.html +18 -10
  39. data/doc/rdoc/classes/Mongrel/Configurator.src/M000112.html +7 -5
  40. data/doc/rdoc/classes/Mongrel/Configurator.src/M000113.html +7 -21
  41. data/doc/rdoc/classes/Mongrel/Configurator.src/M000114.html +10 -6
  42. data/doc/rdoc/classes/Mongrel/Configurator.src/M000115.html +5 -17
  43. data/doc/rdoc/classes/Mongrel/Configurator.src/M000116.html +25 -20
  44. data/doc/rdoc/classes/Mongrel/Configurator.src/M000117.html +6 -5
  45. data/doc/rdoc/classes/Mongrel/Configurator.src/M000118.html +17 -11
  46. data/doc/rdoc/classes/Mongrel/Configurator.src/M000119.html +20 -6
  47. data/doc/rdoc/classes/Mongrel/Configurator.src/M000120.html +5 -5
  48. data/doc/rdoc/classes/Mongrel/Configurator.src/M000121.html +11 -9
  49. data/doc/rdoc/classes/Mongrel/Configurator.src/M000122.html +6 -12
  50. data/doc/rdoc/classes/Mongrel/Configurator.src/M000123.html +5 -5
  51. data/doc/rdoc/classes/Mongrel/Configurator.src/M000124.html +9 -22
  52. data/doc/rdoc/classes/Mongrel/Configurator.src/M000125.html +12 -5
  53. data/doc/rdoc/classes/Mongrel/Configurator.src/M000126.html +5 -20
  54. data/doc/rdoc/classes/Mongrel/Configurator.src/M000127.html +22 -5
  55. data/doc/rdoc/classes/Mongrel/Configurator.src/M000128.html +18 -0
  56. data/doc/rdoc/classes/Mongrel/Configurator.src/M000129.html +33 -0
  57. data/doc/rdoc/classes/Mongrel/Configurator.src/M000130.html +18 -0
  58. data/doc/rdoc/classes/Mongrel/Const.html +1 -1
  59. data/doc/rdoc/classes/Mongrel/DeflateFilter.html +10 -10
  60. data/doc/rdoc/classes/Mongrel/DeflateFilter.src/{M000096.html → M000099.html} +5 -5
  61. data/doc/rdoc/classes/Mongrel/DeflateFilter.src/{M000097.html → M000100.html} +14 -14
  62. data/doc/rdoc/classes/Mongrel/DirHandler.html +31 -31
  63. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000058.html +8 -30
  64. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000059.html +30 -29
  65. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000060.html +29 -50
  66. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000061.html +50 -26
  67. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000062.html +26 -5
  68. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000063.html +18 -0
  69. data/doc/rdoc/classes/Mongrel/Error404Handler.html +10 -10
  70. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000128.html → M000131.html} +4 -4
  71. data/doc/rdoc/classes/Mongrel/Error404Handler.src/{M000129.html → M000132.html} +4 -4
  72. data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
  73. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000070.html → M000072.html} +4 -4
  74. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000071.html → M000073.html} +4 -4
  75. data/doc/rdoc/classes/Mongrel/HttpHandler.html +31 -10
  76. data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000076.html → M000078.html} +0 -0
  77. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000079.html +17 -0
  78. data/doc/rdoc/classes/Mongrel/HttpHandler.src/{M000077.html → M000080.html} +3 -3
  79. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.html +25 -10
  80. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000022.html +3 -3
  81. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000023.html +4 -6
  82. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000024.html +6 -4
  83. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000025.html +17 -0
  84. data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
  85. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000051.html +5 -6
  86. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000052.html +7 -7
  87. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000053.html +7 -37
  88. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000054.html +37 -5
  89. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000055.html +5 -5
  90. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000056.html +5 -6
  91. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000050.html → M000057.html} +6 -6
  92. data/doc/rdoc/classes/Mongrel/HttpRequest.html +30 -21
  93. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000138.html +43 -19
  94. data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000136.html → M000139.html} +6 -6
  95. data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000137.html → M000140.html} +6 -6
  96. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000141.html +32 -0
  97. data/doc/rdoc/classes/Mongrel/HttpResponse.html +61 -61
  98. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000081.html +12 -9
  99. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000082.html +7 -9
  100. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000083.html +12 -9
  101. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000084.html +9 -18
  102. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000085.html +9 -8
  103. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000086.html +9 -7
  104. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000087.html +18 -7
  105. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000088.html +8 -7
  106. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000089.html +7 -5
  107. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000090.html +20 -0
  108. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000091.html +20 -0
  109. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000092.html +18 -0
  110. data/doc/rdoc/classes/Mongrel/HttpServer.html +63 -41
  111. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000064.html +12 -76
  112. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000065.html +74 -13
  113. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000066.html +18 -50
  114. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000067.html +8 -21
  115. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000068.html +38 -5
  116. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000069.html +21 -9
  117. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000070.html +18 -0
  118. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000071.html +22 -0
  119. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.html +15 -15
  120. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000042.html +26 -12
  121. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000043.html +12 -13
  122. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000044.html +26 -0
  123. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.html +15 -15
  124. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000045.html +9 -38
  125. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000046.html +38 -10
  126. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000047.html +23 -0
  127. data/doc/rdoc/classes/Mongrel/RedirectHandler.html +10 -10
  128. data/doc/rdoc/classes/Mongrel/RedirectHandler.src/{M000133.html → M000136.html} +8 -8
  129. data/doc/rdoc/classes/Mongrel/RedirectHandler.src/{M000134.html → M000137.html} +13 -13
  130. data/doc/rdoc/classes/Mongrel/StatisticsFilter.html +16 -16
  131. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/{M000130.html → M000133.html} +10 -10
  132. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/{M000131.html → M000134.html} +10 -10
  133. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/{M000132.html → M000135.html} +4 -4
  134. data/doc/rdoc/classes/Mongrel/StatusHandler.html +20 -20
  135. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000074.html +5 -29
  136. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000075.html +11 -7
  137. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000076.html +42 -0
  138. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000077.html +20 -0
  139. data/doc/rdoc/classes/Mongrel/TimeoutError.html +117 -0
  140. data/doc/rdoc/classes/Mongrel/URIClassifier.html +30 -30
  141. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000093.html +5 -38
  142. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000094.html +5 -23
  143. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000095.html +16 -60
  144. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000096.html +51 -0
  145. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000097.html +36 -0
  146. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000098.html +83 -0
  147. data/doc/rdoc/classes/RequestLog/Access.html +5 -5
  148. data/doc/rdoc/classes/RequestLog/Access.src/{M000139.html → M000142.html} +0 -0
  149. data/doc/rdoc/classes/RequestLog/Files.html +5 -5
  150. data/doc/rdoc/classes/RequestLog/Files.src/{M000140.html → M000143.html} +0 -0
  151. data/doc/rdoc/classes/RequestLog/Objects.html +5 -5
  152. data/doc/rdoc/classes/RequestLog/Objects.src/{M000142.html → M000145.html} +0 -0
  153. data/doc/rdoc/classes/RequestLog/Params.html +5 -5
  154. data/doc/rdoc/classes/RequestLog/Params.src/{M000143.html → M000146.html} +0 -0
  155. data/doc/rdoc/classes/RequestLog/Threads.html +5 -5
  156. data/doc/rdoc/classes/RequestLog/Threads.src/{M000141.html → M000144.html} +0 -0
  157. data/doc/rdoc/created.rid +1 -1
  158. data/doc/rdoc/files/ext/http11/http11_c.html +1 -1
  159. data/doc/rdoc/files/lib/mongrel/camping_rb.html +2 -2
  160. data/doc/rdoc/files/lib/mongrel/cgi_rb.html +2 -2
  161. data/doc/rdoc/files/lib/mongrel/command_rb.html +2 -2
  162. data/doc/rdoc/files/lib/mongrel/debug_rb.html +2 -2
  163. data/doc/rdoc/files/lib/mongrel/handlers_rb.html +1 -1
  164. data/doc/rdoc/files/lib/mongrel/init_rb.html +2 -2
  165. data/doc/rdoc/files/lib/mongrel/rails_rb.html +2 -2
  166. data/doc/rdoc/files/lib/mongrel/stats_rb.html +2 -2
  167. data/doc/rdoc/files/lib/mongrel/tcphack_rb.html +2 -2
  168. data/doc/rdoc/files/lib/mongrel_rb.html +2 -2
  169. data/doc/rdoc/fr_class_index.html +1 -0
  170. data/doc/rdoc/fr_method_index.html +125 -122
  171. data/ext/http11/http11.c +2 -2
  172. data/ext/http11/http11_parser.c +1 -1
  173. data/ext/http11/http11_parser.h +1 -1
  174. data/lib/mongrel.rb +70 -53
  175. data/lib/mongrel/camping.rb +1 -1
  176. data/lib/mongrel/cgi.rb +1 -1
  177. data/lib/mongrel/command.rb +1 -1
  178. data/lib/mongrel/debug.rb +1 -1
  179. data/lib/mongrel/handlers.rb +10 -1
  180. data/lib/mongrel/init.rb +1 -1
  181. data/lib/mongrel/rails.rb +1 -1
  182. data/lib/mongrel/stats.rb +1 -1
  183. data/lib/mongrel/tcphack.rb +1 -1
  184. data/test/test_command.rb +1 -1
  185. data/test/test_conditional.rb +1 -1
  186. data/test/test_configurator.rb +1 -1
  187. data/test/test_debug.rb +1 -1
  188. data/test/test_handlers.rb +1 -1
  189. data/test/test_http11.rb +1 -1
  190. data/test/test_response.rb +1 -1
  191. data/test/test_stats.rb +1 -1
  192. data/test/test_uriclassifier.rb +1 -1
  193. data/test/test_ws.rb +1 -1
  194. data/tools/trickletest.rb +28 -20
  195. metadata +50 -46
  196. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000098.html +0 -24
  197. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000099.html +0 -47
  198. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000100.html +0 -34
  199. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000048.html +0 -18
  200. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000025.html +0 -24
  201. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000038.html +0 -20
  202. data/doc/rdoc/classes/Mongrel/Configurator.src/M000107.html +0 -29
  203. data/doc/rdoc/classes/Mongrel/Configurator.src/M000108.html +0 -31
  204. data/doc/rdoc/classes/Mongrel/Configurator.src/M000109.html +0 -20
  205. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000057.html +0 -21
  206. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000135.html +0 -52
  207. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000078.html +0 -25
  208. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000079.html +0 -20
  209. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000080.html +0 -25
  210. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000063.html +0 -25
  211. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000041.html +0 -39
  212. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000044.html +0 -22
  213. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000072.html +0 -18
  214. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000073.html +0 -24
  215. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000091.html +0 -18
  216. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000092.html +0 -39
@@ -1,4 +1,4 @@
1
- /* Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ /* Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  *
3
3
  * Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  *
@@ -554,7 +554,7 @@ void Init_http11()
554
554
  DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
555
555
  DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
556
556
  DEF_GLOBAL(http_host, "HTTP_HOST");
557
- DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.1");
557
+ DEF_GLOBAL(mongrel_version, "Mongrel 0.3.13.2");
558
558
  DEF_GLOBAL(server_software, "SERVER_SOFTWARE");
559
559
  DEF_GLOBAL(port_80, "80");
560
560
 
@@ -1,5 +1,5 @@
1
1
  #line 1 "ext/http11/http11_parser.rl"
2
- /* Mongrel Web Server - A Mostly Ruby Webserver and Library
2
+ /* Mongrel Web Server - A Mostly Ruby HTTP server and Library
3
3
  *
4
4
  * Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
5
5
  *
@@ -1,4 +1,4 @@
1
- /* Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ /* Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  *
3
3
  * Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  *
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -28,8 +28,7 @@ require 'mongrel/tcphack'
28
28
  require 'yaml'
29
29
  require 'time'
30
30
  require 'rubygems'
31
- require 'etc'
32
-
31
+ require 'etc'
33
32
 
34
33
  begin
35
34
  require 'sendfile'
@@ -62,8 +61,10 @@ module Mongrel
62
61
 
63
62
 
64
63
  # Used to stop the HttpServer via Thread.raise.
65
- class StopServer < Exception
66
- end
64
+ class StopServer < Exception; end
65
+
66
+ # Thrown at a thread when it is timed out.
67
+ class TimeoutError < Exception; end
67
68
 
68
69
 
69
70
  # Every standard HTTP code mapped to the appropriate message. These are
@@ -131,7 +132,7 @@ module Mongrel
131
132
  # The original URI requested by the client. Passed to URIClassifier to build PATH_INFO and SCRIPT_NAME.
132
133
  REQUEST_URI='REQUEST_URI'.freeze
133
134
 
134
- MONGREL_VERSION="0.3.13.1".freeze
135
+ MONGREL_VERSION="0.3.13.2".freeze
135
136
 
136
137
  # TODO: this use of a base for tempfiles needs to be looked at for security problems
137
138
  MONGREL_TMP_BASE="mongrel".freeze
@@ -183,7 +184,12 @@ module Mongrel
183
184
  #
184
185
  # The HttpRequest.initialize method will convert any request that is larger than
185
186
  # Const::MAX_BODY into a Tempfile and use that as the body. Otherwise it uses
186
- # a StringIO object. To be safe, you should assume it works like a file.
187
+ # a StringIO object. To be safe, you should assume it works like a file.
188
+ #
189
+ # The HttpHandler.request_notify system is implemented by having HttpRequest call
190
+ # HttpHandler.request_begins, HttpHandler.request_progress, HttpHandler.process during
191
+ # the IO processing. This adds a small amount of overhead but lets you implement
192
+ # finer controlled handlers and filters.
187
193
  class HttpRequest
188
194
  attr_reader :body, :params
189
195
 
@@ -192,11 +198,12 @@ module Mongrel
192
198
  # body data into the HttpRequest.body attribute.
193
199
  #
194
200
  # TODO: Implement tempfile removal when the request is done.
195
- def initialize(params, initial_body, socket)
201
+ def initialize(params, initial_body, socket, notifier)
196
202
  @params = params
197
203
  @socket = socket
198
204
 
199
205
  clen = params[Const::CONTENT_LENGTH].to_i - initial_body.length
206
+ total = clen
200
207
 
201
208
  if clen > Const::MAX_BODY
202
209
  @body = Tempfile.new(Const::MONGREL_TMP_BASE)
@@ -207,24 +214,27 @@ module Mongrel
207
214
 
208
215
  begin
209
216
  @body.write(initial_body)
217
+ notifier.request_begins(params) if notifier
210
218
 
211
219
  # write the odd sized chunk first
212
220
  clen -= @body.write(@socket.read(clen % Const::CHUNK_SIZE))
221
+ notifier.request_progress(params, clen, total) if notifier
213
222
 
214
223
  # then stream out nothing but perfectly sized chunks
215
- while clen > 0
224
+ while clen > 0 and !@socket.closed?
216
225
  data = @socket.read(Const::CHUNK_SIZE)
217
226
  # have to do it this way since @socket.eof? causes it to block
218
227
  raise "Socket closed or read failure" if not data or data.length != Const::CHUNK_SIZE
219
228
  clen -= @body.write(data)
220
229
  # ASSUME: we are writing to a disk and these writes always write the requested amount
230
+ notifier.request_progress(params, clen, total) if notifier
221
231
  end
222
232
 
223
233
  # rewind to keep the world happy
224
234
  @body.rewind
225
235
  rescue Object
226
236
  # any errors means we should delete the file, including if the file is dumped
227
- STDERR.puts "Error reading request: #$!"
237
+ @socket.close unless @socket.closed?
228
238
  @body.delete if @body.class == Tempfile
229
239
  @body = nil # signals that there was a problem
230
240
  end
@@ -454,7 +464,7 @@ module Mongrel
454
464
 
455
465
  end
456
466
 
457
- # This is the main driver of Mongrel, while the Mognrel::HttpParser and Mongrel::URIClassifier
467
+ # This is the main driver of Mongrel, while the Mongrel::HttpParser and Mongrel::URIClassifier
458
468
  # make up the majority of how the server functions. It's a very simple class that just
459
469
  # has a thread accepting connections and a simple HttpServer.process_client function
460
470
  # to do the heavy lifting with the IO and Ruby.
@@ -517,7 +527,7 @@ module Mongrel
517
527
  begin
518
528
  parser = HttpParser.new
519
529
  params = {}
520
-
530
+ request = nil
521
531
  data = client.readpartial(Const::CHUNK_SIZE)
522
532
  nparsed = 0
523
533
 
@@ -535,15 +545,12 @@ module Mongrel
535
545
  params[Const::PATH_INFO] = path_info
536
546
  params[Const::SCRIPT_NAME] = script_name
537
547
  params[Const::REMOTE_ADDR] = params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last
538
- data = data[nparsed ... data.length] || ""
539
-
540
- if handlers[0].request_notify
541
- # this first handler wants to be notified when the process starts
542
- handlers[0].request_begins(params)
543
- end
548
+ notifier = handlers[0].request_notify ? handlers[0] : nil
544
549
 
545
550
  # TODO: Find a faster/better way to carve out the range, preferably without copying.
546
- request = HttpRequest.new(params, data, client)
551
+ data = data[nparsed ... data.length] || ""
552
+
553
+ request = HttpRequest.new(params, data, client, notifier)
547
554
 
548
555
  # in the case of large file uploads the user could close the socket, so skip those requests
549
556
  break if request.body == nil # nil signals from HttpRequest::initialize that the request was aborted
@@ -563,7 +570,6 @@ module Mongrel
563
570
  end
564
571
  else
565
572
  # Didn't find it, return a stock 404 response.
566
- # TODO: Implement customer 404 files (but really they should use a real web server).
567
573
  client.write(Const::ERROR_404_RESPONSE)
568
574
  end
569
575
 
@@ -580,27 +586,46 @@ module Mongrel
580
586
  # ignored
581
587
  rescue HttpParserError
582
588
  STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
583
- rescue => details
589
+ rescue Errno::EMFILE
590
+ reap_dead_workers('too many files')
591
+ rescue Object
584
592
  STDERR.puts "#{Time.now}: ERROR: #$!"
585
- STDERR.puts details.backtrace.join("\n")
586
593
  ensure
587
594
  client.close unless client.closed?
595
+ request.body.delete if request and request.body.class == Tempfile
588
596
  end
589
597
  end
590
598
 
591
599
  # Used internally to kill off any worker threads that have taken too long
592
600
  # to complete processing. Only called if there are too many processors
593
- # currently servicing.
594
- def reap_dead_workers(worker_list)
595
- mark = Time.now
596
- worker_list.each do |w|
597
- w[:started_on] = Time.now if not w[:started_on]
598
-
599
- if mark - w[:started_on] > @death_time + @timeout
600
- STDERR.puts "Thread #{w.inspect} is too old, killing."
601
- w.raise(StopServer.new("Timed out thread."))
601
+ # currently servicing. It returns the count of workers still active
602
+ # after the reap is done. It only runs if there are workers to reap.
603
+ def reap_dead_workers(reason='unknown')
604
+ if @workers.list.length > 0
605
+ STDERR.puts "#{Time.now}: Reaping #{@workers.list.length} threads for slow workers because of '#{reason}'"
606
+ mark = Time.now
607
+ @workers.list.each do |w|
608
+ w[:started_on] = Time.now if not w[:started_on]
609
+
610
+ if mark - w[:started_on] > @death_time + @timeout
611
+ STDERR.puts "Thread #{w.inspect} is too old, killing."
612
+ w.raise(TimeoutError.new("Timed out thread."))
613
+ end
602
614
  end
603
615
  end
616
+
617
+ return @workers.list.length
618
+ end
619
+
620
+ # Performs a wait on all the currently running threads and kills any that take
621
+ # too long. Right now it just waits 60 seconds, but will expand this to
622
+ # allow setting. The @timeout setting does extend this waiting period by
623
+ # that much longer.
624
+ def graceful_shutdown
625
+ while reap_dead_workers("shutdown") > 0
626
+ STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@death_time + @timeout} seconds."
627
+ sleep @death_time / 10
628
+ end
604
629
  end
605
630
 
606
631
 
@@ -618,14 +643,12 @@ module Mongrel
618
643
  if worker_list.length >= @num_processors
619
644
  STDERR.puts "Server overloaded with #{worker_list.length} processors (#@num_processors max). Dropping connection."
620
645
  client.close
621
- reap_dead_workers(worker_list)
646
+ reap_dead_workers("max processors")
622
647
  else
623
- thread = Thread.new do
624
- process_client(client)
625
- end
648
+ thread = Thread.new { process_client(client) }
626
649
 
650
+ thread.abort_on_exception = true
627
651
  thread[:started_on] = Time.now
628
- thread.priority=1
629
652
  @workers.add(thread)
630
653
 
631
654
  sleep @timeout/100 if @timeout > 0
@@ -634,22 +657,12 @@ module Mongrel
634
657
  @socket.close if not @socket.closed?
635
658
  break
636
659
  rescue Errno::EMFILE
637
- STDERR.puts "Too many open files. Try increasing ulimits."
660
+ reap_dead_workers("too many open files")
638
661
  sleep 0.5
639
662
  end
640
663
  end
641
664
 
642
- # troll through the threads that are waiting and kill any that take too long
643
- # TODO: Allow for death time to be set if people ask for it.
644
- @death_time = 10
645
- shutdown_start = Time.now
646
-
647
- while @workers.list.length > 0
648
- waited_for = (Time.now - shutdown_start).ceil
649
- STDERR.print "Shutdown waited #{waited_for} for #{@workers.list.length} requests, could take #{@death_time + @timeout} seconds.\r" if @workers.list.length > 0
650
- sleep 1
651
- reap_dead_workers(@workers.list)
652
- end
665
+ graceful_shutdown
653
666
  end
654
667
 
655
668
  return @acceptor
@@ -746,8 +759,6 @@ module Mongrel
746
759
  @needs_restart = false
747
760
  @pid_file = defaults[:pid_file]
748
761
 
749
- change_privilege(@defaults[:user], @defaults[:group])
750
-
751
762
  if blk
752
763
  cloaker(&blk).bind(self).call
753
764
  end
@@ -812,6 +823,8 @@ module Mongrel
812
823
  # * :port => Port to bind.
813
824
  # * :num_processors => The maximum number of concurrent threads allowed. (950 default)
814
825
  # * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout)
826
+ # * :user => User to change to, must have :group as well.
827
+ # * :group => Group to change to, must have :user as well.
815
828
  #
816
829
  def listener(options={},&blk)
817
830
  raise "Cannot call listener inside another listener block." if (@listener or @listener_name)
@@ -823,6 +836,10 @@ module Mongrel
823
836
  @listener_name = "#{ops[:host]}:#{ops[:port]}"
824
837
  @listeners[@listener_name] = @listener
825
838
 
839
+ if ops[:user] and ops[:group]
840
+ change_privilege(ops[:user], ops[:group])
841
+ end
842
+
826
843
  # Does the actual cloaking operation to give the new implicit self.
827
844
  if blk
828
845
  cloaker(&blk).bind(self).call
@@ -972,7 +989,7 @@ module Mongrel
972
989
 
973
990
 
974
991
  # This method should actually be called *outside* of the
975
- # Configurator block so that you can control it. In otherwords
992
+ # Configurator block so that you can control it. In other words
976
993
  # do it like: config.join.
977
994
  def join
978
995
  @listeners.values.each {|s| s.acceptor.join }
@@ -991,9 +1008,9 @@ module Mongrel
991
1008
  # debug "/", what = [:rails]
992
1009
  #
993
1010
  # And it will only produce the log/mongrel_debug/rails.log file.
994
- # Available options are: :object, :railes, :files, :threads, :params
1011
+ # Available options are: :object, :rails, :files, :threads, :params
995
1012
  #
996
- # NOTE: Use [:files] to get acccesses dumped to stderr like with WEBrick.
1013
+ # NOTE: Use [:files] to get accesses dumped to stderr like with WEBrick.
997
1014
  def debug(location, what = [:object, :rails, :files, :threads, :params])
998
1015
  require 'mongrel/debug'
999
1016
  handlers = {
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,7 +1,7 @@
1
1
  require 'mongrel/stats'
2
2
  require 'zlib'
3
3
 
4
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
4
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
5
5
  #
6
6
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
7
7
  #
@@ -41,6 +41,12 @@ module Mongrel
41
41
  def request_begins(params)
42
42
  end
43
43
 
44
+ # Called by Mongrel for each IO chunk that is received on the request socket
45
+ # from the client, allowing you to track the progress of the IO and monitor
46
+ # the input.
47
+ def request_progress(params, clen, total)
48
+ end
49
+
44
50
  def process(request, response)
45
51
  end
46
52
 
@@ -59,6 +65,9 @@ module Mongrel
59
65
  def request_begins(params)
60
66
  end
61
67
 
68
+ def request_progress(params, clen, total)
69
+ end
70
+
62
71
  def initialize(options={})
63
72
  @options = options
64
73
  @header_only = false
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #
@@ -1,4 +1,4 @@
1
- # Mongrel Web Server - A Mostly Ruby Webserver and Library
1
+ # Mongrel Web Server - A Mostly Ruby HTTP server and Library
2
2
  #
3
3
  # Copyright (C) 2005 Zed A. Shaw zedshaw AT zedshaw dot com
4
4
  #