m2r 0.0.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/README.md +141 -35
- data/Rakefile +13 -45
- data/example/Procfile +4 -0
- data/example/config.sqlite +0 -0
- data/example/http_0mq.rb +37 -19
- data/example/lobster.ru +14 -6
- data/example/mongrel2.conf +47 -0
- data/example/tmp/access.log +505 -0
- data/example/uploading.ru +37 -0
- data/lib/m2r.rb +49 -3
- data/lib/m2r/connection.rb +66 -0
- data/lib/m2r/connection_factory.rb +41 -0
- data/lib/m2r/handler.rb +130 -0
- data/lib/m2r/headers.rb +72 -0
- data/lib/m2r/rack_handler.rb +47 -0
- data/lib/m2r/request.rb +129 -0
- data/lib/m2r/request/base.rb +33 -0
- data/lib/m2r/request/upload.rb +60 -0
- data/lib/m2r/response.rb +102 -0
- data/lib/m2r/response/content_length.rb +18 -0
- data/lib/m2r/version.rb +5 -0
- data/lib/rack/handler/mongrel2.rb +33 -0
- data/m2r.gemspec +30 -63
- data/test/acceptance/examples_test.rb +32 -0
- data/test/support/capybara.rb +4 -0
- data/test/support/mongrel_helper.rb +40 -0
- data/test/support/test_handler.rb +51 -0
- data/test/support/test_user.rb +37 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/connection_factory_test.rb +29 -0
- data/test/unit/connection_test.rb +49 -0
- data/test/unit/handler_test.rb +41 -0
- data/test/unit/headers_test.rb +50 -0
- data/test/unit/m2r_test.rb +40 -0
- data/test/unit/rack_handler_test.rb +52 -0
- data/test/unit/request_test.rb +38 -0
- data/test/unit/response_test.rb +30 -0
- metadata +310 -105
- data/.document +0 -5
- data/.gitignore +0 -21
- data/ISSUES +0 -62
- data/VERSION +0 -1
- data/benchmarks/jruby +0 -60
- data/example/rack_handler.rb +0 -69
- data/lib/connection.rb +0 -158
- data/lib/fiber_handler.rb +0 -43
- data/lib/handler.rb +0 -66
- data/lib/request.rb +0 -44
- data/test/helper.rb +0 -10
- data/test/test_m2r.rb +0 -7
data/.document
DELETED
data/.gitignore
DELETED
data/ISSUES
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
On Ruby 1.9.2, ffi-rzmq crashes on even moderately high loads with the following stack. At this point, the only fix is to switch over to JRuby. I suspect that this crash has a lot to do with MRI's global interpreter lock (GIL). There's also a note about weird behavior on the ffi-rzmq github page, which counsels people to use JRuby, which doesn't have a GIL.
|
2
|
-
|
3
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80: [BUG] cfp consistency error - call0
|
4
|
-
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
5
|
-
|
6
|
-
-- control frame ----------
|
7
|
-
c:0014 p:---- s:0048 b:0048 l:000047 d:000047 CFUNC :(null)
|
8
|
-
c:0013 p:---- s:0046 b:0046 l:000045 d:000045 CFUNC :new
|
9
|
-
c:0012 p:0044 s:0040 b:0040 l:000039 d:000039 METHOD .rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80
|
10
|
-
c:0011 p:---- s:0035 b:0035 l:000034 d:000034 FINISH
|
11
|
-
c:0010 p:---- s:0033 b:0033 l:000032 d:000032 CFUNC :new
|
12
|
-
c:0009 p:0017 s:0030 b:0030 l:000029 d:000029 METHOD .rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293
|
13
|
-
c:0008 p:0022 s:0024 b:0023 l:000022 d:000022 METHOD /m2r/lib/connection.rb:42
|
14
|
-
c:0007 p:0021 s:0020 b:0020 l:000010 d:000019 BLOCK /m2r/lib/handler.rb:43
|
15
|
-
c:0006 p:---- s:0016 b:0016 l:000015 d:000015 FINISH
|
16
|
-
c:0005 p:---- s:0014 b:0014 l:000013 d:000013 CFUNC :loop
|
17
|
-
c:0004 p:0011 s:0011 b:0011 l:000010 d:000010 METHOD /m2r/lib/handler.rb:39
|
18
|
-
c:0003 p:0112 s:0008 b:0008 l:001598 d:000a68 EVAL example/http_0mq.rb:33
|
19
|
-
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
|
20
|
-
c:0001 p:0000 s:0002 b:0002 l:001598 d:001598 TOP
|
21
|
-
---------------------------
|
22
|
-
-- Ruby level backtrace information ----------------------------------------
|
23
|
-
example/http_0mq.rb:33:in `<main>'
|
24
|
-
/m2r/lib/handler.rb:39:in `listen'
|
25
|
-
/m2r/lib/handler.rb:39:in `loop'
|
26
|
-
/m2r/lib/handler.rb:43:in `block in listen'
|
27
|
-
/m2r/lib/connection.rb:42:in `recv'
|
28
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293:in `recv_string'
|
29
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293:in `new'
|
30
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80:in `initialize'
|
31
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80:in `new'
|
32
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80: [BUG] Segmentation fault
|
33
|
-
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
|
34
|
-
|
35
|
-
-- control frame ----------
|
36
|
-
c:0014 p:---- s:0048 b:0048 l:000047 d:000047 CFUNC :(null)
|
37
|
-
c:0013 p:---- s:0046 b:0046 l:000045 d:000045 CFUNC :new
|
38
|
-
c:0012 p:0044 s:0040 b:0040 l:000039 d:000039 METHOD .rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80
|
39
|
-
c:0011 p:---- s:0035 b:0035 l:000034 d:000034 FINISH
|
40
|
-
c:0010 p:---- s:0033 b:0033 l:000032 d:000032 CFUNC :new
|
41
|
-
c:0009 p:0017 s:0030 b:0030 l:000029 d:000029 METHOD .rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293
|
42
|
-
c:0008 p:0022 s:0024 b:0023 l:000022 d:000022 METHOD /m2r/lib/connection.rb:42
|
43
|
-
c:0007 p:0021 s:0020 b:0020 l:000010 d:000019 BLOCK /m2r/lib/handler.rb:43
|
44
|
-
c:0006 p:---- s:0016 b:0016 l:000015 d:000015 FINISH
|
45
|
-
c:0005 p:---- s:0014 b:0014 l:000013 d:000013 CFUNC :loop
|
46
|
-
c:0004 p:0011 s:0011 b:0011 l:000010 d:000010 METHOD /m2r/lib/handler.rb:39
|
47
|
-
c:0003 p:0112 s:0008 b:0008 l:001598 d:000a68 EVAL example/http_0mq.rb:33
|
48
|
-
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
|
49
|
-
c:0001 p:0000 s:0002 b:0002 l:001598 d:001598 TOP
|
50
|
-
---------------------------
|
51
|
-
-- Ruby level backtrace information ----------------------------------------
|
52
|
-
example/http_0mq.rb:33:in `<main>'
|
53
|
-
/m2r/lib/handler.rb:39:in `listen'
|
54
|
-
/m2r/lib/handler.rb:39:in `loop'
|
55
|
-
/m2r/lib/handler.rb:43:in `block in listen'
|
56
|
-
/m2r/lib/connection.rb:42:in `recv'
|
57
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293:in `recv_string'
|
58
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/socket.rb:293:in `new'
|
59
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80:in `initialize'
|
60
|
-
.rvm/gems/ruby-1.9.2-p0/gems/ffi-rzmq-0.5.0/lib/ffi-rzmq/message.rb:80:in `new'
|
61
|
-
|
62
|
-
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.3
|
data/benchmarks/jruby
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
Machine: 2.66GHZ Core 2 Duo
|
2
|
-
RAM: 4GB
|
3
|
-
|
4
|
-
w/ 1 worker running on JRuby 1.5.1 64-bit hotspot
|
5
|
-
--------------------------------------------------------------------------------------------------
|
6
|
-
httperf --server=localhost --num-conns 10 --num-calls 10000 --port 6767 --uri "/handlertest"
|
7
|
-
httperf --client=0/1 --server=localhost --port=6767 --uri=/handlertest --send-buffer=4096 --recv-buffer=16384 --num-conns=10 --num-calls=10000
|
8
|
-
httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE
|
9
|
-
Maximum connect burst length: 1
|
10
|
-
|
11
|
-
Total: connections 10 requests 100000 replies 100000 test-duration 278.142 s
|
12
|
-
|
13
|
-
Connection rate: 0.0 conn/s (27814.2 ms/conn, <=1 concurrent connections)
|
14
|
-
Connection time [ms]: min 23196.2 avg 27814.2 max 36479.8 median 25946.5 stddev 3871.1
|
15
|
-
Connection time [ms]: connect 1.1
|
16
|
-
Connection length [replies/conn]: 10000.000
|
17
|
-
|
18
|
-
Request rate: 359.5 req/s (2.8 ms/req)
|
19
|
-
Request size [B]: 73.0
|
20
|
-
|
21
|
-
Reply rate [replies/s]: min 165.0 avg 359.1 max 473.6 stddev 61.9 (55 samples)
|
22
|
-
Reply time [ms]: response 2.8 transfer 0.0
|
23
|
-
Reply size [B]: header 40.0 content 290.0 footer 0.0 (total 330.0)
|
24
|
-
Reply status: 1xx=0 2xx=100000 3xx=0 4xx=0 5xx=0
|
25
|
-
|
26
|
-
CPU time [s]: user 25.18 system 109.49 (user 9.1% system 39.4% total 48.4%)
|
27
|
-
Net I/O: 141.5 KB/s (1.2*10^6 bps)
|
28
|
-
|
29
|
-
Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
|
30
|
-
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
|
31
|
-
|
32
|
-
|
33
|
-
w/ 3 workers running on Jruby 1.5.1 64-bit hotspot
|
34
|
-
----------------------------------------------------------------------------------------------------
|
35
|
-
httperf --server=localhost --num-conns 10 --num-calls 10000 --port 6767 --uri "/handlertest"
|
36
|
-
httperf --client=0/1 --server=localhost --port=6767 --uri=/handlertest --send-buffer=4096 --recv-buffer=16384 --num-conns=10 --num-calls=10000
|
37
|
-
httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE
|
38
|
-
Maximum connect burst length: 1
|
39
|
-
|
40
|
-
Total: connections 10 requests 100000 replies 100000 test-duration 311.645 s
|
41
|
-
|
42
|
-
Connection rate: 0.0 conn/s (31164.5 ms/conn, <=1 concurrent connections)
|
43
|
-
Connection time [ms]: min 26030.3 avg 31164.5 max 40239.7 median 28590.5 stddev 4521.9
|
44
|
-
Connection time [ms]: connect 0.5
|
45
|
-
Connection length [replies/conn]: 10000.000
|
46
|
-
|
47
|
-
Request rate: 320.9 req/s (3.1 ms/req)
|
48
|
-
Request size [B]: 73.0
|
49
|
-
|
50
|
-
Reply rate [replies/s]: min 152.2 avg 320.6 max 409.4 stddev 56.1 (62 samples)
|
51
|
-
Reply time [ms]: response 3.1 transfer 0.0
|
52
|
-
Reply size [B]: header 40.0 content 290.0 footer 0.0 (total 330.0)
|
53
|
-
Reply status: 1xx=0 2xx=100000 3xx=0 4xx=0 5xx=0
|
54
|
-
|
55
|
-
CPU time [s]: user 30.40 system 134.12 (user 9.8% system 43.0% total 52.8%)
|
56
|
-
Net I/O: 126.3 KB/s (1.0*10^6 bps)
|
57
|
-
|
58
|
-
Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
|
59
|
-
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
|
60
|
-
|
data/example/rack_handler.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rack'
|
3
|
-
require 'stringio'
|
4
|
-
# require 'ruby-debug'
|
5
|
-
# Debugger.start
|
6
|
-
# gem install ruby-debug19 -- --with-ruby-include=$HOME/.rvm/src/ruby-1.9.2-head
|
7
|
-
|
8
|
-
$: << ::File.expand_path(::File.dirname(__FILE__) + '/../lib')
|
9
|
-
require 'connection'
|
10
|
-
|
11
|
-
$sender_id = "70D107AB-19F5-44AE-A2D0-2326A167D8D7"
|
12
|
-
|
13
|
-
module Rack
|
14
|
-
module Handler
|
15
|
-
class Mongrel2
|
16
|
-
def self.run(app, receive = "tcp://127.0.0.1:9997", send = "tcp://127.0.0.1:9996")
|
17
|
-
conn = ::Mongrel2::Connection.new($sender_id, receive, send)
|
18
|
-
@running = true
|
19
|
-
trap("SIGINT") do
|
20
|
-
@running = false
|
21
|
-
end
|
22
|
-
|
23
|
-
while @running
|
24
|
-
puts "WAITING FOR REQUEST"
|
25
|
-
|
26
|
-
req = conn.recv # Caution: Abort traps on SIGINT :/
|
27
|
-
if req.disconnect?
|
28
|
-
puts "DICONNECT"
|
29
|
-
next
|
30
|
-
end
|
31
|
-
|
32
|
-
script_name = ENV["RACK_RELATIVE_URL_ROOT"] ||
|
33
|
-
# PATTERN is like: /test/(.*.json) or /handlertest
|
34
|
-
req.headers["PATTERN"].split('(', 2).first.gsub(/\/$/, '')
|
35
|
-
|
36
|
-
env = {
|
37
|
-
"rack.version" => Rack::VERSION,
|
38
|
-
"rack.url_scheme" => "http",
|
39
|
-
"rack.input" => StringIO.new(req.body),
|
40
|
-
"rack.errors" => $stderr,
|
41
|
-
"rack.multithread" => true,
|
42
|
-
"rack.multiprocess" => true,
|
43
|
-
"rack.run_once" => false,
|
44
|
-
|
45
|
-
"mongrel2.pattern" => req.headers["PATTERN"],
|
46
|
-
|
47
|
-
"REQUEST_METHOD" => req.headers["METHOD"],
|
48
|
-
"SCRIPT_NAME" => script_name,
|
49
|
-
"PATH_INFO" => req.headers["PATH"].gsub(script_name, ''),
|
50
|
-
"QUERY_STRING" => req.headers["QUERY"]
|
51
|
-
}
|
52
|
-
|
53
|
-
env["SERVER_NAME"], env["SERVER_PORT"] = req.headers["host"].split(':', 2)
|
54
|
-
req.headers.each do |key, val|
|
55
|
-
unless key =~ /content_(type|length)/i
|
56
|
-
key = "HTTP_#{key.upcase}"
|
57
|
-
end
|
58
|
-
env[key] = val
|
59
|
-
end
|
60
|
-
|
61
|
-
status, headers, rack_response = app.call(env)
|
62
|
-
body = ""
|
63
|
-
rack_response.each{|b| body << b}
|
64
|
-
conn.reply_http(req, body, status, headers)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
data/lib/connection.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
# On OSX:
|
2
|
-
# sudo port install zmq
|
3
|
-
# sudo gem install zmq
|
4
|
-
# RUBY_ENGINE = 'ruby'
|
5
|
-
require 'rubygems'
|
6
|
-
gem 'ffi-rzmq'
|
7
|
-
gem 'json'
|
8
|
-
require 'ffi-rzmq'
|
9
|
-
require 'json'
|
10
|
-
|
11
|
-
$: << File.dirname(__FILE__)
|
12
|
-
require 'request'
|
13
|
-
|
14
|
-
CTX = ZMQ::Context.new(1)
|
15
|
-
|
16
|
-
module Mongrel2
|
17
|
-
# A Connection object manages the connection between your handler
|
18
|
-
# and a Mongrel2 server (or servers). It can receive raw requests
|
19
|
-
# or JSON encoded requests whether from HTTP or MSG request types,
|
20
|
-
# and it can send individual responses or batch responses either
|
21
|
-
# raw or as JSON. It also has a way to encode HTTP responses
|
22
|
-
# for simplicity since that'll be fairly common.
|
23
|
-
class Connection
|
24
|
-
|
25
|
-
def initialize(sender_id, sub_addr, pub_addr)
|
26
|
-
@sender_id = sender_id
|
27
|
-
|
28
|
-
@reqs = CTX.socket(ZMQ::UPSTREAM)
|
29
|
-
@reqs.connect(sub_addr)
|
30
|
-
|
31
|
-
@resp = CTX.socket(ZMQ::PUB)
|
32
|
-
@resp.connect(pub_addr)
|
33
|
-
@resp.setsockopt(ZMQ::IDENTITY, sender_id)
|
34
|
-
|
35
|
-
@sub_addr = sub_addr
|
36
|
-
@pub_addr = pub_addr
|
37
|
-
end
|
38
|
-
|
39
|
-
# Receives a raw Request object that you
|
40
|
-
# can then work with.
|
41
|
-
def recv
|
42
|
-
Request.parse(@reqs.recv_string(0))
|
43
|
-
end
|
44
|
-
|
45
|
-
# Same as regular recv, but assumes the body is JSON and
|
46
|
-
# creates a new attribute named req.data with the decoded
|
47
|
-
# payload. This will throw an error if it is not JSON.
|
48
|
-
#
|
49
|
-
# Normally Request just does this if the METHOD is 'JSON'
|
50
|
-
# but you can use this to force it for say HTTP requests.
|
51
|
-
def recv_json
|
52
|
-
self.recv.tap do |req|
|
53
|
-
req.data ||= JSON.parse(req.body)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Raw send to the given connection ID, mostly used
|
58
|
-
# internally.
|
59
|
-
def send_resp(uuid, conn_id, msg)
|
60
|
-
header = "%s %d:%s," % [uuid, conn_id.size, conn_id]
|
61
|
-
string = header + ' ' + msg
|
62
|
-
#puts "DEBUG: #{string.inspect}"
|
63
|
-
@resp.send_string(string, 0)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Does a reply based on the given Request object and message.
|
67
|
-
# This is easier since the req object contains all the info
|
68
|
-
# needed to do the proper reply addressing.
|
69
|
-
def reply(req, msg)
|
70
|
-
self.send_resp(req.sender, req.conn_id, msg)
|
71
|
-
end
|
72
|
-
|
73
|
-
# Same as reply, but tries to convert data to JSON first.
|
74
|
-
def reply_json(req, data)
|
75
|
-
self.send_resp(req.sender, req.conn_id, JSON.generate(data))
|
76
|
-
end
|
77
|
-
|
78
|
-
# Basic HTTP response mechanism which will take your body,
|
79
|
-
# any headers you've made, and encode them so that the
|
80
|
-
# browser gets them.
|
81
|
-
def reply_http(req, body, code=200, headers={})
|
82
|
-
self.reply(req, http_response(body, code, headers))
|
83
|
-
end
|
84
|
-
|
85
|
-
# This lets you send a single message to many currently
|
86
|
-
# connected clients. There's a MAX_IDENTS that you should
|
87
|
-
# not exceed, so chunk your targets as needed. Each target
|
88
|
-
# will receive the message once by Mongrel2, but you don't have
|
89
|
-
# to loop which cuts down on reply volume.
|
90
|
-
def deliver(uuid, idents, data)
|
91
|
-
self.send_resp(uuid, idents.join(' '), data)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Same as deliver, but converts to JSON first.
|
95
|
-
def deliver_json(uuid, idents, data)
|
96
|
-
self.deliver(uuid, idents, JSON.generate(data))
|
97
|
-
end
|
98
|
-
|
99
|
-
# Same as deliver, but builds an HTTP response, which means, yes,
|
100
|
-
# you can reply to multiple connected clients waiting for an HTTP
|
101
|
-
# response from one handler. Kinda cool.
|
102
|
-
def deliver_http(uuid, idents, body, code=200, headers={})
|
103
|
-
self.deliver(uuid, idents, http_response(body, code, headers))
|
104
|
-
end
|
105
|
-
|
106
|
-
private
|
107
|
-
def http_response(body, code, headers)
|
108
|
-
headers['Content-Length'] = body.size
|
109
|
-
headers_s = headers.map{|k, v| "%s: %s" % [k,v]}.join("\r\n")
|
110
|
-
|
111
|
-
"HTTP/1.1 #{code} #{StatusMessage[code.to_i]}\r\n#{headers_s}\r\n\r\n#{body}"
|
112
|
-
end
|
113
|
-
|
114
|
-
# From WEBrick: thanks dawg.
|
115
|
-
StatusMessage = {
|
116
|
-
100 => 'Continue',
|
117
|
-
101 => 'Switching Protocols',
|
118
|
-
200 => 'OK',
|
119
|
-
201 => 'Created',
|
120
|
-
202 => 'Accepted',
|
121
|
-
203 => 'Non-Authoritative Information',
|
122
|
-
204 => 'No Content',
|
123
|
-
205 => 'Reset Content',
|
124
|
-
206 => 'Partial Content',
|
125
|
-
300 => 'Multiple Choices',
|
126
|
-
301 => 'Moved Permanently',
|
127
|
-
302 => 'Found',
|
128
|
-
303 => 'See Other',
|
129
|
-
304 => 'Not Modified',
|
130
|
-
305 => 'Use Proxy',
|
131
|
-
307 => 'Temporary Redirect',
|
132
|
-
400 => 'Bad Request',
|
133
|
-
401 => 'Unauthorized',
|
134
|
-
402 => 'Payment Required',
|
135
|
-
403 => 'Forbidden',
|
136
|
-
404 => 'Not Found',
|
137
|
-
405 => 'Method Not Allowed',
|
138
|
-
406 => 'Not Acceptable',
|
139
|
-
407 => 'Proxy Authentication Required',
|
140
|
-
408 => 'Request Timeout',
|
141
|
-
409 => 'Conflict',
|
142
|
-
410 => 'Gone',
|
143
|
-
411 => 'Length Required',
|
144
|
-
412 => 'Precondition Failed',
|
145
|
-
413 => 'Request Entity Too Large',
|
146
|
-
414 => 'Request-URI Too Large',
|
147
|
-
415 => 'Unsupported Media Type',
|
148
|
-
416 => 'Request Range Not Satisfiable',
|
149
|
-
417 => 'Expectation Failed',
|
150
|
-
500 => 'Internal Server Error',
|
151
|
-
501 => 'Not Implemented',
|
152
|
-
502 => 'Bad Gateway',
|
153
|
-
503 => 'Service Unavailable',
|
154
|
-
504 => 'Gateway Timeout',
|
155
|
-
505 => 'HTTP Version Not Supported'
|
156
|
-
}
|
157
|
-
end # class Connection
|
158
|
-
end # mod Mongrel2
|
data/lib/fiber_handler.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
module Mongrel2
|
2
|
-
class FiberHandler < Handler
|
3
|
-
def initialize(*args)
|
4
|
-
raise "This handler is just around for testing. don't use it, it'll suck."
|
5
|
-
end
|
6
|
-
|
7
|
-
def fiber_handle
|
8
|
-
@fiber ||= Fiber.new do |request|
|
9
|
-
loop do
|
10
|
-
on_request(request)
|
11
|
-
|
12
|
-
# run on_disconnect if the server disconnects
|
13
|
-
if request.disconnect?
|
14
|
-
on_disconnect
|
15
|
-
request = Fiber.yield
|
16
|
-
next
|
17
|
-
end
|
18
|
-
|
19
|
-
# get the response from on_request
|
20
|
-
response = process(request)
|
21
|
-
|
22
|
-
# run the response through a filter
|
23
|
-
response = after_process(response, request)
|
24
|
-
|
25
|
-
# send it back to the server on the PUB socket
|
26
|
-
@connection.reply_http(request, response)
|
27
|
-
|
28
|
-
after_reply(request, response)
|
29
|
-
request = Fiber.yield
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def listen
|
35
|
-
loop do
|
36
|
-
on_wait
|
37
|
-
request = @connection.recv
|
38
|
-
fiber_handle.resume(request)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
data/lib/handler.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
module Mongrel2
|
2
|
-
class Handler
|
3
|
-
attr_accessor :connection
|
4
|
-
def initialize(sender_uuid, subscribe_address, publish_address)
|
5
|
-
@connection = Mongrel2::Connection.new(sender_uuid,
|
6
|
-
subscribe_address, publish_address)
|
7
|
-
end
|
8
|
-
|
9
|
-
# Callback for when the handler is waiting for a request
|
10
|
-
def on_wait(*args)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Callback when a request is received (for debug)
|
14
|
-
def on_request(request, *args)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Override this to return a custom response
|
18
|
-
def process(request, *args)
|
19
|
-
puts "PROCESS REQUEST: #{request}"
|
20
|
-
#raise NoHandlerDefined, "define process_request in your subclass"
|
21
|
-
return request.inspect
|
22
|
-
end
|
23
|
-
|
24
|
-
# Callback for when the server disconnects
|
25
|
-
def on_disconnect(request, *args)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Callback after process_request is done
|
29
|
-
def after_process(response, request, *args)
|
30
|
-
return response
|
31
|
-
end
|
32
|
-
|
33
|
-
# Callback after the server gets the response
|
34
|
-
def after_reply(request, response, *args)
|
35
|
-
end
|
36
|
-
|
37
|
-
# the body of the main recv loop
|
38
|
-
def listen
|
39
|
-
loop do
|
40
|
-
on_wait
|
41
|
-
|
42
|
-
# get the request from Mongrel2 on the UPSTREAM socket
|
43
|
-
request = @connection.recv
|
44
|
-
# run the on_request hook
|
45
|
-
on_request(request)
|
46
|
-
|
47
|
-
# run on_disconnect if the server disconnects
|
48
|
-
if request.disconnect?
|
49
|
-
on_disconnect
|
50
|
-
next
|
51
|
-
end
|
52
|
-
|
53
|
-
# get the response from on_request
|
54
|
-
response = process(request)
|
55
|
-
|
56
|
-
# run the response through a filter
|
57
|
-
response = after_process(response, request)
|
58
|
-
|
59
|
-
# send it back to the server on the PUB socket
|
60
|
-
@connection.reply_http(request, response)
|
61
|
-
|
62
|
-
after_reply(request, response)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|