jubilee 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.rbenv-version +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +54 -0
- data/Guardfile +24 -0
- data/README.md +61 -0
- data/Rakefile +94 -0
- data/VERSION +1 -0
- data/bin/jubilee +6 -0
- data/bin/jubilee_d +10 -0
- data/examples/jubilee/keystore.jks +0 -0
- data/examples/jubilee/server-keystore.jks +0 -0
- data/examples/ssl/ServerTest.java +19 -0
- data/examples/ssl/webroot/index.html +10 -0
- data/jars/netty-3.6.0.Beta1.jar +0 -0
- data/jars/vertx-core-1.3.0.final.jar +0 -0
- data/java/.idea/ant.xml +7 -0
- data/java/.idea/libraries/jruby.xml +9 -0
- data/java/.idea/libraries/netty_3_6_0_Beta1.xml +9 -0
- data/java/.idea/libraries/vertx_core_1_3_0_final.xml +9 -0
- data/java/src/jubilee/JubileeService.java +21 -0
- data/java/src/org/jruby/jubilee/Const.java +148 -0
- data/java/src/org/jruby/jubilee/RackApplication.java +78 -0
- data/java/src/org/jruby/jubilee/RackEnvironment.java +13 -0
- data/java/src/org/jruby/jubilee/RackErrors.java +44 -0
- data/java/src/org/jruby/jubilee/RackInput.java +62 -0
- data/java/src/org/jruby/jubilee/RackResponse.java +16 -0
- data/java/src/org/jruby/jubilee/Server.java +104 -0
- data/java/src/org/jruby/jubilee/deploy/Starter.java +26 -0
- data/java/src/org/jruby/jubilee/impl/DefaultRackEnvironment.java +98 -0
- data/java/src/org/jruby/jubilee/impl/NullIO.java +111 -0
- data/java/src/org/jruby/jubilee/impl/RubyIORackErrors.java +68 -0
- data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +164 -0
- data/lib/jubilee.rb +11 -0
- data/lib/jubilee/application.rb +13 -0
- data/lib/jubilee/cli.rb +74 -0
- data/lib/jubilee/configuration.rb +52 -0
- data/lib/jubilee/const.rb +39 -0
- data/lib/jubilee/jubilee.jar +0 -0
- data/lib/jubilee/response.rb +64 -0
- data/lib/jubilee/server.rb +16 -0
- data/lib/rack/handler/jubilee.rb +43 -0
- data/test/.rbenv-version +1 -0
- data/test/config/app.rb +5 -0
- data/test/jubilee/test_cli.rb +11 -0
- data/test/jubilee/test_config.rb +14 -0
- data/test/jubilee/test_persistent.rb +238 -0
- data/test/jubilee/test_rack_server.rb +116 -0
- data/test/jubilee/test_server.rb +68 -0
- data/test/sinatra_app/app.rb +31 -0
- data/test/sinatra_app/config.ru +6 -0
- data/test/sinatra_app/public/test.html +10 -0
- data/test/sinatra_app/unicorn.conf.rb +29 -0
- data/test/test_helper.rb +21 -0
- metadata +160 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
package org.jruby.jubilee.impl;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyModule;
|
6
|
+
import org.jruby.RubyObject;
|
7
|
+
import org.jruby.anno.JRubyMethod;
|
8
|
+
import org.jruby.jubilee.RackInput;
|
9
|
+
import org.jruby.runtime.Block;
|
10
|
+
import org.jruby.runtime.ObjectAllocator;
|
11
|
+
import org.jruby.runtime.ThreadContext;
|
12
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Created with IntelliJ IDEA.
|
16
|
+
* User: isaiah
|
17
|
+
* Date: 11/26/12
|
18
|
+
* Time: 12:11 PM
|
19
|
+
*/
|
20
|
+
public class NullIO extends RubyObject implements RackInput {
|
21
|
+
public static RubyClass createNullIOClass(Ruby ruby) {
|
22
|
+
RubyModule jModule = ruby.defineModule("Jubilee");
|
23
|
+
RubyClass nullIOClass = jModule.defineClassUnder("NullIO", ruby.getObject(), ALLOCATOR);
|
24
|
+
nullIOClass.defineAnnotatedMethods(NullIO.class);
|
25
|
+
return nullIOClass;
|
26
|
+
}
|
27
|
+
|
28
|
+
public static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
29
|
+
@Override
|
30
|
+
public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
|
31
|
+
return new NullIO(ruby, rubyClass);
|
32
|
+
}
|
33
|
+
};
|
34
|
+
|
35
|
+
public NullIO(Ruby ruby) {
|
36
|
+
this(ruby, createNullIOClass(ruby));
|
37
|
+
}
|
38
|
+
|
39
|
+
public NullIO(Ruby runtime, RubyClass metaClass) {
|
40
|
+
super(runtime, metaClass);
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* gets must be called without arguments and return a string, or nil on EOF.
|
45
|
+
*
|
46
|
+
* @param context it's a JRuby thing
|
47
|
+
* @return a string, or nil on EOF
|
48
|
+
*/
|
49
|
+
@Override
|
50
|
+
@JRubyMethod(name = "gets")
|
51
|
+
public IRubyObject gets(ThreadContext context) {
|
52
|
+
return getRuntime().getNil();
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* read behaves like IO#read. Its signature is read([length, [buffer]]). If given,
|
57
|
+
* length must be an non-negative Integer (>= 0) or nil, and buffer must be a
|
58
|
+
* String and may not be nil. If length is given and not nil, then this method
|
59
|
+
* reads at most length bytes from the input stream. If length is not given or
|
60
|
+
* nil, then this method reads all data until EOF. When EOF is reached, this
|
61
|
+
* method returns nil if length is given and not nil, or "" if length is not
|
62
|
+
* given or is nil. If buffer is given, then the read data will be placed into
|
63
|
+
* buffer instead of a newly created String object.
|
64
|
+
*
|
65
|
+
* @param context it's a JRuby thing
|
66
|
+
* @param args [length, [buffer]]
|
67
|
+
* @return nil if length is given and not nil, or "" if length is not given or nil
|
68
|
+
*/
|
69
|
+
@Override
|
70
|
+
@JRubyMethod(optional = 2)
|
71
|
+
public IRubyObject read(ThreadContext context, IRubyObject[] args) {
|
72
|
+
return getRuntime().getNil();
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* each must be called without arguments and only yield Strings.
|
77
|
+
*
|
78
|
+
* @param context it's a JRuby thing
|
79
|
+
* @param block that receives yield of Strings
|
80
|
+
* @return pretty much nil
|
81
|
+
*/
|
82
|
+
@Override
|
83
|
+
@JRubyMethod
|
84
|
+
public IRubyObject each(ThreadContext context, Block block) {
|
85
|
+
return getRuntime().getNil();
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* rewind must be called without arguments. It rewinds the input stream back
|
90
|
+
* to the beginning. It must not raise Errno::ESPIPE: that is, it may not be
|
91
|
+
* a pipe or a socket. Therefore, handler developers must buffer the input
|
92
|
+
* data into some rewindable object if the underlying input stream is not rewindable.
|
93
|
+
*
|
94
|
+
* @param context it's a JRuby thing
|
95
|
+
* @return pretty much nil
|
96
|
+
*/
|
97
|
+
@Override
|
98
|
+
@JRubyMethod
|
99
|
+
public IRubyObject rewind(ThreadContext context) {
|
100
|
+
return getRuntime().getNil();
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Close the input. Exposed only to the Java side because the Rack spec says
|
105
|
+
* that application code must not call close, so we don't expose a close method to Ruby.
|
106
|
+
*/
|
107
|
+
@Override
|
108
|
+
public IRubyObject close(ThreadContext context) {
|
109
|
+
return getRuntime().getNil();
|
110
|
+
}
|
111
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
package org.jruby.jubilee.impl;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyModule;
|
6
|
+
import org.jruby.RubyObject;
|
7
|
+
import org.jruby.anno.JRubyMethod;
|
8
|
+
import org.jruby.jubilee.RackErrors;
|
9
|
+
import org.jruby.runtime.ObjectAllocator;
|
10
|
+
import org.jruby.runtime.ThreadContext;
|
11
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Created with IntelliJ IDEA.
|
15
|
+
* User: isaiah
|
16
|
+
* Date: 11/26/12
|
17
|
+
* Time: 12:03 PM
|
18
|
+
*/
|
19
|
+
public class RubyIORackErrors extends RubyObject implements RackErrors {
|
20
|
+
|
21
|
+
public static RubyClass createRubyIORackErrorsClass(Ruby runtime) {
|
22
|
+
RubyModule jModule = runtime.defineModule("Jubilee");
|
23
|
+
RubyClass rackErrorsClass = jModule.defineClassUnder("RubyIORackErrors", runtime.getObject(), ALLOCATOR);
|
24
|
+
rackErrorsClass.defineAnnotatedMethods(RubyIORackErrors.class);
|
25
|
+
return rackErrorsClass;
|
26
|
+
}
|
27
|
+
|
28
|
+
public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
29
|
+
@Override
|
30
|
+
public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
|
31
|
+
return new RubyIORackErrors(ruby, rubyClass);
|
32
|
+
}
|
33
|
+
};
|
34
|
+
|
35
|
+
public RubyIORackErrors(Ruby runtime, RubyClass metaClass) {
|
36
|
+
super(runtime, metaClass);
|
37
|
+
}
|
38
|
+
|
39
|
+
public RubyIORackErrors(Ruby runtime) {
|
40
|
+
super(runtime, createRubyIORackErrorsClass(runtime));
|
41
|
+
}
|
42
|
+
|
43
|
+
@Override
|
44
|
+
@JRubyMethod(name = "puts")
|
45
|
+
public IRubyObject puts(ThreadContext context, IRubyObject arg) {
|
46
|
+
//getRuntime().getOutputStream().println(arg.toString());
|
47
|
+
return null; //To change body of implemented methods use File | Settings | File Templates.
|
48
|
+
}
|
49
|
+
|
50
|
+
@Override
|
51
|
+
@JRubyMethod
|
52
|
+
public IRubyObject write(ThreadContext context, IRubyObject string) {
|
53
|
+
//getRuntime().getOutputStream().println(string.toString());
|
54
|
+
return null; //To change body of implemented methods use File | Settings | File Templates.
|
55
|
+
}
|
56
|
+
|
57
|
+
@Override
|
58
|
+
@JRubyMethod
|
59
|
+
public IRubyObject flush() {
|
60
|
+
return null; //To change body of implemented methods use File | Settings | File Templates.
|
61
|
+
}
|
62
|
+
|
63
|
+
@Override
|
64
|
+
@JRubyMethod
|
65
|
+
public IRubyObject close() {
|
66
|
+
return null; //To change body of implemented methods use File | Settings | File Templates.
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
package org.jruby.jubilee.impl;
|
2
|
+
|
3
|
+
import org.jboss.netty.buffer.ChannelBuffer;
|
4
|
+
import org.jruby.*;
|
5
|
+
import org.jruby.anno.JRubyMethod;
|
6
|
+
import org.jruby.jubilee.Const;
|
7
|
+
import org.jruby.jubilee.RackInput;
|
8
|
+
import org.jruby.runtime.Block;
|
9
|
+
import org.jruby.runtime.ObjectAllocator;
|
10
|
+
import org.jruby.runtime.ThreadContext;
|
11
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
12
|
+
import org.vertx.java.core.buffer.Buffer;
|
13
|
+
|
14
|
+
import java.util.concurrent.CountDownLatch;
|
15
|
+
import java.util.concurrent.TimeUnit;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Created with IntelliJ IDEA.
|
19
|
+
* User: isaiah
|
20
|
+
* Date: 11/26/12
|
21
|
+
* Time: 10:12 PM
|
22
|
+
*/
|
23
|
+
public class RubyIORackInput extends RubyObject implements RackInput {
|
24
|
+
private ChannelBuffer buf;
|
25
|
+
private CountDownLatch bodyLatch;
|
26
|
+
|
27
|
+
public static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
28
|
+
@Override
|
29
|
+
public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
|
30
|
+
return new RubyIORackInput(ruby, rubyClass);
|
31
|
+
}
|
32
|
+
};
|
33
|
+
|
34
|
+
public static RubyClass createRubyIORackInputClass(Ruby runtime) {
|
35
|
+
RubyModule jModule = runtime.defineModule("Jubilee");
|
36
|
+
RubyClass rackIOInputClass = jModule.defineClassUnder("RubyIORackInput", runtime.getObject(), ALLOCATOR);
|
37
|
+
rackIOInputClass.defineAnnotatedMethods(RubyIORackInput.class);
|
38
|
+
return rackIOInputClass;
|
39
|
+
}
|
40
|
+
|
41
|
+
public RubyIORackInput(Ruby runtime, RubyClass metaClass) {
|
42
|
+
super(runtime, metaClass);
|
43
|
+
}
|
44
|
+
|
45
|
+
public RubyIORackInput(Ruby runtime, Buffer buf, CountDownLatch bodyLatch) {
|
46
|
+
this(runtime, createRubyIORackInputClass(runtime));
|
47
|
+
this.buf = buf.getChannelBuffer();
|
48
|
+
this.bodyLatch = bodyLatch;
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* gets must be called without arguments and return a string, or nil on EOF.
|
53
|
+
* <p/>
|
54
|
+
* this method return one line a time.
|
55
|
+
*
|
56
|
+
* @param context it's a JRuby thing
|
57
|
+
* @return a string, or nil on EOF
|
58
|
+
*/
|
59
|
+
@Override
|
60
|
+
@JRubyMethod
|
61
|
+
public IRubyObject gets(ThreadContext context) {
|
62
|
+
// TODO this is not the optimistic way. remove the latch and implement tee_input as unicorn
|
63
|
+
try {
|
64
|
+
bodyLatch.await(10, TimeUnit.SECONDS);
|
65
|
+
} catch (InterruptedException ignore) {
|
66
|
+
return getRuntime().getNil();
|
67
|
+
}
|
68
|
+
if (buf.readableBytes() == 0)
|
69
|
+
return getRuntime().getNil();
|
70
|
+
int lineEnd = buf.indexOf(buf.readerIndex(), buf.capacity(), Const.EOL);
|
71
|
+
int readLength;
|
72
|
+
if ((readLength = lineEnd - buf.readerIndex()) > 0) {
|
73
|
+
byte[] dst = new byte[readLength + 1];
|
74
|
+
buf.readBytes(dst, 0, readLength + 1);
|
75
|
+
return RubyString.newString(getRuntime(), dst);
|
76
|
+
}
|
77
|
+
return getRuntime().getNil();
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* read behaves like IO#read. Its signature is read([length, [buffer]]). If given,
|
82
|
+
* length must be an non-negative Integer (>= 0) or nil, and buffer must be a
|
83
|
+
* String and may not be nil. If length is given and not nil, then this method
|
84
|
+
* reads at most length bytes from the input stream. If length is not given or
|
85
|
+
* nil, then this method reads all data until EOF. When EOF is reached, this
|
86
|
+
* method returns nil if length is given and not nil, or "" if) length is not
|
87
|
+
* given or is nil. If buffer is given, then the read data will be placed into
|
88
|
+
* buffer instead of a newly created String object.
|
89
|
+
*
|
90
|
+
* @param context it's a JRuby thing
|
91
|
+
* @param args [length, [buffer]]
|
92
|
+
* @return nil if length is given and not nil, or "" if length is not given or nil
|
93
|
+
*/
|
94
|
+
@Override
|
95
|
+
@JRubyMethod(optional = 2)
|
96
|
+
public IRubyObject read(ThreadContext context, IRubyObject[] args) {
|
97
|
+
try {
|
98
|
+
bodyLatch.await(10, TimeUnit.SECONDS);
|
99
|
+
} catch (InterruptedException ignore) {
|
100
|
+
return getRuntime().getNil();
|
101
|
+
}
|
102
|
+
if (buf.readableBytes() == 0)
|
103
|
+
return getRuntime().getNil();
|
104
|
+
int length;
|
105
|
+
switch (args.length) {
|
106
|
+
case 0:
|
107
|
+
length = buf.readableBytes();
|
108
|
+
break;
|
109
|
+
case 1:
|
110
|
+
int len = RubyInteger.num2int(args[0]);
|
111
|
+
length = len > buf.readableBytes() ? buf.readableBytes() : len;
|
112
|
+
break;
|
113
|
+
default:
|
114
|
+
len = RubyInteger.num2int(args[0]);
|
115
|
+
length = len > buf.readableBytes() ? buf.readableBytes() : len;
|
116
|
+
}
|
117
|
+
byte[] dst = new byte[length];
|
118
|
+
buf.readBytes(dst, 0, length);
|
119
|
+
return RubyString.newString(getRuntime(), dst);
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* each must be called without arguments and only yield Strings.
|
124
|
+
*
|
125
|
+
* @param context it's a JRuby thing
|
126
|
+
* @param block that receives yield of Strings
|
127
|
+
* @return pretty much nil
|
128
|
+
*/
|
129
|
+
@Override
|
130
|
+
@JRubyMethod
|
131
|
+
public IRubyObject each(ThreadContext context, Block block) {
|
132
|
+
IRubyObject str;
|
133
|
+
while (!(str = gets(context)).isNil()) {
|
134
|
+
block.yield(context, str);
|
135
|
+
}
|
136
|
+
return getRuntime().getNil();
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* rewind must be called without arguments. It rewinds the input stream back
|
141
|
+
* to the beginning. It must not raise Errno::ESPIPE: that is, it may not be
|
142
|
+
* a pipe or a socket. Therefore, handler developers must buffer the input
|
143
|
+
* data into some rewindable object if the underlying input stream is not rewindable.
|
144
|
+
*
|
145
|
+
* @param context it's a JRuby thing
|
146
|
+
* @return pretty much nil
|
147
|
+
*/
|
148
|
+
@Override
|
149
|
+
@JRubyMethod
|
150
|
+
public IRubyObject rewind(ThreadContext context) {
|
151
|
+
buf.readerIndex(0);
|
152
|
+
return getRuntime().getNil();
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Close the input. Exposed only to the Java side because the Rack spec says
|
157
|
+
* that application code must not call close, so we don't expose a close method to Ruby.
|
158
|
+
*/
|
159
|
+
@JRubyMethod
|
160
|
+
public IRubyObject close(ThreadContext context) {
|
161
|
+
buf.clear();
|
162
|
+
return getRuntime().getNil();
|
163
|
+
}
|
164
|
+
}
|
data/lib/jubilee.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../jars/vertx-core-1.3.0.final.jar")
|
2
|
+
require File.join(File.dirname(__FILE__), "../jars/netty-3.6.0.Beta1.jar")
|
3
|
+
|
4
|
+
require 'jubilee/jubilee.jar'
|
5
|
+
require 'rack'
|
6
|
+
require 'jubilee/const'
|
7
|
+
require 'jubilee/server'
|
8
|
+
require 'jubilee/application'
|
9
|
+
require 'jubilee/configuration'
|
10
|
+
require 'jubilee/response'
|
11
|
+
require 'rack/handler/jubilee'
|
data/lib/jubilee/cli.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'jubilee'
|
3
|
+
require 'java'
|
4
|
+
|
5
|
+
module Jubilee
|
6
|
+
class CLI
|
7
|
+
# Parsed options
|
8
|
+
attr_accessor :options
|
9
|
+
def initialize(argv)
|
10
|
+
@argv = argv
|
11
|
+
setup_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_options
|
15
|
+
@parser.parse! @argv
|
16
|
+
if @argv.last
|
17
|
+
@options[:rackup] = @argv.shift
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
parse_options
|
23
|
+
@config = Jubilee::Configuration.new(@options)
|
24
|
+
@config.load
|
25
|
+
server = Jubilee::Server.new(@config.app, {port: @config.port, ssl: @config.ssl})
|
26
|
+
server.start
|
27
|
+
puts "Jubilee is listening on port #{@config.port}, press Ctrl+C to quit"
|
28
|
+
starter = org.jruby.jubilee.deploy.Starter.new
|
29
|
+
starter.block
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_options
|
33
|
+
@options = {
|
34
|
+
debug: false,
|
35
|
+
daemon: false,
|
36
|
+
port: 3215,
|
37
|
+
ssl: false,
|
38
|
+
environment: "development"
|
39
|
+
}
|
40
|
+
@parser = OptionParser.new do |o|
|
41
|
+
#o.on "-c", "--config PATH", "Load PATH as a config file" do |arg|
|
42
|
+
# @options[:config_file] = arg
|
43
|
+
#end
|
44
|
+
#o.on "-d", "--daemon", "Daemonize the server" do
|
45
|
+
# @options[:daemon] = true
|
46
|
+
#end
|
47
|
+
o.on "--dir DIR", "Change to DIR before starting" do |arg|
|
48
|
+
@options[:chdir] = arg
|
49
|
+
end
|
50
|
+
o.on "-p", "--port PORT", "Defind which PORT the server should bind" do |arg|
|
51
|
+
@options[:port] = arg
|
52
|
+
end
|
53
|
+
o.on "--ssl", "Enable SSL connection" do
|
54
|
+
@options[:ssl] = true
|
55
|
+
end
|
56
|
+
o.on "--verbose", "Log low level debug information" do
|
57
|
+
@options[:debug] = true
|
58
|
+
end
|
59
|
+
o.on "-e", "--environment ENV", "Rack environment" do |arg|
|
60
|
+
@options[:environment] = arg
|
61
|
+
end
|
62
|
+
o.on "-q", "--quiet" do
|
63
|
+
@options[:quiet] = true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
@parser.banner = "jubilee <options> <rackup file>"
|
68
|
+
@parser.on_tail "-h", "--help", "Show this message" do
|
69
|
+
puts @parser
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Jubilee
|
2
|
+
class Configuration
|
3
|
+
def initialize(options, &block)
|
4
|
+
@options = options
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def load
|
9
|
+
@app = load_rack_adapter(@options, &@block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def app
|
13
|
+
if !@options[:quiet] and @options[:environment] == "development"
|
14
|
+
logger = @options[:logger] || STDOUT
|
15
|
+
Rack::CommonLogger.new(@app, logger)
|
16
|
+
else
|
17
|
+
@app
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def port
|
22
|
+
@options[:port]
|
23
|
+
end
|
24
|
+
|
25
|
+
def ssl
|
26
|
+
@options[:ssl]
|
27
|
+
end
|
28
|
+
|
29
|
+
#def self.load(config)
|
30
|
+
# rackup_code = ::File.read(config)
|
31
|
+
# eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, config)
|
32
|
+
#end
|
33
|
+
|
34
|
+
private
|
35
|
+
def load_rack_adapter(options, &block)
|
36
|
+
if block
|
37
|
+
app = Rack::Builder.new(&block).to_app
|
38
|
+
else
|
39
|
+
if options[:rackup]
|
40
|
+
Kernel.load(options[:rackup])
|
41
|
+
app = Object.const_get(File.basename(options[:rackup], '.rb').capitalize.to_sym).new
|
42
|
+
else
|
43
|
+
Dir.chdir options[:chdir] if options[:chdir]
|
44
|
+
app, opts = Rack::Builder.parse_file "config.ru"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
app
|
48
|
+
#Rack::Lint.new(Rack::CommonLogger.new(app, STDOUT))
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|