public this repo is viewable by everyone
Description: Run multiple framework / rack app / wathever inside the same VM
Clone URL: git://github.com/macournoyer/rack_sandbox.git
first commit
macournoyer (author)
about 1 month ago
commit  95167f5720d92c1d2a3a02b9ba5963ac8aaa1cac
tree    7e2e5fa2883cb0730518ab567960c3e1df89d4aa
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0
@@ -0,0 +1,18 @@
0
+Copyright (c) 2008 Marc-Andre Cournoyer
0
+
0
+Permission is hereby granted, free of charge, to any person obtaining a copy
0
+of this software and associated documentation files (the "Software"), to
0
+deal in the Software without restriction, including without limitation the
0
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
0
+sell copies of the Software, and to permit persons to whom the Software is
0
+furnished to do so, subject to the following conditions:
0
+
0
+The above copyright notice and this permission notice shall be included in
0
+all copies or substantial portions of the Software.
0
+
0
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
0
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0
@@ -0,0 +1,41 @@
0
+== Rack Sandbox Adapter
0
+
0
+Run multiple framework / rack app / wathever inside the same VM
0
+using _why Freaky Freaky Sandbox: http://code.whytheluckystiff.net/sandbox/
0
+
0
+=== Installation
0
+
0
+Patch Ruby and install The Sandbox:
0
+http://code.whytheluckystiff.net/sandbox/wiki/InstallingTheSandbox
0
+
0
+=== Usage
0
+
0
+In config.ru:
0
+
0
+ require 'sandbox' # IMPORTANT: sandbox must be loaded before rubygems!
0
+ require 'rubygems'
0
+
0
+ require 'rack/adapter/sandboxed_rails'
0
+
0
+ map '/rails1' do
0
+ run Rack::Adapter::Sandbox.new %{
0
+ Rack::Adapter::Rails.new(:root => '/path/to/a/rails_app', :prefix => '/rails1')
0
+ }
0
+ end
0
+ map '/rails2' do
0
+ run Rack::Adapter::Sandbox.new %{
0
+ Rack::Adapter::Rails.new(:root => '/path/to/another/rails_app', :prefix => '/rails2')
0
+ }
0
+ end
0
+
0
+Run using Thin:
0
+
0
+ thin start -r config.ru
0
+
0
+You first Rails app will be available at /rails1 and the second one under /rails2.
0
+
0
+Enjoy!
0
+
0
+=== License
0
+Ruby License, http://www.ruby-lang.org/en/LICENSE.txt
0
+(C) Marc-Andre Cournoyer <macournoyer@gmail.com>
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
@@ -0,0 +1,21 @@
0
+$:.unshift File.dirname(__FILE__) + '/../lib'
0
+
0
+# IMPORTANT: sandbox must be loaded before rubygems!
0
+require 'sandbox'
0
+require 'rubygems'
0
+require 'rack/adapter/sandboxed_rails'
0
+require 'thin'
0
+
0
+# FIXME autoload doesn't work for some reason...
0
+require 'thin/connection'
0
+require 'thin/request'
0
+require 'thin/response'
0
+
0
+Thin::Server.start '0.0.0.0', 3000 do
0
+ map '/rails1' do
0
+ run Rack::Adapter::SandboxedRails.new(:root => '/Users/marc/projects/thin/spec/rails_app', :prefix => '/rails1')
0
+ end
0
+ map '/rails2' do
0
+ run Rack::Adapter::SandboxedRails.new(:root => '/Users/marc/projects/rails_app', :prefix => '/rails2')
0
+ end
0
+end
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0
@@ -0,0 +1,17 @@
0
+require 'rack/sandbox'
0
+
0
+module Rack
0
+ module Adapter
0
+ class SandboxedRails < Rack::Sandbox
0
+ def initialize(options)
0
+ super %{
0
+ require 'rubygems'
0
+ require 'rack'
0
+ require 'rack/adapter/rails'
0
+
0
+ app = Rack::Adapter::Rails.new(#{options.inspect})
0
+ }
0
+ end
0
+ end
0
+ end
0
+end
0
\ No newline at end of file
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
0
@@ -0,0 +1,62 @@
0
+require 'sandbox'
0
+require 'sandbox/marshal'
0
+
0
+module Rack
0
+ class Sandbox
0
+ def initialize(eval_code)
0
+ @box = ::Sandbox.new(:init => :all)
0
+
0
+ copy_globals
0
+ copy_env
0
+
0
+ # Load the adapter inside the sandbox
0
+ @box.eval %{
0
+ require 'sandbox/binding'
0
+ require 'sandbox/marshal'
0
+
0
+ #{eval_code}
0
+
0
+ nil
0
+ }
0
+ end
0
+
0
+ def call(env)
0
+ # Remove some values that can't be marshaled
0
+ env.delete('rack.errors')
0
+
0
+ # Call the adapter inside the sandbox,
0
+ # the response will be marshaled and sent
0
+ # back here in the jungle.
0
+ @box.set :env, env
0
+ @box.eval %{
0
+ status, headers, body = app.call(env)
0
+
0
+ # We ensure the response can be marshaled back to the
0
+ # jungle by converting it to a simpler object.
0
+ body_output = []
0
+ body.each { |l| body_output << l }
0
+
0
+ [status, headers, body_output]
0
+ }
0
+ end
0
+
0
+ protected
0
+ # Copy some constants and global variables inside the Sandbox
0
+ def copy_globals
0
+ %w(
0
+ ::File::ALT_SEPARATOR
0
+ ::File::SEPARATOR
0
+ ::File::PATH_SEPARATOR
0
+ $SAFE
0
+ ).each { |v| @box.set v, eval(v) }
0
+ # Copy loadpath
0
+ $:.each { |i| @box.eval("$: << #{i.inspect}") }
0
+ end
0
+
0
+ # Copy the environment variables (+ENV+).
0
+ def copy_env
0
+ @box.set :ENV, {}
0
+ ENV.each { |k,v| @box.eval("ENV[#{k.inspect}] = #{v.inspect}") }
0
+ end
0
+ end
0
+end
...
 
 
 
 
 
 
 
 
 
0
...
1
2
3
4
5
6
7
8
9
10
0
@@ -0,0 +1,9 @@
0
+# Binding extensions loaded inside the sandbox
0
+
0
+# Ok I confess, I have no idea what to do here.
0
+# I get some weird NoMethodError include on <Binding:XXXXX>
0
+class Binding
0
+ def include(i)
0
+ # FIXME wth?
0
+ end
0
+end
0
\ No newline at end of file
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0
@@ -0,0 +1,15 @@
0
+# Sandbox marshals object before sending them back in the Jungle.
0
+# Since we return the response we need to marshal some objects
0
+# that do not support marshaling out of the box.
0
+# This is loaded inside the Sandbox and in the Jungle (outside).
0
+
0
+require 'stringio'
0
+class StringIO
0
+ def marshal_dump
0
+ @string
0
+ end
0
+
0
+ def marshal_load(string)
0
+ @string = string
0
+ end
0
+end

Comments

    No one has commented yet.