mongrel 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +2 -0
- data/CHANGELOG +2 -0
- data/Manifest +68 -0
- data/bin/mongrel_rails +55 -22
- data/examples/camping/README +3 -0
- data/examples/httpd.conf +474 -0
- data/examples/mime.yaml +3 -0
- data/examples/mongrel.conf +9 -0
- data/examples/monitrc +57 -0
- data/ext/http11/http11.c +25 -12
- data/ext/http11/http11_parser.c +456 -331
- data/ext/http11/http11_parser.h +1 -0
- data/ext/http11/http11_parser.java.rl +170 -0
- data/ext/http11/http11_parser.rl +8 -48
- data/ext/http11/http11_parser_common.rl +54 -0
- data/ext/http11/tst.h +2 -2
- data/ext/http11/tst_cleanup.c +0 -1
- data/ext/http11/tst_insert.c +29 -3
- data/ext/http11/tst_search.c +60 -55
- data/lib/mongrel.rb +68 -53
- data/lib/mongrel/cgi.rb +3 -3
- data/lib/mongrel/command.rb +1 -1
- data/lib/mongrel/configurator.rb +41 -31
- data/lib/mongrel/debug.rb +2 -5
- data/lib/mongrel/handlers.rb +23 -9
- data/lib/mongrel/mime_types.yml +2 -1
- data/lib/mongrel/rails.rb +7 -15
- data/mongrel-public_cert.pem +20 -0
- data/mongrel.gemspec +211 -0
- data/test/jruby_socket.rb +39 -0
- data/test/test_cgi_wrapper.rb +26 -0
- data/test/test_command.rb +1 -4
- data/test/test_conditional.rb +6 -18
- data/test/test_configurator.rb +5 -8
- data/test/test_debug.rb +3 -11
- data/test/test_handlers.rb +8 -10
- data/test/test_http11.rb +24 -5
- data/test/test_redirect_handler.rb +2 -6
- data/test/test_request_progress.rb +5 -9
- data/test/test_response.rb +24 -3
- data/test/test_stats.rb +1 -3
- data/test/test_uriclassifier.rb +170 -81
- data/test/test_ws.rb +25 -24
- data/test/testhelp.rb +26 -3
- data/tools/trickletest.rb +2 -2
- metadata +138 -333
- metadata.gz.sig +0 -0
- data/Rakefile +0 -117
- data/doc/rdoc/classes/IO.html +0 -170
- data/doc/rdoc/classes/IO.src/M000003.html +0 -19
- data/doc/rdoc/classes/IO.src/M000004.html +0 -19
- data/doc/rdoc/classes/Kernel.html +0 -159
- data/doc/rdoc/classes/Kernel.src/M000012.html +0 -19
- data/doc/rdoc/classes/Kernel.src/M000013.html +0 -23
- data/doc/rdoc/classes/Mongrel.html +0 -204
- data/doc/rdoc/classes/Mongrel/CGIWrapper.html +0 -404
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000115.html +0 -25
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000116.html +0 -47
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000117.html +0 -34
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000118.html +0 -32
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000119.html +0 -25
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000120.html +0 -18
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000121.html +0 -18
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000122.html +0 -18
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000123.html +0 -19
- data/doc/rdoc/classes/Mongrel/Camping.html +0 -177
- data/doc/rdoc/classes/Mongrel/Camping.src/M000041.html +0 -22
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.html +0 -184
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000042.html +0 -20
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000043.html +0 -58
- data/doc/rdoc/classes/Mongrel/Command.html +0 -132
- data/doc/rdoc/classes/Mongrel/Command/Base.html +0 -384
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000018.html +0 -24
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000019.html +0 -42
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000020.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000021.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000022.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000023.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000024.html +0 -22
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000025.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000026.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000027.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000028.html +0 -24
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000029.html +0 -24
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000030.html +0 -18
- data/doc/rdoc/classes/Mongrel/Command/Registry.html +0 -192
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000031.html +0 -20
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000032.html +0 -29
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000033.html +0 -58
- data/doc/rdoc/classes/Mongrel/Configurator.html +0 -716
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000093.html +0 -27
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000094.html +0 -31
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000095.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000096.html +0 -21
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000097.html +0 -20
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000098.html +0 -23
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000099.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000100.html +0 -38
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000101.html +0 -19
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000102.html +0 -39
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000103.html +0 -33
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000104.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000105.html +0 -24
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000106.html +0 -19
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000107.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000108.html +0 -22
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000109.html +0 -22
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000110.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000111.html +0 -34
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000112.html +0 -18
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000113.html +0 -36
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000114.html +0 -18
- data/doc/rdoc/classes/Mongrel/Const.html +0 -337
- data/doc/rdoc/classes/Mongrel/DeflateFilter.html +0 -188
- data/doc/rdoc/classes/Mongrel/DeflateFilter.src/M000124.html +0 -19
- data/doc/rdoc/classes/Mongrel/DeflateFilter.src/M000125.html +0 -23
- data/doc/rdoc/classes/Mongrel/DirHandler.html +0 -303
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000051.html +0 -21
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000052.html +0 -42
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000053.html +0 -38
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000054.html +0 -65
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000055.html +0 -39
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000056.html +0 -18
- data/doc/rdoc/classes/Mongrel/Error404Handler.html +0 -171
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000126.html +0 -18
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000127.html +0 -18
- data/doc/rdoc/classes/Mongrel/HeaderOut.html +0 -190
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000066.html +0 -21
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000067.html +0 -21
- data/doc/rdoc/classes/Mongrel/HttpHandler.html +0 -215
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000072.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000073.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000074.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.html +0 -210
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000014.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000015.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000016.html +0 -19
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000017.html +0 -17
- data/doc/rdoc/classes/Mongrel/HttpParams.html +0 -131
- data/doc/rdoc/classes/Mongrel/HttpParser.html +0 -278
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000044.html +0 -28
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000045.html +0 -29
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000046.html +0 -29
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000047.html +0 -59
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000048.html +0 -27
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000049.html +0 -27
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000050.html +0 -28
- data/doc/rdoc/classes/Mongrel/HttpParserError.html +0 -111
- data/doc/rdoc/classes/Mongrel/HttpRequest.html +0 -284
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000133.html +0 -50
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000134.html +0 -41
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000135.html +0 -29
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000136.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000137.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000138.html +0 -32
- data/doc/rdoc/classes/Mongrel/HttpResponse.html +0 -443
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000075.html +0 -25
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000076.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000077.html +0 -26
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000078.html +0 -22
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000079.html +0 -22
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000080.html +0 -22
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000081.html +0 -31
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000082.html +0 -21
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000083.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000084.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000085.html +0 -20
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000086.html +0 -18
- data/doc/rdoc/classes/Mongrel/HttpServer.html +0 -402
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000057.html +0 -25
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000058.html +0 -100
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000059.html +0 -32
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000060.html +0 -21
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000061.html +0 -29
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000062.html +0 -65
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000063.html +0 -34
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000064.html +0 -18
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000065.html +0 -22
- data/doc/rdoc/classes/Mongrel/Rails.html +0 -112
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.html +0 -225
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000034.html +0 -37
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000035.html +0 -25
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000036.html +0 -26
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.html +0 -263
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000037.html +0 -23
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000038.html +0 -56
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000039.html +0 -20
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000040.html +0 -25
- data/doc/rdoc/classes/Mongrel/RedirectHandler.html +0 -187
- data/doc/rdoc/classes/Mongrel/RedirectHandler.src/M000131.html +0 -22
- data/doc/rdoc/classes/Mongrel/RedirectHandler.src/M000132.html +0 -27
- data/doc/rdoc/classes/Mongrel/StatisticsFilter.html +0 -211
- data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000128.html +0 -24
- data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000129.html +0 -24
- data/doc/rdoc/classes/Mongrel/StatisticsFilter.src/M000130.html +0 -18
- data/doc/rdoc/classes/Mongrel/Stats.html +0 -309
- data/doc/rdoc/classes/Mongrel/Stats.src/M000139.html +0 -19
- data/doc/rdoc/classes/Mongrel/Stats.src/M000140.html +0 -23
- data/doc/rdoc/classes/Mongrel/Stats.src/M000141.html +0 -26
- data/doc/rdoc/classes/Mongrel/Stats.src/M000142.html +0 -18
- data/doc/rdoc/classes/Mongrel/Stats.src/M000143.html +0 -18
- data/doc/rdoc/classes/Mongrel/Stats.src/M000144.html +0 -18
- data/doc/rdoc/classes/Mongrel/Stats.src/M000145.html +0 -23
- data/doc/rdoc/classes/Mongrel/Stats.src/M000146.html +0 -20
- data/doc/rdoc/classes/Mongrel/StatusHandler.html +0 -194
- data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000068.html +0 -18
- data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000069.html +0 -24
- data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000070.html +0 -42
- data/doc/rdoc/classes/Mongrel/StatusHandler.src/M000071.html +0 -20
- data/doc/rdoc/classes/Mongrel/StopServer.html +0 -117
- data/doc/rdoc/classes/Mongrel/TimeoutError.html +0 -117
- data/doc/rdoc/classes/Mongrel/URIClassifier.html +0 -317
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000087.html +0 -18
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000088.html +0 -18
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000089.html +0 -39
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000090.html +0 -51
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000091.html +0 -36
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000092.html +0 -83
- data/doc/rdoc/classes/MongrelDbg.html +0 -209
- data/doc/rdoc/classes/MongrelDbg.src/M000007.html +0 -24
- data/doc/rdoc/classes/MongrelDbg.src/M000008.html +0 -20
- data/doc/rdoc/classes/MongrelDbg.src/M000009.html +0 -22
- data/doc/rdoc/classes/MongrelDbg.src/M000010.html +0 -21
- data/doc/rdoc/classes/MongrelDbg.src/M000011.html +0 -18
- data/doc/rdoc/classes/Mutex.html +0 -158
- data/doc/rdoc/classes/Mutex.src/M000001.html +0 -24
- data/doc/rdoc/classes/Mutex.src/M000002.html +0 -32
- data/doc/rdoc/classes/RequestLog.html +0 -115
- data/doc/rdoc/classes/RequestLog/Access.html +0 -151
- data/doc/rdoc/classes/RequestLog/Access.src/M000147.html +0 -19
- data/doc/rdoc/classes/RequestLog/Files.html +0 -144
- data/doc/rdoc/classes/RequestLog/Files.src/M000148.html +0 -19
- data/doc/rdoc/classes/RequestLog/Objects.html +0 -150
- data/doc/rdoc/classes/RequestLog/Objects.src/M000150.html +0 -51
- data/doc/rdoc/classes/RequestLog/Params.html +0 -144
- data/doc/rdoc/classes/RequestLog/Params.src/M000151.html +0 -19
- data/doc/rdoc/classes/RequestLog/Threads.html +0 -144
- data/doc/rdoc/classes/RequestLog/Threads.src/M000149.html +0 -34
- data/doc/rdoc/classes/TCPServer.html +0 -173
- data/doc/rdoc/classes/TCPServer.src/M000005.html +0 -19
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/COPYING.html +0 -168
- data/doc/rdoc/files/LICENSE.html +0 -168
- data/doc/rdoc/files/README.html +0 -213
- data/doc/rdoc/files/ext/http11/http11_c.html +0 -101
- data/doc/rdoc/files/lib/mongrel/camping_rb.html +0 -120
- data/doc/rdoc/files/lib/mongrel/cgi_rb.html +0 -120
- data/doc/rdoc/files/lib/mongrel/command_rb.html +0 -123
- data/doc/rdoc/files/lib/mongrel/configurator_rb.html +0 -111
- data/doc/rdoc/files/lib/mongrel/debug_rb.html +0 -122
- data/doc/rdoc/files/lib/mongrel/handlers_rb.html +0 -122
- data/doc/rdoc/files/lib/mongrel/init_rb.html +0 -121
- data/doc/rdoc/files/lib/mongrel/rails_rb.html +0 -123
- data/doc/rdoc/files/lib/mongrel/stats_rb.html +0 -113
- data/doc/rdoc/files/lib/mongrel/tcphack_rb.html +0 -113
- data/doc/rdoc/files/lib/mongrel_rb.html +0 -135
- data/doc/rdoc/files/lib/mutex_fix_rb.html +0 -108
- data/doc/rdoc/fr_class_index.html +0 -68
- data/doc/rdoc/fr_file_index.html +0 -42
- data/doc/rdoc/fr_method_index.html +0 -177
- data/doc/rdoc/index.html +0 -24
- data/doc/rdoc/rdoc-style.css +0 -208
- data/tools/rakehelp.rb +0 -117
data/lib/mongrel.rb
CHANGED
@@ -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.
|
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 "
|
266
|
-
|
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
|
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
|
441
|
-
write(Const::STATUS_FORMAT % [@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
|
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
|
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=
|
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
|
-
@
|
566
|
+
@throttle = throttle
|
566
567
|
@num_processors = num_processors
|
567
|
-
@
|
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.
|
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
|
-
|
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
|
645
|
-
rescue HttpParserError
|
646
|
-
|
647
|
-
|
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}:
|
654
|
-
STDERR.puts
|
658
|
+
rescue Object => e
|
659
|
+
STDERR.puts "#{Time.now}: Read error: #{e.inspect}"
|
660
|
+
STDERR.puts e.backtrace.join("\n")
|
655
661
|
ensure
|
656
|
-
|
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] > @
|
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.
|
685
|
-
#
|
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 #{@
|
690
|
-
sleep @
|
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
|
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 @
|
755
|
+
sleep @throttle/100.0 if @throttle > 0
|
741
756
|
end
|
742
757
|
rescue StopServer
|
743
|
-
@socket.close
|
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
|
751
|
-
rescue Object =>
|
752
|
-
STDERR.puts "
|
753
|
-
STDERR.puts
|
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
|
-
|
799
|
-
|
800
|
-
|
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
|
data/lib/mongrel/cgi.rb
CHANGED
@@ -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.
|
data/lib/mongrel/command.rb
CHANGED
@@ -179,7 +179,7 @@ module Mongrel
|
|
179
179
|
print_command_list
|
180
180
|
return true
|
181
181
|
elsif cmd_name == "--version"
|
182
|
-
|
182
|
+
puts "Mongrel Web Server #{Mongrel::Const::MONGREL_VERSION}"
|
183
183
|
return true
|
184
184
|
end
|
185
185
|
|
data/lib/mongrel/configurator.rb
CHANGED
@@ -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={}, &
|
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
|
51
|
-
cloaker(&
|
49
|
+
if block
|
50
|
+
cloaker(&block).bind(self).call
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
55
|
-
# Change
|
54
|
+
# Change privileges of the process to specified user and group.
|
56
55
|
def change_privilege(user, group)
|
57
56
|
begin
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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 "
|
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
|
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
|
-
#
|
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(&
|
102
|
+
def cloaker(&block)
|
94
103
|
cloaking_class.class_eval do
|
95
|
-
define_method :cloaker_, &
|
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.
|
118
|
-
# * :
|
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={},&
|
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[:
|
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
|
138
|
-
cloaker(&
|
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
|
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
|
|