mongrel 1.0.1 → 1.0.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 (263) hide show
  1. data.tar.gz.sig +2 -0
  2. data/CHANGELOG +2 -0
  3. data/Manifest +68 -0
  4. data/bin/mongrel_rails +55 -22
  5. data/examples/camping/README +3 -0
  6. data/examples/httpd.conf +474 -0
  7. data/examples/mime.yaml +3 -0
  8. data/examples/mongrel.conf +9 -0
  9. data/examples/monitrc +57 -0
  10. data/ext/http11/http11.c +25 -12
  11. data/ext/http11/http11_parser.c +456 -331
  12. data/ext/http11/http11_parser.h +1 -0
  13. data/ext/http11/http11_parser.java.rl +170 -0
  14. data/ext/http11/http11_parser.rl +8 -48
  15. data/ext/http11/http11_parser_common.rl +54 -0
  16. data/ext/http11/tst.h +2 -2
  17. data/ext/http11/tst_cleanup.c +0 -1
  18. data/ext/http11/tst_insert.c +29 -3
  19. data/ext/http11/tst_search.c +60 -55
  20. data/lib/mongrel.rb +68 -53
  21. data/lib/mongrel/cgi.rb +3 -3
  22. data/lib/mongrel/command.rb +1 -1
  23. data/lib/mongrel/configurator.rb +41 -31
  24. data/lib/mongrel/debug.rb +2 -5
  25. data/lib/mongrel/handlers.rb +23 -9
  26. data/lib/mongrel/mime_types.yml +2 -1
  27. data/lib/mongrel/rails.rb +7 -15
  28. data/mongrel-public_cert.pem +20 -0
  29. data/mongrel.gemspec +211 -0
  30. data/test/jruby_socket.rb +39 -0
  31. data/test/test_cgi_wrapper.rb +26 -0
  32. data/test/test_command.rb +1 -4
  33. data/test/test_conditional.rb +6 -18
  34. data/test/test_configurator.rb +5 -8
  35. data/test/test_debug.rb +3 -11
  36. data/test/test_handlers.rb +8 -10
  37. data/test/test_http11.rb +24 -5
  38. data/test/test_redirect_handler.rb +2 -6
  39. data/test/test_request_progress.rb +5 -9
  40. data/test/test_response.rb +24 -3
  41. data/test/test_stats.rb +1 -3
  42. data/test/test_uriclassifier.rb +170 -81
  43. data/test/test_ws.rb +25 -24
  44. data/test/testhelp.rb +26 -3
  45. data/tools/trickletest.rb +2 -2
  46. metadata +138 -333
  47. metadata.gz.sig +0 -0
  48. data/Rakefile +0 -117
  49. data/doc/rdoc/classes/IO.html +0 -170
  50. data/doc/rdoc/classes/IO.src/M000003.html +0 -19
  51. data/doc/rdoc/classes/IO.src/M000004.html +0 -19
  52. data/doc/rdoc/classes/Kernel.html +0 -159
  53. data/doc/rdoc/classes/Kernel.src/M000012.html +0 -19
  54. data/doc/rdoc/classes/Kernel.src/M000013.html +0 -23
  55. data/doc/rdoc/classes/Mongrel.html +0 -204
  56. data/doc/rdoc/classes/Mongrel/CGIWrapper.html +0 -404
  57. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000115.html +0 -25
  58. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000116.html +0 -47
  59. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000117.html +0 -34
  60. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000118.html +0 -32
  61. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000119.html +0 -25
  62. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000120.html +0 -18
  63. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000121.html +0 -18
  64. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000122.html +0 -18
  65. data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000123.html +0 -19
  66. data/doc/rdoc/classes/Mongrel/Camping.html +0 -177
  67. data/doc/rdoc/classes/Mongrel/Camping.src/M000041.html +0 -22
  68. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.html +0 -184
  69. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000042.html +0 -20
  70. data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000043.html +0 -58
  71. data/doc/rdoc/classes/Mongrel/Command.html +0 -132
  72. data/doc/rdoc/classes/Mongrel/Command/Base.html +0 -384
  73. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000018.html +0 -24
  74. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000019.html +0 -42
  75. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000020.html +0 -18
  76. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000021.html +0 -18
  77. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000022.html +0 -18
  78. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000023.html +0 -18
  79. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000024.html +0 -22
  80. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000025.html +0 -18
  81. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000026.html +0 -18
  82. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000027.html +0 -18
  83. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000028.html +0 -24
  84. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000029.html +0 -24
  85. data/doc/rdoc/classes/Mongrel/Command/Base.src/M000030.html +0 -18
  86. data/doc/rdoc/classes/Mongrel/Command/Registry.html +0 -192
  87. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000031.html +0 -20
  88. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000032.html +0 -29
  89. data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000033.html +0 -58
  90. data/doc/rdoc/classes/Mongrel/Configurator.html +0 -716
  91. data/doc/rdoc/classes/Mongrel/Configurator.src/M000093.html +0 -27
  92. data/doc/rdoc/classes/Mongrel/Configurator.src/M000094.html +0 -31
  93. data/doc/rdoc/classes/Mongrel/Configurator.src/M000095.html +0 -18
  94. data/doc/rdoc/classes/Mongrel/Configurator.src/M000096.html +0 -21
  95. data/doc/rdoc/classes/Mongrel/Configurator.src/M000097.html +0 -20
  96. data/doc/rdoc/classes/Mongrel/Configurator.src/M000098.html +0 -23
  97. data/doc/rdoc/classes/Mongrel/Configurator.src/M000099.html +0 -18
  98. data/doc/rdoc/classes/Mongrel/Configurator.src/M000100.html +0 -38
  99. data/doc/rdoc/classes/Mongrel/Configurator.src/M000101.html +0 -19
  100. data/doc/rdoc/classes/Mongrel/Configurator.src/M000102.html +0 -39
  101. data/doc/rdoc/classes/Mongrel/Configurator.src/M000103.html +0 -33
  102. data/doc/rdoc/classes/Mongrel/Configurator.src/M000104.html +0 -18
  103. data/doc/rdoc/classes/Mongrel/Configurator.src/M000105.html +0 -24
  104. data/doc/rdoc/classes/Mongrel/Configurator.src/M000106.html +0 -19
  105. data/doc/rdoc/classes/Mongrel/Configurator.src/M000107.html +0 -18
  106. data/doc/rdoc/classes/Mongrel/Configurator.src/M000108.html +0 -22
  107. data/doc/rdoc/classes/Mongrel/Configurator.src/M000109.html +0 -22
  108. data/doc/rdoc/classes/Mongrel/Configurator.src/M000110.html +0 -18
  109. data/doc/rdoc/classes/Mongrel/Configurator.src/M000111.html +0 -34
  110. data/doc/rdoc/classes/Mongrel/Configurator.src/M000112.html +0 -18
  111. data/doc/rdoc/classes/Mongrel/Configurator.src/M000113.html +0 -36
  112. data/doc/rdoc/classes/Mongrel/Configurator.src/M000114.html +0 -18
  113. data/doc/rdoc/classes/Mongrel/Const.html +0 -337
  114. data/doc/rdoc/classes/Mongrel/DeflateFilter.html +0 -188
  115. data/doc/rdoc/classes/Mongrel/DeflateFilter.src/M000124.html +0 -19
  116. data/doc/rdoc/classes/Mongrel/DeflateFilter.src/M000125.html +0 -23
  117. data/doc/rdoc/classes/Mongrel/DirHandler.html +0 -303
  118. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000051.html +0 -21
  119. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000052.html +0 -42
  120. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000053.html +0 -38
  121. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000054.html +0 -65
  122. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000055.html +0 -39
  123. data/doc/rdoc/classes/Mongrel/DirHandler.src/M000056.html +0 -18
  124. data/doc/rdoc/classes/Mongrel/Error404Handler.html +0 -171
  125. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000126.html +0 -18
  126. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000127.html +0 -18
  127. data/doc/rdoc/classes/Mongrel/HeaderOut.html +0 -190
  128. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000066.html +0 -21
  129. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000067.html +0 -21
  130. data/doc/rdoc/classes/Mongrel/HttpHandler.html +0 -215
  131. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000072.html +0 -17
  132. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000073.html +0 -17
  133. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000074.html +0 -17
  134. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.html +0 -210
  135. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000014.html +0 -17
  136. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000015.html +0 -17
  137. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000016.html +0 -19
  138. data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000017.html +0 -17
  139. data/doc/rdoc/classes/Mongrel/HttpParams.html +0 -131
  140. data/doc/rdoc/classes/Mongrel/HttpParser.html +0 -278
  141. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000044.html +0 -28
  142. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000045.html +0 -29
  143. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000046.html +0 -29
  144. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000047.html +0 -59
  145. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000048.html +0 -27
  146. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000049.html +0 -27
  147. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000050.html +0 -28
  148. data/doc/rdoc/classes/Mongrel/HttpParserError.html +0 -111
  149. data/doc/rdoc/classes/Mongrel/HttpRequest.html +0 -284
  150. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000133.html +0 -50
  151. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000134.html +0 -41
  152. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000135.html +0 -29
  153. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000136.html +0 -20
  154. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000137.html +0 -20
  155. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000138.html +0 -32
  156. data/doc/rdoc/classes/Mongrel/HttpResponse.html +0 -443
  157. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000075.html +0 -25
  158. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000076.html +0 -20
  159. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000077.html +0 -26
  160. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000078.html +0 -22
  161. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000079.html +0 -22
  162. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000080.html +0 -22
  163. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000081.html +0 -31
  164. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000082.html +0 -21
  165. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000083.html +0 -20
  166. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000084.html +0 -20
  167. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000085.html +0 -20
  168. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000086.html +0 -18
  169. data/doc/rdoc/classes/Mongrel/HttpServer.html +0 -402
  170. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000057.html +0 -25
  171. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000058.html +0 -100
  172. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000059.html +0 -32
  173. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000060.html +0 -21
  174. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000061.html +0 -29
  175. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000062.html +0 -65
  176. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000063.html +0 -34
  177. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000064.html +0 -18
  178. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000065.html +0 -22
  179. data/doc/rdoc/classes/Mongrel/Rails.html +0 -112
  180. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.html +0 -225
  181. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000034.html +0 -37
  182. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000035.html +0 -25
  183. data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000036.html +0 -26
  184. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.html +0 -263
  185. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000037.html +0 -23
  186. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000038.html +0 -56
  187. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000039.html +0 -20
  188. data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000040.html +0 -25
  189. data/doc/rdoc/classes/Mongrel/RedirectHandler.html +0 -187
  190. data/doc/rdoc/classes/Mongrel/RedirectHandler.src/M000131.html +0 -22
  191. data/doc/rdoc/classes/Mongrel/RedirectHandler.src/M000132.html +0 -27
  192. data/doc/rdoc/classes/Mongrel/StatisticsFilter.html +0 -211
  193. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000128.html +0 -24
  194. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000129.html +0 -24
  195. data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000130.html +0 -18
  196. data/doc/rdoc/classes/Mongrel/Stats.html +0 -309
  197. data/doc/rdoc/classes/Mongrel/Stats.src/M000139.html +0 -19
  198. data/doc/rdoc/classes/Mongrel/Stats.src/M000140.html +0 -23
  199. data/doc/rdoc/classes/Mongrel/Stats.src/M000141.html +0 -26
  200. data/doc/rdoc/classes/Mongrel/Stats.src/M000142.html +0 -18
  201. data/doc/rdoc/classes/Mongrel/Stats.src/M000143.html +0 -18
  202. data/doc/rdoc/classes/Mongrel/Stats.src/M000144.html +0 -18
  203. data/doc/rdoc/classes/Mongrel/Stats.src/M000145.html +0 -23
  204. data/doc/rdoc/classes/Mongrel/Stats.src/M000146.html +0 -20
  205. data/doc/rdoc/classes/Mongrel/StatusHandler.html +0 -194
  206. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000068.html +0 -18
  207. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000069.html +0 -24
  208. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000070.html +0 -42
  209. data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000071.html +0 -20
  210. data/doc/rdoc/classes/Mongrel/StopServer.html +0 -117
  211. data/doc/rdoc/classes/Mongrel/TimeoutError.html +0 -117
  212. data/doc/rdoc/classes/Mongrel/URIClassifier.html +0 -317
  213. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000087.html +0 -18
  214. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000088.html +0 -18
  215. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000089.html +0 -39
  216. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000090.html +0 -51
  217. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000091.html +0 -36
  218. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000092.html +0 -83
  219. data/doc/rdoc/classes/MongrelDbg.html +0 -209
  220. data/doc/rdoc/classes/MongrelDbg.src/M000007.html +0 -24
  221. data/doc/rdoc/classes/MongrelDbg.src/M000008.html +0 -20
  222. data/doc/rdoc/classes/MongrelDbg.src/M000009.html +0 -22
  223. data/doc/rdoc/classes/MongrelDbg.src/M000010.html +0 -21
  224. data/doc/rdoc/classes/MongrelDbg.src/M000011.html +0 -18
  225. data/doc/rdoc/classes/Mutex.html +0 -158
  226. data/doc/rdoc/classes/Mutex.src/M000001.html +0 -24
  227. data/doc/rdoc/classes/Mutex.src/M000002.html +0 -32
  228. data/doc/rdoc/classes/RequestLog.html +0 -115
  229. data/doc/rdoc/classes/RequestLog/Access.html +0 -151
  230. data/doc/rdoc/classes/RequestLog/Access.src/M000147.html +0 -19
  231. data/doc/rdoc/classes/RequestLog/Files.html +0 -144
  232. data/doc/rdoc/classes/RequestLog/Files.src/M000148.html +0 -19
  233. data/doc/rdoc/classes/RequestLog/Objects.html +0 -150
  234. data/doc/rdoc/classes/RequestLog/Objects.src/M000150.html +0 -51
  235. data/doc/rdoc/classes/RequestLog/Params.html +0 -144
  236. data/doc/rdoc/classes/RequestLog/Params.src/M000151.html +0 -19
  237. data/doc/rdoc/classes/RequestLog/Threads.html +0 -144
  238. data/doc/rdoc/classes/RequestLog/Threads.src/M000149.html +0 -34
  239. data/doc/rdoc/classes/TCPServer.html +0 -173
  240. data/doc/rdoc/classes/TCPServer.src/M000005.html +0 -19
  241. data/doc/rdoc/created.rid +0 -1
  242. data/doc/rdoc/files/COPYING.html +0 -168
  243. data/doc/rdoc/files/LICENSE.html +0 -168
  244. data/doc/rdoc/files/README.html +0 -213
  245. data/doc/rdoc/files/ext/http11/http11_c.html +0 -101
  246. data/doc/rdoc/files/lib/mongrel/camping_rb.html +0 -120
  247. data/doc/rdoc/files/lib/mongrel/cgi_rb.html +0 -120
  248. data/doc/rdoc/files/lib/mongrel/command_rb.html +0 -123
  249. data/doc/rdoc/files/lib/mongrel/configurator_rb.html +0 -111
  250. data/doc/rdoc/files/lib/mongrel/debug_rb.html +0 -122
  251. data/doc/rdoc/files/lib/mongrel/handlers_rb.html +0 -122
  252. data/doc/rdoc/files/lib/mongrel/init_rb.html +0 -121
  253. data/doc/rdoc/files/lib/mongrel/rails_rb.html +0 -123
  254. data/doc/rdoc/files/lib/mongrel/stats_rb.html +0 -113
  255. data/doc/rdoc/files/lib/mongrel/tcphack_rb.html +0 -113
  256. data/doc/rdoc/files/lib/mongrel_rb.html +0 -135
  257. data/doc/rdoc/files/lib/mutex_fix_rb.html +0 -108
  258. data/doc/rdoc/fr_class_index.html +0 -68
  259. data/doc/rdoc/fr_file_index.html +0 -42
  260. data/doc/rdoc/fr_method_index.html +0 -177
  261. data/doc/rdoc/index.html +0 -24
  262. data/doc/rdoc/rdoc-style.css +0 -208
  263. data/tools/rakehelp.rb +0 -117
@@ -4,12 +4,10 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- $mongrel_debug_client = false
8
-
9
- require 'rubygems'
10
7
  require 'socket'
11
8
  require 'http11'
12
9
  require 'tempfile'
10
+
13
11
  begin
14
12
  require 'fastthread'
15
13
  rescue RuntimeError => e
@@ -18,6 +16,9 @@ rescue LoadError
18
16
  ensure
19
17
  require 'thread'
20
18
  end
19
+
20
+ require 'cgi_multipart_eof_fix'
21
+
21
22
  require 'stringio'
22
23
  require 'mongrel/cgi'
23
24
  require 'mongrel/handlers'
@@ -36,30 +37,27 @@ require 'uri'
36
37
  module Mongrel
37
38
 
38
39
  class URIClassifier
39
- attr_reader :handler_map
40
-
40
+ attr_reader :handler_map
41
+
41
42
  # Returns the URIs that have been registered with this classifier so far.
42
43
  # The URIs returned should not be modified as this will cause a memory leak.
43
44
  # You can use this to inspect the contents of the URIClassifier.
44
45
  def uris
45
46
  @handler_map.keys
46
47
  end
47
-
48
48
  # Simply does an inspect that looks like a Hash inspect.
49
49
  def inspect
50
50
  @handler_map.inspect
51
51
  end
52
- end
53
52
 
53
+ end
54
54
 
55
55
  # Used to stop the HttpServer via Thread.raise.
56
56
  class StopServer < Exception; end
57
57
 
58
-
59
58
  # Thrown at a thread when it is timed out.
60
59
  class TimeoutError < Exception; end
61
60
 
62
-
63
61
  # Every standard HTTP code mapped to the appropriate message. These are
64
62
  # used so frequently that they are placed directly in Mongrel for easy
65
63
  # access rather than Mongrel::Const.
@@ -125,7 +123,7 @@ module Mongrel
125
123
  REQUEST_URI='REQUEST_URI'.freeze
126
124
  REQUEST_PATH='REQUEST_PATH'.freeze
127
125
 
128
- MONGREL_VERSION="1.0.1".freeze
126
+ MONGREL_VERSION="1.0.2".freeze
129
127
 
130
128
  MONGREL_TMP_BASE="mongrel".freeze
131
129
 
@@ -261,11 +259,11 @@ module Mongrel
261
259
 
262
260
  update_request_progress(remain, total)
263
261
  end
264
- rescue Object
265
- STDERR.puts "ERROR reading http body: #$!"
266
- $!.backtrace.join("\n")
262
+ rescue Object => e
263
+ STDERR.puts "#{Time.now}: Error reading HTTP body: #{e.inspect}"
264
+ STDERR.puts e.backtrace.join("\n")
267
265
  # any errors means we should delete the file, including if the file is dumped
268
- @socket.close rescue Object
266
+ @socket.close rescue nil
269
267
  @body.delete if @body.class == Tempfile
270
268
  @body = nil # signals that there was a problem
271
269
  end
@@ -399,6 +397,7 @@ module Mongrel
399
397
  @socket = socket
400
398
  @body = StringIO.new
401
399
  @status = 404
400
+ @reason = HTTP_STATUS_CODES[@status]
402
401
  @header = HeaderOut.new(StringIO.new)
403
402
  @header[Const::DATE] = Time.now.httpdate
404
403
  @body_sent = false
@@ -414,8 +413,9 @@ module Mongrel
414
413
  # by simple passing "finalize=true" to the start method. By default
415
414
  # all handlers run and then mongrel finalizes the request when they're
416
415
  # all done.
417
- def start(status=200, finalize=false)
416
+ def start(status=200, finalize=false, reason=HTTP_STATUS_CODES[status])
418
417
  @status = status.to_i
418
+ @reason = reason
419
419
  yield @header, @body
420
420
  finished if finalize
421
421
  end
@@ -437,8 +437,8 @@ module Mongrel
437
437
 
438
438
  def send_status(content_length=@body.length)
439
439
  if not @status_sent
440
- @header['Content-Length'] = content_length unless @status == 304
441
- write(Const::STATUS_FORMAT % [@status, HTTP_STATUS_CODES[@status]])
440
+ @header['Content-Length'] = content_length if content_length and @status != 304
441
+ write(Const::STATUS_FORMAT % [@status, @reason])
442
442
  @status_sent = true
443
443
  end
444
444
  end
@@ -482,7 +482,7 @@ module Mongrel
482
482
 
483
483
  def socket_error(details)
484
484
  # ignore these since it means the client closed off early
485
- @socket.close rescue Object
485
+ @socket.close rescue nil
486
486
  done = true
487
487
  raise details
488
488
  end
@@ -540,6 +540,7 @@ module Mongrel
540
540
  attr_reader :classifier
541
541
  attr_reader :host
542
542
  attr_reader :port
543
+ attr_reader :throttle
543
544
  attr_reader :timeout
544
545
  attr_reader :num_processors
545
546
 
@@ -553,18 +554,18 @@ module Mongrel
553
554
  # way to deal with overload. Other schemes involve still parsing the client's request
554
555
  # which defeats the point of an overload handling system.
555
556
  #
556
- # The timeout parameter is a sleep timeout (in hundredths of a second) that is placed between
557
+ # The throttle parameter is a sleep timeout (in hundredths of a second) that is placed between
557
558
  # socket.accept calls in order to give the server a cheap throttle time. It defaults to 0 and
558
559
  # actually if it is 0 then the sleep is not done at all.
559
- def initialize(host, port, num_processors=(2**30-1), timeout=0)
560
+ def initialize(host, port, num_processors=950, throttle=0, timeout=60)
560
561
  @socket = TCPServer.new(host, port)
561
562
  @classifier = URIClassifier.new
562
563
  @host = host
563
564
  @port = port
564
565
  @workers = ThreadGroup.new
565
- @timeout = timeout
566
+ @throttle = throttle
566
567
  @num_processors = num_processors
567
- @death_time = 60
568
+ @timeout = timeout
568
569
  end
569
570
 
570
571
  # Does the majority of the IO processing. It has been written in Ruby using
@@ -591,7 +592,7 @@ module Mongrel
591
592
  if not params[Const::REQUEST_PATH]
592
593
  # it might be a dumbass full host request header
593
594
  uri = URI.parse(params[Const::REQUEST_URI])
594
- params[Const::REQUEST_PATH] = uri.request_uri
595
+ params[Const::REQUEST_PATH] = uri.path
595
596
  end
596
597
 
597
598
  raise "No REQUEST PATH" if not params[Const::REQUEST_PATH]
@@ -601,7 +602,14 @@ module Mongrel
601
602
  if handlers
602
603
  params[Const::PATH_INFO] = path_info
603
604
  params[Const::SCRIPT_NAME] = script_name
604
- params[Const::REMOTE_ADDR] = params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last
605
+
606
+ # From http://www.ietf.org/rfc/rfc3875 :
607
+ # "Script authors should be aware that the REMOTE_ADDR and REMOTE_HOST
608
+ # meta-variables (see sections 4.1.8 and 4.1.9) may not identify the
609
+ # ultimate source of the request. They identify the client for the
610
+ # immediate request to the server; that client may be a proxy, gateway,
611
+ # or other intermediary acting on behalf of the actual source client."
612
+ params[Const::REMOTE_ADDR] = client.peeraddr.last
605
613
 
606
614
  # select handlers that want more detailed request notification
607
615
  notifiers = handlers.select { |h| h.request_notify }
@@ -641,19 +649,24 @@ module Mongrel
641
649
  end
642
650
  end
643
651
  rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
644
- client.close rescue Object
645
- rescue HttpParserError
646
- if $mongrel_debug_client
647
- STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
648
- STDERR.puts "#{Time.now}: REQUEST DATA: #{data.inspect}\n---\nPARAMS: #{params.inspect}\n---\n"
649
- end
652
+ client.close rescue nil
653
+ rescue HttpParserError => e
654
+ STDERR.puts "#{Time.now}: HTTP parse error, malformed request (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #{e.inspect}"
655
+ STDERR.puts "#{Time.now}: REQUEST DATA: #{data.inspect}\n---\nPARAMS: #{params.inspect}\n---\n"
650
656
  rescue Errno::EMFILE
651
657
  reap_dead_workers('too many files')
652
- rescue Object
653
- STDERR.puts "#{Time.now}: ERROR: #$!"
654
- STDERR.puts $!.backtrace.join("\n") if $mongrel_debug_client
658
+ rescue Object => e
659
+ STDERR.puts "#{Time.now}: Read error: #{e.inspect}"
660
+ STDERR.puts e.backtrace.join("\n")
655
661
  ensure
656
- client.close rescue Object
662
+ begin
663
+ client.close
664
+ rescue IOError
665
+ # Already closed
666
+ rescue Object => e
667
+ STDERR.puts "#{Time.now}: Client error: #{e.inspect}"
668
+ STDERR.puts e.backtrace.join("\n")
669
+ end
657
670
  request.body.delete if request and request.body.class == Tempfile
658
671
  end
659
672
  end
@@ -670,7 +683,7 @@ module Mongrel
670
683
  @workers.list.each do |w|
671
684
  w[:started_on] = Time.now if not w[:started_on]
672
685
 
673
- if mark - w[:started_on] > @death_time + @timeout
686
+ if mark - w[:started_on] > @timeout + @throttle
674
687
  STDERR.puts "Thread #{w.inspect} is too old, killing."
675
688
  w.raise(TimeoutError.new(error_msg))
676
689
  end
@@ -681,13 +694,13 @@ module Mongrel
681
694
  end
682
695
 
683
696
  # Performs a wait on all the currently running threads and kills any that take
684
- # too long. Right now it just waits 60 seconds, but will expand this to
685
- # allow setting. The @timeout setting does extend this waiting period by
697
+ # too long. It waits by @timeout seconds, which can be set in .initialize or
698
+ # via mongrel_rails. The @throttle setting does extend this waiting period by
686
699
  # that much longer.
687
700
  def graceful_shutdown
688
701
  while reap_dead_workers("shutdown") > 0
689
- STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@death_time + @timeout} seconds."
690
- sleep @death_time / 10
702
+ STDERR.print "Waiting for #{@workers.list.length} requests to finish, could take #{@timeout + @throttle} seconds."
703
+ sleep @timeout / 10
691
704
  end
692
705
  end
693
706
 
@@ -697,6 +710,8 @@ module Mongrel
697
710
  # 9 is currently TCP_DEFER_ACCEPT
698
711
  $tcp_defer_accept_opts = [Socket::SOL_TCP, 9, 1]
699
712
  $tcp_cork_opts = [Socket::SOL_TCP, 3, 1]
713
+ when /freebsd(([1-4]\..{1,2})|5\.[0-4])/
714
+ # Do nothing, just closing a bug when freebsd <= 5.4
700
715
  when /freebsd/
701
716
  # Use the HTTP accept filter if available.
702
717
  # The struct made by pack() is defined in /usr/include/sys/socket.h as accept_filter_arg
@@ -713,7 +728,7 @@ module Mongrel
713
728
 
714
729
  configure_socket_options
715
730
 
716
- if $tcp_defer_accept_opts
731
+ if defined?($tcp_defer_accept_opts) and $tcp_defer_accept_opts
717
732
  @socket.setsockopt(*$tcp_defer_accept_opts) rescue nil
718
733
  end
719
734
 
@@ -722,7 +737,7 @@ module Mongrel
722
737
  begin
723
738
  client = @socket.accept
724
739
 
725
- if $tcp_cork_opts
740
+ if defined?($tcp_cork_opts) and $tcp_cork_opts
726
741
  client.setsockopt(*$tcp_cork_opts) rescue nil
727
742
  end
728
743
 
@@ -730,27 +745,27 @@ module Mongrel
730
745
 
731
746
  if worker_list.length >= @num_processors
732
747
  STDERR.puts "Server overloaded with #{worker_list.length} processors (#@num_processors max). Dropping connection."
733
- client.close rescue Object
748
+ client.close rescue nil
734
749
  reap_dead_workers("max processors")
735
750
  else
736
751
  thread = Thread.new(client) {|c| process_client(c) }
737
752
  thread[:started_on] = Time.now
738
753
  @workers.add(thread)
739
754
 
740
- sleep @timeout/100 if @timeout > 0
755
+ sleep @throttle/100.0 if @throttle > 0
741
756
  end
742
757
  rescue StopServer
743
- @socket.close rescue Object
758
+ @socket.close
744
759
  break
745
760
  rescue Errno::EMFILE
746
761
  reap_dead_workers("too many open files")
747
762
  sleep 0.5
748
763
  rescue Errno::ECONNABORTED
749
764
  # client closed the socket even before accept
750
- client.close rescue Object
751
- rescue Object => exc
752
- STDERR.puts "!!!!!! UNHANDLED EXCEPTION! #{exc}. TELL ZED HE'S A MORON."
753
- STDERR.puts $!.backtrace.join("\n") if $mongrel_debug_client
765
+ client.close rescue nil
766
+ rescue Object => e
767
+ STDERR.puts "#{Time.now}: Unhandled listen loop exception #{e.inspect}."
768
+ STDERR.puts e.backtrace.join("\n")
754
769
  end
755
770
  end
756
771
  graceful_shutdown
@@ -794,12 +809,12 @@ module Mongrel
794
809
 
795
810
  # Stops the acceptor thread and then causes the worker threads to finish
796
811
  # off the request queue before finally exiting.
797
- def stop
798
- stopper = Thread.new do
799
- exc = StopServer.new
800
- @acceptor.raise(exc)
812
+ def stop(synchronous=false)
813
+ @acceptor.raise(StopServer.new)
814
+
815
+ if synchronous
816
+ sleep(0.5) while @acceptor.alive?
801
817
  end
802
- stopper.priority = 10
803
818
  end
804
819
 
805
820
  end
@@ -109,10 +109,10 @@ module Mongrel
109
109
  end
110
110
 
111
111
  @head.delete('cookie')
112
-
113
- # @output_cookies seems to never be used, but we'll process it just in case
114
- @output_cookies.each {|c| to['Set-Cookie'] = c.to_s } if @output_cookies
115
112
  end
113
+
114
+ # @output_cookies seems to never be used, but we'll process it just in case
115
+ @output_cookies.each {|c| to['Set-Cookie'] = c.to_s } if @output_cookies
116
116
  end
117
117
 
118
118
  # The dumb thing is people can call header or this or both and in any order.
@@ -179,7 +179,7 @@ module Mongrel
179
179
  print_command_list
180
180
  return true
181
181
  elsif cmd_name == "--version"
182
- STDERR.puts "Mongrel Web Server #{Mongrel::Const::MONGREL_VERSION}"
182
+ puts "Mongrel Web Server #{Mongrel::Const::MONGREL_VERSION}"
183
183
  return true
184
184
  end
185
185
 
@@ -1,7 +1,6 @@
1
1
  require 'yaml'
2
2
  require 'etc'
3
3
 
4
-
5
4
  module Mongrel
6
5
  # Implements a simple DSL for configuring a Mongrel server for your
7
6
  # purposes. More used by framework implementers to setup Mongrel
@@ -39,7 +38,7 @@ module Mongrel
39
38
  attr_reader :needs_restart
40
39
 
41
40
  # You pass in initial defaults and then a block to continue configuring.
42
- def initialize(defaults={}, &blk)
41
+ def initialize(defaults={}, &block)
43
42
  @listener = nil
44
43
  @listener_name = nil
45
44
  @listeners = {}
@@ -47,25 +46,31 @@ module Mongrel
47
46
  @needs_restart = false
48
47
  @pid_file = defaults[:pid_file]
49
48
 
50
- if blk
51
- cloaker(&blk).bind(self).call
49
+ if block
50
+ cloaker(&block).bind(self).call
52
51
  end
53
52
  end
54
53
 
55
- # Change privilege of the process to specified user and group.
54
+ # Change privileges of the process to specified user and group.
56
55
  def change_privilege(user, group)
57
56
  begin
58
- if group
59
- log "Changing group to #{group}."
60
- Process::GID.change_privilege(Etc.getgrnam(group).gid)
61
- end
62
-
63
- if user
64
- log "Changing user to #{user}."
65
- Process::UID.change_privilege(Etc.getpwnam(user).uid)
57
+ uid, gid = Process.euid, Process.egid
58
+ target_uid = Etc.getpwnam(user).uid if user
59
+ target_gid = Etc.getgrnam(group).gid if group
60
+
61
+ if uid != target_uid or gid != target_gid
62
+ log "Initiating groups for #{user.inspect}:#{group.inspect}."
63
+ Process.initgroups(user, target_id)
64
+
65
+ log "Changing group to #{group.inspect}."
66
+ Process::GID.change_privilege(target_gid)
67
+
68
+ log "Changing user to #{user.inspect}."
69
+ Process::UID.change_privilege(target_uid)
66
70
  end
67
- rescue Errno::EPERM
68
- log "FAILED to change user:group #{user}:#{group}: #$!"
71
+ rescue Errno::EPERM => e
72
+ log "Couldn't change user and group to #{user.inspect}:#{group.inspect}: #{e.to_s}."
73
+ log "Mongrel failed to start."
69
74
  exit 1
70
75
  end
71
76
  end
@@ -74,15 +79,19 @@ module Mongrel
74
79
  File.unlink(@pid_file) if @pid_file and File.exists?(@pid_file)
75
80
  end
76
81
 
77
- # Writes the PID file but only if we're on windows.
82
+ # Writes the PID file if we're not on Windows.
78
83
  def write_pid_file
79
84
  if RUBY_PLATFORM !~ /mswin/
80
85
  log "Writing PID file to #{@pid_file}"
81
86
  open(@pid_file,"w") {|f| f.write(Process.pid) }
87
+ open(@pid_file,"w") do |f|
88
+ f.write(Process.pid)
89
+ File.chmod(0644, @pid_file)
90
+ end
82
91
  end
83
92
  end
84
93
 
85
- # generates a class for cloaking the current self and making the DSL nicer
94
+ # Generates a class for cloaking the current self and making the DSL nicer.
86
95
  def cloaking_class
87
96
  class << self
88
97
  self
@@ -90,9 +99,9 @@ module Mongrel
90
99
  end
91
100
 
92
101
  # Do not call this. You were warned.
93
- def cloaker(&blk)
102
+ def cloaker(&block)
94
103
  cloaking_class.class_eval do
95
- define_method :cloaker_, &blk
104
+ define_method :cloaker_, &block
96
105
  meth = instance_method( :cloaker_ )
97
106
  remove_method :cloaker_
98
107
  meth
@@ -114,18 +123,20 @@ module Mongrel
114
123
  #
115
124
  # * :host => Host name to bind.
116
125
  # * :port => Port to bind.
117
- # * :num_processors => The maximum number of concurrent threads allowed. (950 default)
118
- # * :timeout => 1/100th of a second timeout between requests. (10 is 1/10th, 0 is timeout)
126
+ # * :num_processors => The maximum number of concurrent threads allowed.
127
+ # * :throttle => Time to pause (in hundredths of a second) between accepting clients.
128
+ # * :timeout => Time to wait (in seconds) before killing a stalled thread.
119
129
  # * :user => User to change to, must have :group as well.
120
130
  # * :group => Group to change to, must have :user as well.
121
131
  #
122
- def listener(options={},&blk)
132
+ def listener(options={},&block)
123
133
  raise "Cannot call listener inside another listener block." if (@listener or @listener_name)
124
134
  ops = resolve_defaults(options)
125
135
  ops[:num_processors] ||= 950
126
- ops[:timeout] ||= 0
136
+ ops[:throttle] ||= 0
137
+ ops[:timeout] ||= 60
127
138
 
128
- @listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i, ops[:num_processors].to_i, ops[:timeout].to_i)
139
+ @listener = Mongrel::HttpServer.new(ops[:host], ops[:port].to_i, ops[:num_processors].to_i, ops[:throttle].to_i, ops[:timeout].to_i)
129
140
  @listener_name = "#{ops[:host]}:#{ops[:port]}"
130
141
  @listeners[@listener_name] = @listener
131
142
 
@@ -134,8 +145,8 @@ module Mongrel
134
145
  end
135
146
 
136
147
  # Does the actual cloaking operation to give the new implicit self.
137
- if blk
138
- cloaker(&blk).bind(self).call
148
+ if block
149
+ cloaker(&block).bind(self).call
139
150
  end
140
151
 
141
152
  # all done processing this listener setup, reset implicit variables
@@ -277,11 +288,10 @@ module Mongrel
277
288
  # Calls .stop on all the configured listeners so they
278
289
  # stop processing requests (gracefully). By default it
279
290
  # assumes that you don't want to restart.
280
- def stop(needs_restart=false)
281
- @listeners.each {|name,s|
282
- s.stop
283
- }
284
-
291
+ def stop(needs_restart=false, synchronous=false)
292
+ @listeners.each do |name,s|
293
+ s.stop(synchronous)
294
+ end
285
295
  @needs_restart = needs_restart
286
296
  end
287
297