mongrel 0.3.13.1 → 0.3.13.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 (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
  #