em-rack-mongrel2 0.1.0 → 0.2.0
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.
- data/README.md +23 -14
- data/em-rack-mongrel2.gemspec +7 -3
- data/example/async_sinatra/app.rb +2 -2
- data/example/async_sinatra/config.ru +3 -4
- data/example/mongrel2.conf +7 -1
- data/example/sinatra/app.rb +3 -3
- data/example/sinatra/config.ru +3 -4
- data/example/upload/app.rb +36 -0
- data/example/upload/config.ru +7 -0
- data/lib/mongrel2/connection.rb +4 -8
- data/lib/mongrel2/request.rb +19 -26
- data/lib/mongrel2.rb +11 -11
- data/lib/rack/handler/mongrel2.rb +6 -5
- data/spec/request_spec.rb +81 -26
- data/spec/response_spec.rb +0 -1
- data/spec/spec_helper.rb +2 -1
- metadata +35 -45
data/README.md
CHANGED
@@ -22,31 +22,40 @@ Download all dependencies.
|
|
22
22
|
Run Mongrel2.
|
23
23
|
|
24
24
|
cd example
|
25
|
-
mkdir -p tmp/pids logs
|
25
|
+
mkdir -p tmp/pids logs run
|
26
26
|
m2sh load
|
27
|
-
m2sh start -name main
|
27
|
+
sudo m2sh start -name main
|
28
28
|
|
29
|
-
Run a simple sinatra example
|
29
|
+
Run a simple sinatra example,
|
30
30
|
|
31
31
|
cd sinatra
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
rackup -s Mongrel2 \
|
33
|
+
-O uuid=9539ED88-1B33-4D19-A9F9-283E5BF11AC7 \
|
34
|
+
-O send=tcp://127.0.0.1:9996 \
|
35
|
+
-O recv=tcp://127.0.0.1:9997
|
36
36
|
|
37
|
-
|
37
|
+
an async sinatra example or
|
38
38
|
|
39
39
|
cd async_sinatra
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
rackup -s Mongrel2 \
|
41
|
+
-O uuid=AEE66029-E420-42E7-A7C8-6C37BBFC7B9F \
|
42
|
+
-O send=tcp://127.0.0.1:9998 \
|
43
|
+
-O recv=tcp://127.0.0.1:9999
|
44
44
|
|
45
|
-
|
45
|
+
a big-upload example.
|
46
|
+
|
47
|
+
cd upload
|
48
|
+
rackup -s Mongrel2 \
|
49
|
+
-O uuid=51226E47-AE49-4BC8-A9C6-BD7F6827E8A4 \
|
50
|
+
-O send=tcp://127.0.0.1:10000 \
|
51
|
+
-O recv=tcp://127.0.0.1:10001 \
|
52
|
+
-O chroot=..
|
53
|
+
|
54
|
+
## How to use in your projects
|
46
55
|
|
47
56
|
1. Get mongrel2 installed (http://mongrel2.org/wiki/quick_start.html)
|
48
57
|
1. Get your config for mongrel2 setup (see example directory)
|
49
|
-
1. Add it to your Gemfile (gem 'em-rack-mongrel2'
|
58
|
+
1. Add it to your Gemfile (gem 'em-rack-mongrel2')
|
50
59
|
1. You also need some sort of JSON parsing library installed, like Yajl or JSON (gem i yajl-ruby or gem i json). json-jruby will work too
|
51
60
|
1. Run Mongrel2
|
52
61
|
1. Run your rack application
|
data/em-rack-mongrel2.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'em-rack-mongrel2'
|
16
|
-
s.version = '0.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.2.0'
|
17
|
+
s.date = '2012-02-12'
|
18
18
|
s.rubyforge_project = 'em-rack-mongrel2'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -42,6 +42,8 @@ Gem::Specification.new do |s|
|
|
42
42
|
## that are needed for an end user to actually USE your code.
|
43
43
|
s.add_dependency('ffi', ['~> 1.0.0'])
|
44
44
|
s.add_dependency('em-zeromq', ['~> 0.2.2'])
|
45
|
+
s.add_dependency('multi_json', ['~> 1.0.3'])
|
46
|
+
s.add_dependency('tnetstring', ['~> 0.3.4'])
|
45
47
|
|
46
48
|
## List your development dependencies here. Development dependencies are
|
47
49
|
## those that are only needed during development
|
@@ -66,6 +68,8 @@ Gem::Specification.new do |s|
|
|
66
68
|
example/sinatra/.gitignore
|
67
69
|
example/sinatra/app.rb
|
68
70
|
example/sinatra/config.ru
|
71
|
+
example/upload/app.rb
|
72
|
+
example/upload/config.ru
|
69
73
|
lib/mongrel2.rb
|
70
74
|
lib/mongrel2/connection.rb
|
71
75
|
lib/mongrel2/request.rb
|
@@ -81,4 +85,4 @@ Gem::Specification.new do |s|
|
|
81
85
|
## Test files will be grabbed from the file list. Make sure the path glob
|
82
86
|
## matches what you actually use.
|
83
87
|
s.test_files = s.files.select { |path| path =~ /^spec\/.*_spec\.rb/ }
|
84
|
-
end
|
88
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift File.expand_path('.') # Ruby 1.9 doesn't have . in the load path...
|
3
3
|
|
4
4
|
require 'rack/handler/mongrel2'
|
5
5
|
require 'app'
|
6
6
|
|
7
|
-
|
8
|
-
exit(0)
|
7
|
+
run AsyncExample
|
data/example/mongrel2.conf
CHANGED
@@ -7,6 +7,10 @@ darkblog2 = Host(name='localhost', routes={
|
|
7
7
|
send_ident='AEE66029-E420-42E7-A7C8-6C37BBFC7B9F',
|
8
8
|
recv_spec='tcp://127.0.0.1:9998',
|
9
9
|
recv_ident='')
|
10
|
+
'/upload/': Handler(send_spec='tcp://127.0.0.1:10001',
|
11
|
+
send_ident='51226E47-AE49-4BC8-A9C6-BD7F6827E8A4',
|
12
|
+
recv_spec='tcp://127.0.0.1:10000',
|
13
|
+
recv_ident='')
|
10
14
|
})
|
11
15
|
|
12
16
|
main = Server(
|
@@ -24,7 +28,9 @@ main = Server(
|
|
24
28
|
|
25
29
|
settings = {
|
26
30
|
'zeromq.threads': 1,
|
27
|
-
'control_port': 'ipc://tmp/mongrel2_control'
|
31
|
+
'control_port': 'ipc://tmp/mongrel2_control',
|
32
|
+
'upload.temp_store': '/tmp/mongrel2.upload.XXXXXX',
|
33
|
+
'limits.content_length': 1024
|
28
34
|
}
|
29
35
|
|
30
36
|
servers = [main]
|
data/example/sinatra/app.rb
CHANGED
data/example/sinatra/config.ru
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift File.expand_path('.') # Ruby 1.9 doesn't have . in the load path...
|
3
3
|
|
4
4
|
require 'rack/handler/mongrel2'
|
5
5
|
require 'app'
|
6
6
|
|
7
|
-
|
8
|
-
exit(0)
|
7
|
+
run Sinatra::Application
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'yajl/json_gem'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
set(:mongrel2_upload) do |value|
|
6
|
+
condition do
|
7
|
+
case value
|
8
|
+
when :start
|
9
|
+
request.env.key?('HTTP_X_MONGREL2_UPLOAD_START')
|
10
|
+
when :done
|
11
|
+
request.env.key?('HTTP_X_MONGREL2_UPLOAD_DONE')
|
12
|
+
else
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
pp request
|
20
|
+
end
|
21
|
+
|
22
|
+
put '/ok', :mongrel2_upload => :done do
|
23
|
+
'upload done'
|
24
|
+
end
|
25
|
+
|
26
|
+
put '/ok', :mongrel2_upload => :start do
|
27
|
+
throw :async # continue the upload
|
28
|
+
end
|
29
|
+
|
30
|
+
put '/ng', :mongrel2_upload => :done do
|
31
|
+
'this will never happen'
|
32
|
+
end
|
33
|
+
|
34
|
+
put '/ng', :mongrel2_upload => :start do
|
35
|
+
'' # cancel the upload
|
36
|
+
end
|
data/lib/mongrel2/connection.rb
CHANGED
@@ -1,18 +1,14 @@
|
|
1
|
-
require 'em-zeromq'
|
2
|
-
require 'mongrel2/request'
|
3
|
-
require 'mongrel2/response'
|
4
|
-
|
5
1
|
module Mongrel2
|
6
2
|
class Connection
|
7
|
-
attr_reader :
|
3
|
+
attr_reader :chroot
|
8
4
|
@context = nil
|
9
5
|
|
10
6
|
def self.context
|
11
|
-
|
7
|
+
@context ||= EM::ZeroMQ::Context.new(1)
|
12
8
|
end
|
13
9
|
|
14
|
-
def initialize(uuid, sub, pub, app)
|
15
|
-
@uuid, @sub, @pub, @app = uuid, sub, pub, app
|
10
|
+
def initialize(uuid, sub, pub, chroot, app)
|
11
|
+
@uuid, @sub, @pub, @chroot, @app = uuid, sub, pub, chroot, app
|
16
12
|
|
17
13
|
# Connect to receive requests
|
18
14
|
@reqs = self.class.context.connect(ZMQ::PULL, sub, self)
|
data/lib/mongrel2/request.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'mongrel2'
|
2
|
-
require 'rack'
|
3
|
-
require 'eventmachine'
|
4
|
-
|
5
1
|
module Mongrel2
|
6
2
|
class Request
|
7
3
|
attr_reader :headers, :body, :uuid, :conn_id, :path, :connection
|
@@ -10,25 +6,21 @@ module Mongrel2
|
|
10
6
|
def parse(msg, connection)
|
11
7
|
# UUID CONN_ID PATH SIZE:HEADERS,SIZE:BODY,
|
12
8
|
uuid, conn_id, path, rest = msg.split(' ', 4)
|
13
|
-
headers, rest =
|
14
|
-
|
15
|
-
|
9
|
+
headers, rest = TNetstring.parse(rest)
|
10
|
+
headers = MultiJson.decode(headers)
|
11
|
+
body, _ = TNetstring.parse(rest)
|
16
12
|
new(uuid, conn_id, path, headers, body, connection)
|
17
13
|
end
|
18
|
-
|
19
|
-
def parse_netstring(ns)
|
20
|
-
# SIZE:HEADERS,
|
21
|
-
|
22
|
-
len, rest = ns.split(':', 2)
|
23
|
-
len = len.to_i
|
24
|
-
raise "Netstring did not end in ','" unless rest[len].chr == ','
|
25
|
-
[rest[0, len], rest[(len + 1)..-1]]
|
26
|
-
end
|
27
14
|
end
|
28
15
|
|
29
16
|
def initialize(uuid, conn_id, path, headers, body, connection)
|
30
|
-
@uuid, @conn_id, @path, @headers
|
31
|
-
|
17
|
+
@uuid, @conn_id, @path, @headers = uuid, conn_id, path, headers
|
18
|
+
if (body_path = headers['x-mongrel2-upload-done'])
|
19
|
+
@body = File.open(File.join(connection.chroot, body_path))
|
20
|
+
else
|
21
|
+
@body = StringIO.new(body)
|
22
|
+
end
|
23
|
+
@data = headers['METHOD'] == 'JSON' ? MultiJson.decode(body) : {}
|
32
24
|
@connection = connection
|
33
25
|
end
|
34
26
|
|
@@ -41,18 +33,18 @@ module Mongrel2
|
|
41
33
|
end
|
42
34
|
|
43
35
|
def env
|
36
|
+
return @env if @env
|
44
37
|
script_name = ENV['RACK_RELATIVE_URL_ROOT'] || headers['PATTERN'].split('(', 2).first.gsub(/\/$/, '')
|
45
|
-
env = {
|
38
|
+
@env = {
|
46
39
|
'rack.version' => Rack::VERSION,
|
47
40
|
'rack.url_scheme' => 'http', # Only HTTP for now
|
48
|
-
'rack.input' =>
|
41
|
+
'rack.input' => body,
|
49
42
|
'rack.errors' => $stderr,
|
50
43
|
'rack.multithread' => true,
|
51
44
|
'rack.multiprocess' => true,
|
52
45
|
'rack.run_once' => false,
|
53
46
|
'mongrel2.pattern' => headers['PATTERN'],
|
54
47
|
'REQUEST_METHOD' => headers['METHOD'],
|
55
|
-
'CONTENT_TYPE' => headers['content-type'],
|
56
48
|
'SCRIPT_NAME' => script_name,
|
57
49
|
'PATH_INFO' => headers['PATH'].gsub(script_name, ''),
|
58
50
|
'QUERY_STRING' => headers['QUERY'] || '',
|
@@ -62,15 +54,16 @@ module Mongrel2
|
|
62
54
|
'async.close' => EM::DefaultDeferrable.new
|
63
55
|
}
|
64
56
|
|
65
|
-
env['SERVER_NAME'], env['SERVER_PORT'] = headers['host'].split(':', 2)
|
57
|
+
@env['SERVER_NAME'], @env['SERVER_PORT'] = headers['host'].split(':', 2)
|
66
58
|
headers.each do |key, val|
|
67
|
-
|
68
|
-
|
59
|
+
key = key.upcase.gsub('-', '_')
|
60
|
+
unless %w[CONTENT_TYPE CONTENT_LENGTH].include?(key)
|
61
|
+
key = "HTTP_#{key}"
|
69
62
|
end
|
70
|
-
env[key] = val
|
63
|
+
@env[key] = val
|
71
64
|
end
|
72
65
|
|
73
|
-
env
|
66
|
+
@env
|
74
67
|
end
|
75
68
|
end
|
76
69
|
end
|
data/lib/mongrel2.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
require 'rack'
|
2
|
+
require 'stringio'
|
3
|
+
require 'eventmachine'
|
4
|
+
require 'em-zeromq'
|
5
|
+
require 'multi_json'
|
6
|
+
require 'tnetstring'
|
7
|
+
|
8
|
+
require 'mongrel2/connection'
|
9
|
+
require 'mongrel2/request'
|
10
|
+
require 'mongrel2/response'
|
10
11
|
|
11
12
|
module Mongrel2
|
12
|
-
|
13
|
-
VERSION = '0.1.0'
|
13
|
+
VERSION = '0.2.0'
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
2
|
+
|
3
|
+
require 'mongrel2'
|
4
4
|
|
5
5
|
module Rack
|
6
6
|
module Handler
|
@@ -10,7 +10,8 @@ module Rack
|
|
10
10
|
options = {
|
11
11
|
:recv => ENV['RACK_MONGREL2_RECV'] || 'tcp://127.0.0.1:9997',
|
12
12
|
:send => ENV['RACK_MONGREL2_SEND'] || 'tcp://127.0.0.1:9996',
|
13
|
-
:uuid => ENV['RACK_MONGREL2_UUID']
|
13
|
+
:uuid => ENV['RACK_MONGREL2_UUID'],
|
14
|
+
:chroot => ENV['RACK_MONGREL2_CHROOT'] || '.'
|
14
15
|
}.merge(options)
|
15
16
|
|
16
17
|
raise ArgumentError.new('Must specify an :uuid or set RACK_MONGREL2_UUID') if options[:uuid].nil?
|
@@ -18,7 +19,7 @@ module Rack
|
|
18
19
|
conn = nil
|
19
20
|
|
20
21
|
EM.run do
|
21
|
-
conn = ::Mongrel2::Connection.new(options[:uuid], options[:recv], options[:send], app)
|
22
|
+
conn = ::Mongrel2::Connection.new(options[:uuid], options[:recv], options[:send], options[:chroot], app)
|
22
23
|
|
23
24
|
# This doesn't work at all until zmq fixes their shit (in 2.1.x I think), but trap it now anyway.
|
24
25
|
%w(INT TERM KILL).each do |sig|
|
data/spec/request_spec.rb
CHANGED
@@ -1,32 +1,45 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'mongrel2/request'
|
3
2
|
|
4
3
|
describe Mongrel2::Request do
|
5
|
-
it
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
it "should parse a Mongrel2 message" do
|
5
|
+
message = "UUID CON PATH 253:{\"PATH\":\"/\",\"user-agent\":\"curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3\",\"host\":\"localhost:6767\",\"accept\":\"*/*\",\"connection\":\"close\",\"x-forwarded-for\":\"::1\",\"METHOD\":\"GET\",\"VERSION\":\"HTTP/1.1\",\"URI\":\"/\",\"PATTERN\":\"/\"},0:,"
|
6
|
+
connection = double('connection')
|
7
|
+
uuid = 'UUID'
|
8
|
+
conn_id = 'CON'
|
9
|
+
path = 'PATH'
|
10
|
+
headers = {
|
11
|
+
'PATH' => '/',
|
12
|
+
'user-agent' => 'curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3',
|
13
|
+
'host' => 'localhost:6767',
|
14
|
+
'accept' => '*/*',
|
15
|
+
'connection' => 'close',
|
16
|
+
'x-forwarded-for' => '::1',
|
17
|
+
'METHOD' => 'GET',
|
18
|
+
'VERSION' => 'HTTP/1.1',
|
19
|
+
'URI' => '/',
|
20
|
+
'PATTERN' => '/'
|
21
|
+
}
|
22
|
+
body = ''
|
23
|
+
request = double('request')
|
24
|
+
Mongrel2::Request.should_receive(:new).with(uuid, conn_id, path, headers, body, connection).and_return(request)
|
25
|
+
r = Mongrel2::Request.parse(message, connection)
|
26
|
+
r.should eql(request)
|
11
27
|
end
|
12
28
|
|
13
|
-
it
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
it "should parse a Mongrel2 message and have all parts populated" do
|
28
|
-
netstring = "UUID CON PATH 253:{\"PATH\":\"/\",\"user-agent\":\"curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3\",\"host\":\"localhost:6767\",\"accept\":\"*/*\",\"connection\":\"close\",\"x-forwarded-for\":\"::1\",\"METHOD\":\"GET\",\"VERSION\":\"HTTP/1.1\",\"URI\":\"/\",\"PATTERN\":\"/\"},0:,"
|
29
|
-
r = Mongrel2::Request.parse(netstring, double())
|
29
|
+
it "should have all parts populated" do
|
30
|
+
headers = {
|
31
|
+
"PATH" => "/",
|
32
|
+
"user-agent" => "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3",
|
33
|
+
"host" => "localhost:6767",
|
34
|
+
"accept" => "*/*",
|
35
|
+
"connection" => "close",
|
36
|
+
"x-forwarded-for" => "::1",
|
37
|
+
"METHOD" => "GET",
|
38
|
+
"VERSION" => "HTTP/1.1",
|
39
|
+
"URI" => "/",
|
40
|
+
"PATTERN" => "/"
|
41
|
+
}
|
42
|
+
r = Mongrel2::Request.new('UUID', 'CON', 'PATH', headers, '', double())
|
30
43
|
r.should_not be_nil
|
31
44
|
r.uuid.should eql('UUID')
|
32
45
|
r.conn_id.should eql('CON')
|
@@ -46,13 +59,55 @@ describe Mongrel2::Request do
|
|
46
59
|
end
|
47
60
|
|
48
61
|
it "should return rack env with async callbacks" do
|
49
|
-
netstring = "UUID CON PATH 253:{\"PATH\":\"/\",\"user-agent\":\"curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3\",\"host\":\"localhost:6767\",\"accept\":\"*/*\",\"connection\":\"close\",\"x-forwarded-for\":\"::1\",\"METHOD\":\"GET\",\"VERSION\":\"HTTP/1.1\",\"URI\":\"/\",\"PATTERN\":\"/\"},0:,"
|
50
62
|
response = double("response")
|
63
|
+
uuid = double('uuid')
|
64
|
+
conn_id = double('conn_id')
|
65
|
+
path = double('path')
|
66
|
+
headers = {
|
67
|
+
"PATH" => "/",
|
68
|
+
"user-agent" => "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3",
|
69
|
+
"host" => "localhost:6767",
|
70
|
+
"accept" => "*/*",
|
71
|
+
"connection" => "close",
|
72
|
+
"x-forwarded-for" => "::1",
|
73
|
+
"METHOD" => "GET",
|
74
|
+
"VERSION" => "HTTP/1.1",
|
75
|
+
"URI" => "/",
|
76
|
+
"PATTERN" => "/"
|
77
|
+
}
|
78
|
+
body = double('body')
|
51
79
|
connection = double("connection")
|
52
|
-
r = Mongrel2::Request.
|
80
|
+
r = Mongrel2::Request.new(uuid, conn_id, path, headers, body, connection)
|
53
81
|
connection.should_receive(:post_process).with(response, r)
|
54
82
|
env = r.env
|
55
83
|
env['async.callback'].call(response)
|
56
84
|
env['async.close'].should_not be_nil
|
57
85
|
end
|
86
|
+
|
87
|
+
it "should open an async uploaded file for body" do
|
88
|
+
response = double("response")
|
89
|
+
uuid = double('uuid')
|
90
|
+
conn_id = double('conn_id')
|
91
|
+
path = double('path')
|
92
|
+
headers = {
|
93
|
+
"PATH" => "/",
|
94
|
+
"user-agent" => "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3",
|
95
|
+
"host" => "localhost:6767",
|
96
|
+
"accept" => "*/*",
|
97
|
+
"connection" => "close",
|
98
|
+
"x-forwarded-for" => "::1",
|
99
|
+
"METHOD" => "GET",
|
100
|
+
"VERSION" => "HTTP/1.1",
|
101
|
+
"URI" => "/",
|
102
|
+
"PATTERN" => "/",
|
103
|
+
'x-mongrel2-upload-done' => 'tmp/upload.file'
|
104
|
+
}
|
105
|
+
body = double('body')
|
106
|
+
connection = double("connection")
|
107
|
+
connection.stub(:chroot).and_return('.')
|
108
|
+
io = double('io')
|
109
|
+
File.should_receive(:open).with('./tmp/upload.file').and_return(io)
|
110
|
+
r = Mongrel2::Request.new(uuid, conn_id, path, headers, body, connection)
|
111
|
+
r.body.should eql(io)
|
112
|
+
end
|
58
113
|
end
|
data/spec/response_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-rack-mongrel2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
5
|
+
version: 0.2.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- ICHIBANGASE, Yutaka
|
@@ -15,7 +10,8 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2012-
|
13
|
+
date: 2012-02-12 00:00:00 +09:00
|
14
|
+
default_executable:
|
19
15
|
dependencies:
|
20
16
|
- !ruby/object:Gem::Dependency
|
21
17
|
name: ffi
|
@@ -25,11 +21,6 @@ dependencies:
|
|
25
21
|
requirements:
|
26
22
|
- - ~>
|
27
23
|
- !ruby/object:Gem::Version
|
28
|
-
hash: 23
|
29
|
-
segments:
|
30
|
-
- 1
|
31
|
-
- 0
|
32
|
-
- 0
|
33
24
|
version: 1.0.0
|
34
25
|
type: :runtime
|
35
26
|
version_requirements: *id001
|
@@ -41,62 +32,64 @@ dependencies:
|
|
41
32
|
requirements:
|
42
33
|
- - ~>
|
43
34
|
- !ruby/object:Gem::Version
|
44
|
-
hash: 19
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
- 2
|
48
|
-
- 2
|
49
35
|
version: 0.2.2
|
50
36
|
type: :runtime
|
51
37
|
version_requirements: *id002
|
52
38
|
- !ruby/object:Gem::Dependency
|
53
|
-
name:
|
39
|
+
name: multi_json
|
54
40
|
prerelease: false
|
55
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
56
42
|
none: false
|
57
43
|
requirements:
|
58
44
|
- - ~>
|
59
45
|
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
46
|
+
version: 1.0.3
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: tnetstring
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.3.4
|
58
|
+
type: :runtime
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rspec
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
65
68
|
version: 2.3.0
|
66
69
|
type: :development
|
67
|
-
version_requirements: *
|
70
|
+
version_requirements: *id005
|
68
71
|
- !ruby/object:Gem::Dependency
|
69
72
|
name: fuubar
|
70
73
|
prerelease: false
|
71
|
-
requirement: &
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
72
75
|
none: false
|
73
76
|
requirements:
|
74
77
|
- - ~>
|
75
78
|
- !ruby/object:Gem::Version
|
76
|
-
hash: 25
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
- 0
|
80
|
-
- 3
|
81
79
|
version: 0.0.3
|
82
80
|
type: :development
|
83
|
-
version_requirements: *
|
81
|
+
version_requirements: *id006
|
84
82
|
- !ruby/object:Gem::Dependency
|
85
83
|
name: yard
|
86
84
|
prerelease: false
|
87
|
-
requirement: &
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
88
86
|
none: false
|
89
87
|
requirements:
|
90
88
|
- - ~>
|
91
89
|
- !ruby/object:Gem::Version
|
92
|
-
hash: 15
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
- 6
|
96
|
-
- 4
|
97
90
|
version: 0.6.4
|
98
91
|
type: :development
|
99
|
-
version_requirements: *
|
92
|
+
version_requirements: *id007
|
100
93
|
description: A Rack handler for the Mongrel2 web server with EventMachine support, by Zed Shaw. http://mongrel2.org/
|
101
94
|
email: yichiban@gmail.com
|
102
95
|
executables: []
|
@@ -119,6 +112,8 @@ files:
|
|
119
112
|
- example/sinatra/.gitignore
|
120
113
|
- example/sinatra/app.rb
|
121
114
|
- example/sinatra/config.ru
|
115
|
+
- example/upload/app.rb
|
116
|
+
- example/upload/config.ru
|
122
117
|
- lib/mongrel2.rb
|
123
118
|
- lib/mongrel2/connection.rb
|
124
119
|
- lib/mongrel2/request.rb
|
@@ -128,6 +123,7 @@ files:
|
|
128
123
|
- spec/response_spec.rb
|
129
124
|
- spec/spec.opts
|
130
125
|
- spec/spec_helper.rb
|
126
|
+
has_rdoc: true
|
131
127
|
homepage: http://github.com/ichiban/em-rack-mongrel2
|
132
128
|
licenses: []
|
133
129
|
|
@@ -141,23 +137,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
137
|
requirements:
|
142
138
|
- - ">="
|
143
139
|
- !ruby/object:Gem::Version
|
144
|
-
hash: 3
|
145
|
-
segments:
|
146
|
-
- 0
|
147
140
|
version: "0"
|
148
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
142
|
none: false
|
150
143
|
requirements:
|
151
144
|
- - ">="
|
152
145
|
- !ruby/object:Gem::Version
|
153
|
-
hash: 3
|
154
|
-
segments:
|
155
|
-
- 0
|
156
146
|
version: "0"
|
157
147
|
requirements: []
|
158
148
|
|
159
149
|
rubyforge_project: em-rack-mongrel2
|
160
|
-
rubygems_version: 1.
|
150
|
+
rubygems_version: 1.6.2
|
161
151
|
signing_key:
|
162
152
|
specification_version: 2
|
163
153
|
summary: A Mongrel2 Rack handler with EventMachine.
|