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,10 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel'
9
- require File.dirname(__FILE__) + '/testhelp.rb'
10
-
7
+ require 'test/testhelp'
11
8
 
12
9
  class TestCommand < GemPlugin::Plugin "/commands"
13
10
  include Mongrel::Command::Base
@@ -4,19 +4,17 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'net/http'
9
- require 'mongrel'
7
+ require 'test/testhelp'
10
8
 
11
9
  include Mongrel
12
10
 
13
11
  class ConditionalResponseTest < Test::Unit::TestCase
14
12
  def setup
15
- @h = HttpServer.new('127.0.0.1', 3501)
16
- @h.register('/', Mongrel::DirHandler.new('.'))
17
- @h.run
13
+ @server = HttpServer.new('127.0.0.1', 3501)
14
+ @server.register('/', Mongrel::DirHandler.new('.'))
15
+ @server.run
18
16
 
19
- @http = Net::HTTP.new(@h.host, @h.port)
17
+ @http = Net::HTTP.new(@server.host, @server.port)
20
18
 
21
19
  # get the ETag and Last-Modified headers
22
20
  @path = '/README'
@@ -27,17 +25,7 @@ class ConditionalResponseTest < Test::Unit::TestCase
27
25
  end
28
26
 
29
27
  def teardown
30
- orig_stderr = STDERR.dup
31
-
32
- # temporarily disable the puts method in STDERR to silence warnings from stop
33
- class << STDERR
34
- define_method(:puts) {}
35
- end
36
-
37
- @h.stop
38
- ensure
39
- # restore STDERR
40
- STDERR.reopen(orig_stderr)
28
+ @server.stop(true)
41
29
  end
42
30
 
43
31
  # status should be 304 Not Modified when If-None-Match is the matching ETag
@@ -4,10 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel'
9
- require 'net/http'
10
- require File.dirname(__FILE__) + "/testhelp.rb"
7
+ require 'test/testhelp'
11
8
 
12
9
  $test_plugin_fired = 0
13
10
 
@@ -32,10 +29,10 @@ end
32
29
  class ConfiguratorTest < Test::Unit::TestCase
33
30
 
34
31
  def test_base_handler_config
35
- config = nil
32
+ @config = nil
36
33
 
37
34
  redirect_test_io do
38
- config = Mongrel::Configurator.new :host => "localhost" do
35
+ @config = Mongrel::Configurator.new :host => "localhost" do
39
36
  listener :port => 4501 do
40
37
  # 2 in front should run, but the sentinel shouldn't since dirhandler processes the request
41
38
  uri "/", :handler => plugin("/handlers/testplugin")
@@ -60,7 +57,7 @@ class ConfiguratorTest < Test::Unit::TestCase
60
57
  end
61
58
 
62
59
 
63
- config.listeners.each do |host,listener|
60
+ @config.listeners.each do |host,listener|
64
61
  assert listener.classifier.uris.length == 3, "Wrong number of registered URIs"
65
62
  assert listener.classifier.uris.include?("/"), "/ not registered"
66
63
  assert listener.classifier.uris.include?("/test"), "/test not registered"
@@ -78,7 +75,7 @@ class ConfiguratorTest < Test::Unit::TestCase
78
75
  end
79
76
 
80
77
  redirect_test_io do
81
- config.stop
78
+ @config.stop(false, true)
82
79
  end
83
80
 
84
81
  assert_raise Errno::EBADF, Errno::ECONNREFUSED do
@@ -4,23 +4,15 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'fileutils'
8
- FileUtils.mkdir_p "log/mongrel_debug"
9
-
10
- require 'test/unit'
11
- require 'mongrel/rails'
7
+ require 'test/testhelp'
12
8
  require 'mongrel/debug'
13
9
 
14
-
15
10
  class MongrelDbgTest < Test::Unit::TestCase
16
11
 
17
- def setup
12
+ def test_tracing_to_log
18
13
  FileUtils.rm_rf "log/mongrel_debug"
19
- MongrelDbg::configure
20
- end
21
-
22
14
 
23
- def test_tracing_to_log
15
+ MongrelDbg::configure
24
16
  out = StringIO.new
25
17
 
26
18
  MongrelDbg::begin_trace(:rails)
@@ -4,11 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'net/http'
9
- require 'mongrel'
10
- require 'timeout'
11
- require File.dirname(__FILE__) + "/testhelp.rb"
7
+ require 'test/testhelp'
12
8
 
13
9
  class SimpleHandler < Mongrel::HttpHandler
14
10
  def process(request, response)
@@ -48,15 +44,16 @@ class HandlersTest < Test::Unit::TestCase
48
44
  uri "/dumb", :handler => Mongrel::DeflateFilter.new
49
45
  uri "/dumb", :handler => DumbHandler.new, :in_front => true
50
46
  uri "/files", :handler => Mongrel::DirHandler.new("doc")
51
- uri "/files_nodir", :handler => Mongrel::DirHandler.new("doc",listing_allowed=false, index_html="none")
47
+ uri "/files_nodir", :handler => Mongrel::DirHandler.new("doc", listing_allowed=false, index_html="none")
52
48
  uri "/status", :handler => Mongrel::StatusHandler.new(:stats_filter => stats)
49
+ uri "/relative", :handler => Mongrel::DirHandler.new(nil, listing_allowed=false, index_html="none")
53
50
  end
54
51
  end
55
52
  @config.run
56
53
  end
57
54
 
58
55
  def teardown
59
- @config.stop
56
+ @config.stop(false, true)
60
57
  end
61
58
 
62
59
  def test_more_web_server
@@ -70,6 +67,7 @@ class HandlersTest < Test::Unit::TestCase
70
67
  "http://localhost:9998/status",
71
68
  ])
72
69
 
70
+ # XXX This can't possibly have good coverage.
73
71
  check_status res, String
74
72
  end
75
73
 
@@ -78,14 +76,14 @@ class HandlersTest < Test::Unit::TestCase
78
76
  # test that no accept-encoding returns a non-deflated response
79
77
  req = h.get("/dumb")
80
78
  assert(
81
- !req.header['Content-Encoding'] ||
82
- !req.header['Content-Encoding'].include?('deflate'))
79
+ !req['Content-Encoding'] ||
80
+ !req['Content-Encoding'].include?('deflate'))
83
81
  assert_equal "test", req.body
84
82
 
85
83
  req = h.get("/dumb", {"Accept-Encoding" => "deflate"})
86
84
  # -MAX_WBITS stops zlib from looking for a zlib header
87
85
  inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
88
- assert req.header['Content-Encoding'].include?('deflate')
86
+ assert req['Content-Encoding'].include?('deflate')
89
87
  assert_equal "test", inflater.inflate(req.body)
90
88
  end
91
89
  end
@@ -4,11 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'http11'
9
- require 'mongrel'
10
- require 'benchmark'
11
- require 'digest/sha1'
7
+ require 'test/testhelp'
12
8
 
13
9
  include Mongrel
14
10
 
@@ -19,10 +15,21 @@ class HttpParserTest < Test::Unit::TestCase
19
15
  req = {}
20
16
  http = "GET / HTTP/1.1\r\n\r\n"
21
17
  nread = parser.execute(req, http, 0)
18
+
22
19
  assert nread == http.length, "Failed to parse the full HTTP request"
23
20
  assert parser.finished?, "Parser didn't finish"
24
21
  assert !parser.error?, "Parser had error"
25
22
  assert nread == parser.nread, "Number read returned from execute does not match"
23
+
24
+ assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL']
25
+ assert_equal '/', req['REQUEST_PATH']
26
+ assert_equal 'HTTP/1.1', req['HTTP_VERSION']
27
+ assert_equal '/', req['REQUEST_URI']
28
+ assert_equal 'CGI/1.2', req['GATEWAY_INTERFACE']
29
+ assert_equal 'GET', req['REQUEST_METHOD']
30
+ assert_nil req['FRAGMENT']
31
+ assert_nil req['QUERY_STRING']
32
+
26
33
  parser.reset
27
34
  assert parser.nread == 0, "Number read after reset should be 0"
28
35
  end
@@ -62,6 +69,18 @@ class HttpParserTest < Test::Unit::TestCase
62
69
  assert parser.error?, "Parser SHOULD have error"
63
70
  end
64
71
 
72
+ def test_fragment_in_uri
73
+ parser = HttpParser.new
74
+ req = {}
75
+ get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n"
76
+ assert_nothing_raised do
77
+ parser.execute(req, get, 0)
78
+ end
79
+ assert parser.finished?
80
+ assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI']
81
+ assert_equal 'posts-17408', req['FRAGMENT']
82
+ end
83
+
65
84
  # lame random garbage maker
66
85
  def rand_data(min, max, readable=true)
67
86
  count = min + ((rand(max)+1) *10).to_i
@@ -4,11 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel'
9
- require 'net/http'
10
- require 'uri'
11
- require 'timeout'
7
+ require 'test/testhelp'
12
8
 
13
9
  class RedirectHandlerTest < Test::Unit::TestCase
14
10
 
@@ -19,7 +15,7 @@ class RedirectHandlerTest < Test::Unit::TestCase
19
15
  end
20
16
 
21
17
  def teardown
22
- @server.stop
18
+ @server.stop(true)
23
19
  end
24
20
 
25
21
  def test_simple_redirect
@@ -4,11 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel'
9
- require 'net/http'
10
- require File.dirname(__FILE__) + '/testhelp.rb'
11
-
7
+ require 'test/testhelp'
12
8
 
13
9
  class UploadBeginHandler < Mongrel::HttpHandler
14
10
  attr_reader :request_began, :request_progressed, :request_processed
@@ -18,9 +14,9 @@ class UploadBeginHandler < Mongrel::HttpHandler
18
14
  end
19
15
 
20
16
  def reset
21
- @request_began =
22
- @request_progressed =
23
- @request_processed = false
17
+ @request_began = false
18
+ @request_progressed = false
19
+ @request_processed = false
24
20
  end
25
21
 
26
22
  def request_begins(params)
@@ -49,7 +45,7 @@ class RequestProgressTest < Test::Unit::TestCase
49
45
  end
50
46
 
51
47
  def teardown
52
- @server.stop
48
+ @server.stop(true)
53
49
  end
54
50
 
55
51
  def test_begin_end_progress
@@ -4,9 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel'
9
- require 'benchmark'
7
+ require 'test/testhelp'
10
8
 
11
9
  include Mongrel
12
10
 
@@ -102,5 +100,28 @@ class ResponseTest < Test::Unit::TestCase
102
100
  assert io.length > 0, "output didn't have data"
103
101
  assert io.read[-contents.length..-1] == contents, "output doesn't end with file payload"
104
102
  end
103
+
104
+ def test_response_with_custom_reason
105
+ reason = "You made a bad request"
106
+ io = StringIO.new
107
+ resp = HttpResponse.new(io)
108
+ resp.start(400, false, reason) { |head,out| }
109
+ resp.finished
110
+
111
+ io.rewind
112
+ assert_match(/.* #{reason}$/, io.readline.chomp, "wrong custom reason phrase")
113
+ end
114
+
115
+ def test_response_with_default_reason
116
+ code = 400
117
+ io = StringIO.new
118
+ resp = HttpResponse.new(io)
119
+ resp.start(code) { |head,out| }
120
+ resp.finished
121
+
122
+ io.rewind
123
+ assert_match(/.* #{HTTP_STATUS_CODES[code]}$/, io.readline.chomp, "wrong default reason phrase")
124
+ end
125
+
105
126
  end
106
127
 
@@ -4,9 +4,7 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'mongrel/stats'
9
- require 'stringio'
7
+ require 'test/testhelp'
10
8
 
11
9
  class StatsTest < Test::Unit::TestCase
12
10
 
@@ -4,169 +4,258 @@
4
4
  # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
5
  # for more information.
6
6
 
7
- require 'test/unit'
8
- require 'net/http'
9
- require 'mongrel'
10
- require 'benchmark'
7
+ require 'test/testhelp'
11
8
 
12
9
  include Mongrel
13
10
 
14
11
  class URIClassifierTest < Test::Unit::TestCase
15
12
 
16
13
  def test_uri_finding
17
- u = URIClassifier.new
18
- u.register("/test", 1)
14
+ uri_classifier = URIClassifier.new
15
+ uri_classifier.register("/test", 1)
19
16
 
20
- sn,pi,val = u.resolve("/test")
21
- assert val != nil, "didn't resolve"
22
- assert_equal 1, val, "wrong value"
23
- assert_equal "/test",sn, "wrong SCRIPT_NAME"
17
+ script_name, path_info, value = uri_classifier.resolve("/test")
18
+ assert_equal 1, value
19
+ assert_equal "/test", script_name
20
+ end
21
+
22
+ def test_root_handler_only
23
+ uri_classifier = URIClassifier.new
24
+ uri_classifier.register("/", 1)
25
+
26
+ script_name, path_info, value = uri_classifier.resolve("/test")
27
+ assert_equal 1, value
28
+ assert_equal "/", script_name
29
+ assert_equal "/test", path_info
24
30
  end
25
-
26
31
 
27
32
  def test_uri_prefix_ops
28
33
  test = "/pre/fix/test"
29
34
  prefix = "/pre"
30
35
 
31
- u = URIClassifier.new
32
- u.register(prefix,1)
36
+ uri_classifier = URIClassifier.new
37
+ uri_classifier.register(prefix,1)
33
38
 
34
- sn,pi,val = u.resolve(prefix)
35
- sn,pi,val = u.resolve(test)
36
- assert val != nil, "didn't resolve"
37
- assert_equal prefix,sn, "wrong script name"
38
- assert_equal test[sn.length .. -1],pi, "wrong path info"
39
+ script_name, path_info, value = uri_classifier.resolve(prefix)
40
+ script_name, path_info, value = uri_classifier.resolve(test)
41
+ assert_equal 1, value
42
+ assert_equal prefix, script_name
43
+ assert_equal test[script_name.length .. -1], path_info
39
44
 
40
- assert u.inspect != nil, "No inspect for classifier"
41
- assert u.uris[0] == prefix, "URI list didn't match"
45
+ assert uri_classifier.inspect
46
+ assert_equal prefix, uri_classifier.uris[0]
42
47
  end
43
48
 
44
49
  def test_not_finding
45
50
  test = "/cant/find/me"
46
- u = URIClassifier.new
47
- u.register(test, 1)
51
+ uri_classifier = URIClassifier.new
52
+ uri_classifier.register(test, 1)
48
53
 
49
- sn,pi,val = u.resolve("/nope/not/here")
50
- assert_equal nil,sn, "shouldn't be found"
51
- assert_equal nil,pi, "shouldn't be found"
52
- assert_equal nil,val, "shouldn't be found"
54
+ script_name, path_info, value = uri_classifier.resolve("/nope/not/here")
55
+ assert_nil script_name
56
+ assert_nil path_info
57
+ assert_nil value
53
58
  end
54
59
 
55
60
  def test_exceptions
56
- u = URIClassifier.new
61
+ uri_classifier = URIClassifier.new
57
62
 
58
- u.register("test", 1)
63
+ uri_classifier.register("/test", 1)
59
64
 
60
65
  failed = false
61
66
  begin
62
- u.register("test", 1)
67
+ uri_classifier.register("/test", 1)
63
68
  rescue => e
64
69
  failed = true
65
70
  end
66
71
 
67
- assert failed, "it didn't fail as expected"
72
+ assert failed
68
73
 
69
74
  failed = false
70
75
  begin
71
- u.register("", 1)
76
+ uri_classifier.register("", 1)
72
77
  rescue => e
73
78
  failed = true
74
79
  end
75
80
 
76
- assert failed, "it didn't fail as expected"
81
+ assert failed
77
82
  end
78
83
 
79
84
 
80
85
  def test_register_unregister
81
- u = URIClassifier.new
86
+ uri_classifier = URIClassifier.new
82
87
 
83
88
  100.times do
84
- u.register("stuff", 1)
85
- val = u.unregister("stuff")
86
- assert_equal 1,val, "didn't get the right return value"
89
+ uri_classifier.register("/stuff", 1)
90
+ value = uri_classifier.unregister("/stuff")
91
+ assert_equal 1, value
87
92
  end
88
93
 
89
- u.register("things",1)
90
- sn,pi,val = u.resolve("things")
91
- assert_equal 1, val, "result doesn't match"
94
+ uri_classifier.register("/things",1)
95
+ script_name, path_info, value = uri_classifier.resolve("/things")
96
+ assert_equal 1, value
92
97
 
93
- u.unregister("things")
94
- sn,pi,val = u.resolve("things")
95
- assert_equal nil, val, "result should be nil"
98
+ uri_classifier.unregister("/things")
99
+ script_name, path_info, value = uri_classifier.resolve("/things")
100
+ assert_nil value
96
101
 
97
102
  end
98
103
 
99
104
 
100
105
  def test_uri_branching
101
- u = URIClassifier.new
102
- u.register("/test", 1)
103
- u.register("/test/this",2)
106
+ uri_classifier = URIClassifier.new
107
+ uri_classifier.register("/test", 1)
108
+ uri_classifier.register("/test/this",2)
104
109
 
105
- sn,pi,h = u.resolve("/test")
106
- sn,pi,h = u.resolve("/test/that")
107
- assert_equal "/test", sn, "failed to properly find script off branch portion of uri"
108
- assert_equal "/that", pi, "didn't get the right patch info"
109
- assert_equal 1, h, "wrong result for branching uri"
110
+ script_name, path_info, handler = uri_classifier.resolve("/test")
111
+ script_name, path_info, handler = uri_classifier.resolve("/test/that")
112
+ assert_equal "/test", script_name, "failed to properly find script off branch portion of uri"
113
+ assert_equal "/that", path_info
114
+ assert_equal 1, handler, "wrong result for branching uri"
110
115
  end
111
116
 
112
117
  def test_all_prefixing
113
118
  tests = ["/test","/test/that","/test/this"]
114
119
  uri = "/test/this/that"
115
- u = URIClassifier.new
120
+ uri_classifier = URIClassifier.new
116
121
 
117
- cur = ""
122
+ current = ""
118
123
  uri.each_byte do |c|
119
- cur << c.chr
120
- u.register(cur, c)
124
+ current << c.chr
125
+ uri_classifier.register(current, c)
121
126
  end
122
127
 
123
- # try to resolve everything with no asserts as a fuzzing
128
+ # Try to resolve everything with no asserts as a fuzzing
124
129
  tests.each do |prefix|
125
- cur = ""
130
+ current = ""
126
131
  prefix.each_byte do |c|
127
- cur << c.chr
128
- sn, pi, h = u.resolve(cur)
129
- assert sn != nil, "didn't get a script name"
130
- assert pi != nil, "didn't get path info"
131
- assert h != nil, "didn't find the handler"
132
+ current << c.chr
133
+ script_name, path_info, handler = uri_classifier.resolve(current)
134
+ assert script_name
135
+ assert path_info
136
+ assert handler
132
137
  end
133
138
  end
134
139
 
135
- # assert that we find stuff
140
+ # Assert that we find stuff
136
141
  tests.each do |t|
137
- sn, pi, h = u.resolve(t)
138
- assert h != nil, "didn't find handler"
142
+ script_name, path_info, handler = uri_classifier.resolve(t)
143
+ assert handler
139
144
  end
140
145
 
141
- # assert we don't find stuff
142
- sn, pi, h = u.resolve("chicken")
143
- assert_nil h, "shoulnd't find anything"
144
- assert_nil sn, "shoulnd't find anything"
145
- assert_nil pi, "shoulnd't find anything"
146
+ # Assert we don't find stuff
147
+ script_name, path_info, handler = uri_classifier.resolve("chicken")
148
+ assert_nil handler
149
+ assert_nil script_name
150
+ assert_nil path_info
146
151
  end
147
152
 
148
153
 
149
154
  # Verifies that a root mounted ("/") handler resolves
150
155
  # such that path info matches the original URI.
151
- # This is needed to accomodate real usage of handlers.
156
+ # This is needed to accommodate real usage of handlers.
152
157
  def test_root_mounted
153
- u = URIClassifier.new
158
+ uri_classifier = URIClassifier.new
154
159
  root = "/"
155
160
  path = "/this/is/a/test"
156
161
 
157
- u.register(root, 1)
162
+ uri_classifier.register(root, 1)
158
163
 
159
- sn, pi, h = u.resolve(root)
160
- assert_equal 1,h, "didn't find handler"
161
- assert_equal root,pi, "didn't get right path info"
162
- assert_equal root,sn, "didn't get right script name"
164
+ script_name, path_info, handler = uri_classifier.resolve(root)
165
+ assert_equal 1, handler
166
+ assert_equal root, path_info
167
+ assert_equal root, script_name
163
168
 
164
- sn, pi, h = u.resolve(path)
165
- assert_equal path,pi, "didn't get right path info"
166
- assert_equal root,sn, "didn't get right script name"
167
- assert_equal 1,h, "didn't find handler"
169
+ script_name, path_info, handler = uri_classifier.resolve(path)
170
+ assert_equal path, path_info
171
+ assert_equal root, script_name
172
+ assert_equal 1, handler
168
173
  end
169
174
 
170
-
175
+ # Verifies that a root mounted ("/") handler
176
+ # is the default point, doesn't matter the order we use
177
+ # to register the URIs
178
+ def test_classifier_order
179
+ tests = ["/before", "/way_past"]
180
+ root = "/"
181
+ path = "/path"
182
+
183
+ uri_classifier = URIClassifier.new
184
+ uri_classifier.register(path, 1)
185
+ uri_classifier.register(root, 2)
186
+
187
+ tests.each do |uri|
188
+ script_name, path_info, handler = uri_classifier.resolve(uri)
189
+ # p uri_classifier.resolve(uri)
190
+ assert_equal root, script_name, "#{uri} did not resolve to #{root}"
191
+ assert_equal uri, path_info
192
+ assert_equal 2, handler
193
+ end
194
+ end
195
+
196
+ if ENV['BENCHMARK']
197
+ # Eventually we will have a suite of benchmarks instead of lamely installing a test
198
+
199
+ def test_benchmark
200
+
201
+ # This URI set should favor a TST. Both versions increase linearly until you hit 14
202
+ # URIs, then the TST flattens out.
203
+ @uris = %w(
204
+ /
205
+ /dag /dig /digbark /dog /dogbark /dog/bark /dug /dugbarking /puppy
206
+ /c /cat /cat/tree /cat/tree/mulberry /cats /cot /cot/tree/mulberry /kitty /kittycat
207
+ # /eag /eig /eigbark /eog /eogbark /eog/bark /eug /eugbarking /iuppy
208
+ # /f /fat /fat/tree /fat/tree/mulberry /fats /fot /fot/tree/mulberry /jitty /jittyfat
209
+ # /gag /gig /gigbark /gog /gogbark /gog/bark /gug /gugbarking /kuppy
210
+ # /h /hat /hat/tree /hat/tree/mulberry /hats /hot /hot/tree/mulberry /litty /littyhat
211
+ # /ceag /ceig /ceigbark /ceog /ceogbark /ceog/cbark /ceug /ceugbarking /ciuppy
212
+ # /cf /cfat /cfat/ctree /cfat/ctree/cmulberry /cfats /cfot /cfot/ctree/cmulberry /cjitty /cjittyfat
213
+ # /cgag /cgig /cgigbark /cgog /cgogbark /cgog/cbark /cgug /cgugbarking /ckuppy
214
+ # /ch /chat /chat/ctree /chat/ctree/cmulberry /chats /chot /chot/ctree/cmulberry /citty /cittyhat
215
+ )
216
+
217
+ @requests = %w(
218
+ /
219
+ /dig
220
+ /digging
221
+ /dogging
222
+ /dogbarking/
223
+ /puppy/barking
224
+ /c
225
+ /cat
226
+ /cat/shrub
227
+ /cat/tree
228
+ /cat/tree/maple
229
+ /cat/tree/mulberry/tree
230
+ /cat/tree/oak
231
+ /cats/
232
+ /cats/tree
233
+ /cod
234
+ /zebra
235
+ )
236
+
237
+ @classifier = URIClassifier.new
238
+ @uris.each do |uri|
239
+ @classifier.register(uri, 1)
240
+ end
241
+
242
+ puts "#{@uris.size} URIs / #{@requests.size * 10000} requests"
243
+
244
+ Benchmark.bm do |x|
245
+ x.report do
246
+ # require 'ruby-prof'
247
+ # profile = RubyProf.profile do
248
+ 10000.times do
249
+ @requests.each do |request|
250
+ @classifier.resolve(request)
251
+ end
252
+ end
253
+ # end
254
+ # File.open("profile.html", 'w') { |file| RubyProf::GraphHtmlPrinter.new(profile).print(file, 0) }
255
+ end
256
+ end
257
+ end
258
+ end
259
+
171
260
  end
172
261