jubilee 1.0.2 → 1.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG +17 -0
- data/Gemfile +19 -1
- data/Gemfile.lock +189 -31
- data/LICENSE.txt +20 -0
- data/README.md +44 -5
- data/ROADMAP +5 -0
- data/Rakefile +6 -5
- data/examples/chatapp/Gemfile +2 -1
- data/examples/chatapp/Gemfile.lock +8 -6
- data/examples/chatapp/README.md +5 -2
- data/examples/chatapp/app.rb +24 -0
- data/examples/chatapp/public/assets/javascripts/application.js +59 -6
- data/examples/chatapp/public/assets/stylesheets/application.css +25 -0
- data/examples/jubilee.conf.rb +0 -3
- data/jars/{hazelcast-2.6.jar → hazelcast-2.6.3.jar} +0 -0
- data/jars/{netty-all-4.0.4.Final.jar → netty-all-4.0.13.Final.jar} +0 -0
- data/jars/vertx-core-2.1M3-SNAPSHOT.jar +0 -0
- data/jars/vertx-hazelcast-2.1M3-SNAPSHOT.jar +0 -0
- data/java/src/jubilee/JubileeService.java +7 -7
- data/java/src/org/jruby/jubilee/Const.java +10 -35
- data/java/src/org/jruby/jubilee/RackApplication.java +77 -46
- data/java/src/org/jruby/jubilee/RackResponse.java +1 -3
- data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +88 -0
- data/java/src/org/jruby/jubilee/{Server.java → RubyServer.java} +17 -14
- data/java/src/org/jruby/jubilee/impl/RackEnvironment.java +157 -0
- data/java/src/org/jruby/jubilee/impl/RackEnvironmentHash.java +449 -0
- data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +5 -5
- data/java/src/org/jruby/jubilee/impl/{NullIO.java → RubyNullIO.java} +5 -9
- data/java/src/org/jruby/jubilee/utils/RubyHelper.java +37 -0
- data/jubilee.gemspec +101 -14
- data/lib/jubilee.rb +4 -3
- data/lib/jubilee/cli.rb +2 -1
- data/lib/jubilee/configuration.rb +4 -9
- data/lib/jubilee/const.rb +2 -2
- data/lib/jubilee/jubilee.jar +0 -0
- data/lib/jubilee/response.rb +9 -8
- data/lib/jubilee/server.rb +1 -1
- data/lib/jubilee/version.rb +8 -1
- data/lib/rack/chunked.rb +38 -0
- data/spec/apps/rack/basic/config.ru +50 -0
- data/spec/apps/rails4/basic/.gitignore +16 -0
- data/spec/apps/rails4/basic/Gemfile +41 -0
- data/spec/apps/rails4/basic/Gemfile.lock +127 -0
- data/spec/apps/rails4/basic/README.rdoc +28 -0
- data/spec/apps/rails4/basic/Rakefile +6 -0
- data/spec/apps/rails4/basic/app/assets/images/.keep +0 -0
- data/spec/apps/rails4/basic/app/assets/images/rails.png +0 -0
- data/spec/apps/rails4/basic/app/assets/javascripts/application.js +16 -0
- data/spec/apps/rails4/basic/app/assets/stylesheets/application.css +13 -0
- data/spec/apps/rails4/basic/app/controllers/application_controller.rb +5 -0
- data/spec/apps/rails4/basic/app/controllers/concerns/.keep +0 -0
- data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb +11 -0
- data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb.erb +11 -0
- data/spec/apps/rails4/basic/app/controllers/root_controller.rb +14 -0
- data/spec/apps/rails4/basic/app/helpers/application_helper.rb +2 -0
- data/spec/apps/rails4/basic/app/mailers/.keep +0 -0
- data/spec/apps/rails4/basic/app/models/.keep +0 -0
- data/spec/apps/rails4/basic/app/models/concerns/.keep +0 -0
- data/spec/apps/rails4/basic/app/views/layouts/application.html.erb +14 -0
- data/spec/apps/rails4/basic/app/views/reloader/index.html.erb +1 -0
- data/spec/apps/rails4/basic/app/views/root/index.html.erb +8 -0
- data/spec/apps/rails4/basic/app/views/root/streaming.html.erb +6 -0
- data/spec/apps/rails4/basic/bin/bundle +3 -0
- data/spec/apps/rails4/basic/bin/rails +4 -0
- data/spec/apps/rails4/basic/bin/rake +4 -0
- data/spec/apps/rails4/basic/config.ru +4 -0
- data/spec/apps/rails4/basic/config/application.rb +23 -0
- data/spec/apps/rails4/basic/config/boot.rb +4 -0
- data/spec/apps/rails4/basic/config/database.yml +20 -0
- data/spec/apps/rails4/basic/config/environment.rb +5 -0
- data/spec/apps/rails4/basic/config/environments/development.rb +29 -0
- data/spec/apps/rails4/basic/config/environments/production.rb +80 -0
- data/spec/apps/rails4/basic/config/environments/test.rb +36 -0
- data/spec/apps/rails4/basic/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/apps/rails4/basic/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/apps/rails4/basic/config/initializers/inflections.rb +16 -0
- data/spec/apps/rails4/basic/config/initializers/mime_types.rb +5 -0
- data/spec/apps/rails4/basic/config/initializers/secret_token.rb +12 -0
- data/spec/apps/rails4/basic/config/initializers/session_store.rb +2 -0
- data/spec/apps/rails4/basic/config/initializers/wrap_parameters.rb +14 -0
- data/spec/apps/rails4/basic/config/locales/en.yml +23 -0
- data/spec/apps/rails4/basic/config/routes.rb +5 -0
- data/spec/apps/rails4/basic/db/seeds.rb +7 -0
- data/spec/apps/rails4/basic/lib/assets/.keep +0 -0
- data/spec/apps/rails4/basic/lib/tasks/.keep +0 -0
- data/spec/apps/rails4/basic/public/404.html +58 -0
- data/spec/apps/rails4/basic/public/422.html +58 -0
- data/spec/apps/rails4/basic/public/500.html +57 -0
- data/spec/apps/rails4/basic/public/favicon.ico +0 -0
- data/spec/apps/rails4/basic/public/robots.txt +5 -0
- data/spec/apps/rails4/basic/public/some_page.html +7 -0
- data/spec/apps/rails4/basic/test/controllers/.keep +0 -0
- data/spec/apps/rails4/basic/test/fixtures/.keep +0 -0
- data/spec/apps/rails4/basic/test/helpers/.keep +0 -0
- data/spec/apps/rails4/basic/test/integration/.keep +0 -0
- data/spec/apps/rails4/basic/test/mailers/.keep +0 -0
- data/spec/apps/rails4/basic/test/models/.keep +0 -0
- data/spec/apps/rails4/basic/test/test_helper.rb +15 -0
- data/spec/apps/rails4/basic/vendor/assets/javascripts/.keep +0 -0
- data/spec/apps/rails4/basic/vendor/assets/stylesheets/.keep +0 -0
- data/spec/apps/sinatra/basic/Gemfile +4 -0
- data/spec/apps/sinatra/basic/Gemfile.lock +20 -0
- data/spec/apps/sinatra/basic/basic.rb +27 -0
- data/spec/apps/sinatra/basic/config.ru +7 -0
- data/spec/apps/sinatra/basic/public/some_page.html +7 -0
- data/spec/apps/sinatra/basic/views/index.erb +4 -0
- data/spec/apps/sinatra/basic/views/posted.haml +2 -0
- data/spec/apps/sinatra/basic/views/poster.haml +4 -0
- data/spec/apps/sinatra/basic/views/request_mapping.haml +4 -0
- data/spec/integration/basic_rack_spec.rb +89 -0
- data/spec/integration/basic_rails4_spec.rb +64 -0
- data/spec/integration/basic_sinatra_spec.rb +80 -0
- data/spec/spec_helper.rb +13 -0
- data/test/jubilee/test_cli.rb +1 -1
- data/test/jubilee/test_configuration.rb +18 -1
- data/test/jubilee/test_rack_server.rb +7 -7
- data/test/jubilee/test_response.rb +35 -36
- data/test/jubilee/test_server.rb +1 -1
- data/test/jubilee/test_upload.rb +14 -11
- data/test/test_helper.rb +1 -0
- metadata +97 -18
- data/VERSION +0 -1
- data/jars/vertx-core-2.1.0-SNAPSHOT.jar +0 -0
- data/java/src/org/jruby/jubilee/RackErrors.java +0 -44
- data/java/src/org/jruby/jubilee/impl/DefaultRackEnvironment.java +0 -99
- data/java/src/org/jruby/jubilee/impl/RubyIORackErrors.java +0 -68
data/Rakefile
CHANGED
@@ -28,16 +28,17 @@ Jeweler::Tasks.new do |gem|
|
|
28
28
|
gem.homepage = "http://github.com/isaiah/jubilee"
|
29
29
|
gem.license = "MIT"
|
30
30
|
gem.summary = %Q{More than a server for rack applications.}
|
31
|
-
gem.description = %Q{Jubilee is a
|
31
|
+
gem.description = %Q{Jubilee is a jruby webserver built upon Vertx.}
|
32
32
|
gem.email = "issaria@gmail.com"
|
33
33
|
gem.authors = ["Isaiah Peng"]
|
34
|
+
gem.version = Jubilee::Version::STRING
|
34
35
|
# dependencies defined in Gemfile
|
35
36
|
end
|
36
37
|
Jeweler::RubygemsDotOrgTasks.new
|
37
38
|
|
38
39
|
require 'rake/testtask'
|
39
40
|
Rake::TestTask.new(:test) do |test|
|
40
|
-
test.libs << 'lib' << 'test'
|
41
|
+
test.libs << 'lib' << 'test' << 'spec'
|
41
42
|
test.pattern = 'test/**/test_*.rb'
|
42
43
|
test.verbose = true
|
43
44
|
end
|
@@ -56,7 +57,7 @@ task :default => :test
|
|
56
57
|
|
57
58
|
require 'rdoc/task'
|
58
59
|
Rake::RDocTask.new do |rdoc|
|
59
|
-
version = Jubilee::
|
60
|
+
version = Jubilee::Version::STRING
|
60
61
|
|
61
62
|
rdoc.rdoc_dir = 'rdoc'
|
62
63
|
rdoc.title = "jubilee #{version}"
|
@@ -80,7 +81,7 @@ desc "Compile the extension, need jdk7 because vertx relies on it"
|
|
80
81
|
task :compile => "pkg/classes" do |t|
|
81
82
|
ant.javac :srcdir => "java", :destdir => t.prerequisites.first,
|
82
83
|
:source => "1.7", :target => "1.7", :debug => true,
|
83
|
-
:classpath => "${java.class.path}:${sun.boot.class.path}:jars/vertx-core-2.
|
84
|
+
:classpath => "${java.class.path}:${sun.boot.class.path}:jars/vertx-core-2.1M3-SNAPSHOT.jar:jars/netty-all-4.0.13.Final.jar:jars/jackson-core-2.2.2.jar:jars/jackson-databind-2.2.2.jar:jars/jackson-annotations-2.2.2.jar:jars/hazelcast-2.6.3.jar"
|
84
85
|
end
|
85
86
|
|
86
87
|
desc "Build the jar"
|
@@ -88,7 +89,7 @@ task :jar => [:clean, :compile] do
|
|
88
89
|
ant.jar :basedir => "pkg/classes", :destfile => "lib/jubilee/jubilee.jar", :includes => "**/*.class"
|
89
90
|
end
|
90
91
|
|
91
|
-
task :
|
92
|
+
task :build => :jar
|
92
93
|
|
93
94
|
desc "Run the specs"
|
94
95
|
task :spec => :jar do
|
data/examples/chatapp/Gemfile
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
GEM
|
2
|
+
remote: https://rubygems.org/
|
2
3
|
specs:
|
3
|
-
ffi (1.9.
|
4
|
-
|
4
|
+
ffi (1.9.3)
|
5
|
+
ffi (1.9.3-java)
|
6
|
+
haml (4.0.4)
|
5
7
|
tilt
|
6
|
-
jubilee (1.0.
|
8
|
+
jubilee (1.0.2)
|
7
9
|
rack (>= 1.4.1)
|
8
10
|
spoon (~> 0.0.4)
|
9
11
|
rack (1.5.2)
|
10
|
-
rack-protection (1.5.
|
12
|
+
rack-protection (1.5.1)
|
11
13
|
rack
|
12
|
-
sinatra (1.4.
|
14
|
+
sinatra (1.4.4)
|
13
15
|
rack (~> 1.4)
|
14
16
|
rack-protection (~> 1.4)
|
15
17
|
tilt (~> 1.3, >= 1.3.4)
|
@@ -22,5 +24,5 @@ PLATFORMS
|
|
22
24
|
|
23
25
|
DEPENDENCIES
|
24
26
|
haml
|
25
|
-
jubilee (
|
27
|
+
jubilee (~> 1.0.2)
|
26
28
|
sinatra
|
data/examples/chatapp/README.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
Get started
|
2
2
|
-----------
|
3
3
|
|
4
|
-
|
4
|
+
There is a [online demo](http://192.241.201.68:8080/) for this
|
5
|
+
application.
|
6
|
+
|
7
|
+
Make sure you are using jruby 1.7+ (jubilee 1.1.0+ require jruby 1.7.5 or later) and your JDK version is 7+
|
5
8
|
|
6
9
|
To run the application:
|
7
10
|
|
@@ -9,6 +12,6 @@ To run the application:
|
|
9
12
|
bundle && jubilee --eventbus /eventbus
|
10
13
|
```
|
11
14
|
|
12
|
-
Then go to http://localhost:
|
15
|
+
Then go to http://localhost:8080 in your browser, if you have the page
|
13
16
|
opened in multiple tabs or windows you can see the message you sent are
|
14
17
|
broadcasted to all the other tabs.
|
data/examples/chatapp/app.rb
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
Bundler.require(:default)
|
3
|
+
require 'vertx'
|
4
|
+
|
5
|
+
def to_a(shared_set)
|
6
|
+
ret = []
|
7
|
+
shared_set.each{ |item| ret << item}
|
8
|
+
ret
|
9
|
+
end
|
10
|
+
|
11
|
+
Vertx::EventBus.register_handler('logout') do |message|
|
12
|
+
Vertx::SharedData.get_set(:users).delete(message.body)
|
13
|
+
end
|
14
|
+
|
15
|
+
# register the user and return the pervious users
|
16
|
+
Vertx::EventBus.register_handler('login') do |message|
|
17
|
+
user = message.body
|
18
|
+
users = Vertx::SharedData.get_set(:users).add(user)
|
19
|
+
message.reply(users: to_a(users))
|
20
|
+
Vertx::EventBus.publish("new_user", user)
|
21
|
+
end
|
22
|
+
|
3
23
|
|
4
24
|
get "/" do
|
5
25
|
haml :index
|
@@ -24,6 +44,10 @@ __END__
|
|
24
44
|
@@index
|
25
45
|
#updates
|
26
46
|
|
47
|
+
%p
|
48
|
+
%label receiver
|
49
|
+
%select#receivers(name="receiver")
|
50
|
+
%option all
|
27
51
|
%p
|
28
52
|
%textarea#content(name="content" rows=8 cols=80)
|
29
53
|
|
@@ -1,14 +1,67 @@
|
|
1
|
+
// To generate a random id
|
2
|
+
function s4() {
|
3
|
+
return Math.floor((1 + Math.random()) * 0x10000)
|
4
|
+
.toString(16)
|
5
|
+
.substring(1);
|
6
|
+
};
|
7
|
+
|
1
8
|
$(function() {
|
2
9
|
var eb = new vertx.EventBus("/eventbus");
|
10
|
+
var updates = $("#updates");
|
11
|
+
var uid = "Guest_" + s4();
|
3
12
|
|
4
13
|
eb.onopen = function() {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
14
|
+
eb.send("login", uid, function(data){
|
15
|
+
for(var i = 0; i < data.users.length; i++) {
|
16
|
+
if (data.users[i] != uid) $("#receivers").append("<option>" + data.users[i] + "</option>");
|
17
|
+
}
|
18
|
+
});
|
19
|
+
updates.html("<h5>Welcome to the Jubilee chat room!</h5>");
|
20
|
+
eb.registerHandler("chat", function(data) {
|
21
|
+
if (data.sender != uid)
|
22
|
+
updates.append("<div class='public'><span class='sender'>" + data.sender + " said:</span>" + data.message + "</div>");
|
23
|
+
else
|
24
|
+
updates.append("<div class='public by_you'><span class='sender'>You said:</span>" + data.message + "</div>");
|
25
|
+
});
|
26
|
+
|
27
|
+
eb.registerHandler("new_user", function(data) {
|
28
|
+
if (data != uid) {
|
29
|
+
$("#receivers").append("<option>" + data + "</option");
|
30
|
+
updates.append("<div class='login'>" + data + " joined the room.</div>");
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
eb.registerHandler(uid, function(data) {
|
35
|
+
updates.append("<div class='private'><span class='sender'>" + data.sender + " said to you:</span>" + data.message + "</div>");
|
36
|
+
});
|
37
|
+
|
38
|
+
eb.registerHandler("logout", function(data) {
|
39
|
+
$('#receivers option:contains("' + data + '")').remove();
|
40
|
+
updates.append("<div class='logout'>" + data + " left the room.</div>");
|
41
|
+
});
|
9
42
|
|
10
|
-
|
11
|
-
|
43
|
+
window.onbeforeunload = function() {
|
44
|
+
eb.publish("logout", uid);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
var sendMessage = function() {
|
49
|
+
var msg = $("#content").val();
|
50
|
+
if ((receiver = $("#receivers").val()) === "all") {
|
51
|
+
eb.publish("chat", {sender: uid, message: msg});
|
52
|
+
} else {
|
53
|
+
updates.append("<div class='public by_you'><span class='sender'>You said to " + uid + ":</span>" + msg + "</div>");
|
54
|
+
eb.send(receiver, {sender: uid, message: msg});
|
55
|
+
}
|
12
56
|
$("#content").val("");
|
57
|
+
}
|
58
|
+
|
59
|
+
$("#send").click(sendMessage);
|
60
|
+
|
61
|
+
$(document.body).keyup(function(ev) {
|
62
|
+
if (ev.which === 13) {
|
63
|
+
sendMessage();
|
64
|
+
}
|
13
65
|
});
|
66
|
+
|
14
67
|
});
|
@@ -2,3 +2,28 @@
|
|
2
2
|
min-height: 400px;
|
3
3
|
border: 1px solid #ccc;
|
4
4
|
}
|
5
|
+
|
6
|
+
.public, .private, .login, .logout {
|
7
|
+
border-bottom: 1px solid #CCCCCC;
|
8
|
+
line-height: 1.2em;
|
9
|
+
}
|
10
|
+
|
11
|
+
.private {
|
12
|
+
color: blue;
|
13
|
+
}
|
14
|
+
|
15
|
+
.login {
|
16
|
+
color: green;
|
17
|
+
}
|
18
|
+
.logout {
|
19
|
+
color: red;
|
20
|
+
}
|
21
|
+
.by_you {
|
22
|
+
color: gray;
|
23
|
+
}
|
24
|
+
.sender {
|
25
|
+
display: inline-block;
|
26
|
+
width: 168px;
|
27
|
+
font-size: 0.8em;
|
28
|
+
font-style: italic;
|
29
|
+
}
|
data/examples/jubilee.conf.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,20 +1,20 @@
|
|
1
1
|
package jubilee;
|
2
2
|
|
3
3
|
import org.jruby.Ruby;
|
4
|
-
import org.jruby.jubilee.
|
5
|
-
import org.jruby.jubilee.
|
6
|
-
import org.jruby.jubilee.impl.RubyIORackErrors;
|
4
|
+
import org.jruby.jubilee.RubyHttpServerResponse;
|
5
|
+
import org.jruby.jubilee.RubyServer;
|
7
6
|
import org.jruby.jubilee.impl.RubyIORackInput;
|
7
|
+
import org.jruby.jubilee.impl.RubyNullIO;
|
8
8
|
import org.jruby.runtime.load.BasicLibraryService;
|
9
9
|
|
10
10
|
import java.io.IOException;
|
11
11
|
|
12
12
|
public class JubileeService implements BasicLibraryService {
|
13
13
|
public boolean basicLoad(final Ruby ruby) throws IOException {
|
14
|
-
|
15
|
-
|
16
|
-
RubyIORackInput.
|
17
|
-
|
14
|
+
RubyServer.createServerClass(ruby);
|
15
|
+
RubyHttpServerResponse.createHttpServerResponseClass(ruby);
|
16
|
+
RubyIORackInput.createIORackInputClass(ruby);
|
17
|
+
RubyNullIO.createNullIOClass(ruby);
|
18
18
|
return true;
|
19
19
|
}
|
20
20
|
}
|
@@ -14,10 +14,11 @@ import java.util.Map;
|
|
14
14
|
*/
|
15
15
|
public final class Const {
|
16
16
|
|
17
|
-
public static final String JUBILEE_VERSION = "Jubilee
|
17
|
+
public static final String JUBILEE_VERSION = "Jubilee(1.1.0)";
|
18
18
|
public static final String HTTP_11 = "HTTP/1.1";
|
19
19
|
public static final String HTTP_10 = "HTTP/1.0";
|
20
20
|
|
21
|
+
public static final String SCRIPT_NAME = "SCRIPT_NAME";
|
21
22
|
public static final String SERVER_SOFTWARE = "SERVER_SOFTWARE";
|
22
23
|
public static final String SERVER_PROTOCOL = "SERVER_PROTOCOL";
|
23
24
|
public static final String GATEWAY_INTERFACE = "GATEWAY_INTERFACE";
|
@@ -50,7 +51,7 @@ public final class Const {
|
|
50
51
|
public static final String HTTP_CONTENT_LENGTH = "CONTENT_LENGTH";
|
51
52
|
|
52
53
|
public static class Rack {
|
53
|
-
public static final String
|
54
|
+
public static final String HTTP_AUTHORIZATION = "HTTP_AUTHORIZATION";
|
54
55
|
public static final String HTTP_EXPECT = "HTTP_EXPECT";
|
55
56
|
public static final String HTTP_IF_MATCH = "HTTP_IF_MATCH";
|
56
57
|
public static final String HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE";
|
@@ -78,13 +79,15 @@ public final class Const {
|
|
78
79
|
public static final String ACCEPT = "accept";
|
79
80
|
public static final String ACCEPT_LANGUAGE = "accept-language";
|
80
81
|
public static final String ACCEPT_ENCODING = "accept-encoding";
|
82
|
+
public static final String AUTHORIZATION = "authorization";
|
81
83
|
public static final String CONNECTION = "connection";
|
82
|
-
public static final String CONTENT_TYPE = "
|
83
|
-
public static final String CONTENT_LENGTH = "
|
84
|
+
public static final String CONTENT_TYPE = "Content-Type";
|
85
|
+
public static final String CONTENT_LENGTH = "Content-Length";
|
84
86
|
public static final String CONTENT_MD5 = "content-md5";
|
85
87
|
public static final String HOST = "host";
|
86
88
|
|
87
|
-
public static final String
|
89
|
+
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
|
90
|
+
|
88
91
|
public static final String EXPECT = "expect";
|
89
92
|
public static final String IF_MATCH = "if-match";
|
90
93
|
public static final String IF_MODIFIED_SINCE = "if-modified-since";
|
@@ -104,35 +107,6 @@ public final class Const {
|
|
104
107
|
public static final String X_FORWARDED_FOR = "x-forwarded-for"; // original ip
|
105
108
|
}
|
106
109
|
|
107
|
-
public static Map<String, String> ADDITIONAL_HEADERS = new HashMap<String, String>();
|
108
|
-
|
109
|
-
static {
|
110
|
-
ADDITIONAL_HEADERS.put(Vertx.DATE, Rack.HTTP_DATE);
|
111
|
-
ADDITIONAL_HEADERS.put(Vertx.EXPECT, Rack.HTTP_EXPECT);
|
112
|
-
ADDITIONAL_HEADERS.put(Vertx.IF_MATCH, Rack.HTTP_IF_MATCH);
|
113
|
-
ADDITIONAL_HEADERS.put(Vertx.IF_MODIFIED_SINCE, Rack.HTTP_IF_MODIFIED_SINCE);
|
114
|
-
ADDITIONAL_HEADERS.put(Vertx.IF_NONE_MATCH, Rack.HTTP_IF_NONE_MATCH);
|
115
|
-
ADDITIONAL_HEADERS.put(Vertx.IF_RANGE, Rack.HTTP_IF_RANGE);
|
116
|
-
ADDITIONAL_HEADERS.put(Vertx.IF_UNMODIFIED_SINCE, Rack.HTTP_IF_UNMODIFIED_SINCE);
|
117
|
-
ADDITIONAL_HEADERS.put(Vertx.RANGE, Rack.HTTP_RANGE);
|
118
|
-
ADDITIONAL_HEADERS.put(Vertx.PRAGMA, Rack.HTTP_PRAGMA);
|
119
|
-
ADDITIONAL_HEADERS.put(Vertx.MAX_FORWARDS, Rack.HTTP_MAX_FORWARDS);
|
120
|
-
ADDITIONAL_HEADERS.put(Vertx.REFERER, Rack.HTTP_REFERER);
|
121
|
-
ADDITIONAL_HEADERS.put(Vertx.VIA, Rack.HTTP_VIA);
|
122
|
-
ADDITIONAL_HEADERS.put(Vertx.WARNING, Rack.HTTP_WARNING);
|
123
|
-
ADDITIONAL_HEADERS.put(Vertx.X_REQUESTED_WITH, Rack.HTTP_X_REQUESTED_WITH);
|
124
|
-
ADDITIONAL_HEADERS.put(Vertx.DNT, Rack.HTTP_DNT);
|
125
|
-
ADDITIONAL_HEADERS.put(Vertx.X_FORWARDED_FOR, Rack.HTTP_X_FORWARDED_FOR);
|
126
|
-
ADDITIONAL_HEADERS.put(Vertx.CONTENT_MD5, Rack.HTTP_CONTENT_MD5);
|
127
|
-
}
|
128
|
-
|
129
|
-
public static RubyArray RackVersion(Ruby runtime) {
|
130
|
-
RubyArray version = RubyArray.newArray(runtime, 2);
|
131
|
-
version.add("1");
|
132
|
-
version.add("4");
|
133
|
-
return version;
|
134
|
-
}
|
135
|
-
|
136
110
|
public static final String HTTP = "http";
|
137
111
|
public static final String HTTPS = "https";
|
138
112
|
public static final String URL_SCHEME = "rack.url_scheme";
|
@@ -141,7 +115,8 @@ public final class Const {
|
|
141
115
|
public static final String RACK_MULTITHREAD = "rack.multithread";
|
142
116
|
public static final String RACK_MULTIPROCESS = "rack.multiprocess";
|
143
117
|
public static final String RACK_RUNONCE = "rack.run_once";
|
144
|
-
|
118
|
+
|
119
|
+
public static final String RACK_HIJACK_P = "rack.hijack?";
|
145
120
|
|
146
121
|
private Const() {
|
147
122
|
}
|
@@ -3,17 +3,23 @@ package org.jruby.jubilee;
|
|
3
3
|
import io.netty.buffer.ByteBuf;
|
4
4
|
import io.netty.buffer.Unpooled;
|
5
5
|
import org.jruby.Ruby;
|
6
|
+
import org.jruby.RubyArray;
|
7
|
+
import org.jruby.RubyClass;
|
8
|
+
import org.jruby.RubyFixnum;
|
6
9
|
import org.jruby.javasupport.JavaEmbedUtils;
|
7
|
-
import org.jruby.jubilee.impl.
|
10
|
+
import org.jruby.jubilee.impl.RackEnvironment;
|
8
11
|
import org.jruby.jubilee.impl.RubyIORackInput;
|
12
|
+
import org.jruby.jubilee.impl.RubyNullIO;
|
13
|
+
import org.jruby.runtime.ThreadContext;
|
9
14
|
import org.jruby.runtime.builtin.IRubyObject;
|
10
15
|
import org.vertx.java.core.Handler;
|
16
|
+
import org.vertx.java.core.Vertx;
|
11
17
|
import org.vertx.java.core.VoidHandler;
|
12
18
|
import org.vertx.java.core.buffer.Buffer;
|
13
19
|
import org.vertx.java.core.http.HttpServerRequest;
|
20
|
+
import org.vertx.java.core.impl.DefaultVertx;
|
14
21
|
|
15
|
-
import java.
|
16
|
-
import java.util.concurrent.Executors;
|
22
|
+
import java.io.IOException;
|
17
23
|
import java.util.concurrent.atomic.AtomicBoolean;
|
18
24
|
|
19
25
|
/**
|
@@ -23,51 +29,76 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|
23
29
|
* Time: 5:40 PM
|
24
30
|
*/
|
25
31
|
public class RackApplication {
|
26
|
-
|
27
|
-
|
32
|
+
private IRubyObject app;
|
33
|
+
private boolean ssl;
|
34
|
+
private Ruby runtime;
|
35
|
+
private DefaultVertx vertx;
|
36
|
+
private RubyClass rackIOInputClass;
|
37
|
+
private RubyClass httpServerResponseClass;
|
38
|
+
private RubyArray rackVersion;
|
39
|
+
private RubyNullIO nullio;
|
40
|
+
private RackEnvironment rackEnv;
|
28
41
|
|
29
|
-
|
42
|
+
public RackApplication(Vertx vertx, ThreadContext context, IRubyObject app, boolean ssl) throws IOException {
|
43
|
+
this.app = app;
|
44
|
+
this.ssl = ssl;
|
45
|
+
this.vertx = (DefaultVertx) vertx;
|
46
|
+
this.runtime = context.runtime;
|
47
|
+
this.rackVersion = RubyArray.newArrayLight(runtime, RubyFixnum.one(runtime), RubyFixnum.four(runtime));
|
48
|
+
// Memorize the ruby classes
|
49
|
+
this.rackIOInputClass = (RubyClass) runtime.getClassFromPath("Jubilee::IORackInput");
|
50
|
+
this.httpServerResponseClass = (RubyClass) runtime.getClassFromPath("Jubilee::HttpServerResponse");
|
51
|
+
this.nullio = new RubyNullIO(runtime, (RubyClass) runtime.getClassFromPath("Jubilee::NullIO"));
|
30
52
|
|
31
|
-
|
32
|
-
|
33
|
-
this.ssl = ssl;
|
34
|
-
exec = Executors.newFixedThreadPool(numberOfWorkers);
|
35
|
-
}
|
53
|
+
this.rackEnv = new RackEnvironment(runtime);
|
54
|
+
}
|
36
55
|
|
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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
public void call(final HttpServerRequest request) {
|
57
|
+
// String te = request.headers().get(Const.Vertx.TRANSFER_ENCODING);
|
58
|
+
// String contentLength;
|
59
|
+
final RackInput input;
|
60
|
+
// This should be handled by Netty (expose a contentLength methods via HttpRequest,
|
61
|
+
// it set the empty content flag when passing the header
|
62
|
+
// if ((te != null && te.equals("chunked")) ||
|
63
|
+
// ((contentLength = request.headers().get(Const.Vertx.CONTENT_LENGTH)) != null && !contentLength.equals("0"))) {
|
64
|
+
final ByteBuf bodyBuf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
65
|
+
final AtomicBoolean eof = new AtomicBoolean(false);
|
66
|
+
input = new RubyIORackInput(runtime, rackIOInputClass, request, bodyBuf, eof);
|
67
|
+
|
68
|
+
request.dataHandler(new Handler<Buffer>() {
|
69
|
+
@Override
|
70
|
+
public void handle(Buffer buffer) {
|
71
|
+
bodyBuf.writeBytes(buffer.getByteBuf());
|
72
|
+
}
|
73
|
+
});
|
74
|
+
|
75
|
+
request.endHandler(new VoidHandler() {
|
76
|
+
@Override
|
77
|
+
protected void handle() {
|
78
|
+
eof.set(true);
|
79
|
+
}
|
80
|
+
});
|
81
|
+
// } else {
|
82
|
+
// input = nullio;
|
83
|
+
// }
|
84
|
+
Runnable task = new Runnable() {
|
85
|
+
@Override
|
86
|
+
public void run() {
|
87
|
+
// This is a different context, do NOT replace runtime.getCurrentContext()
|
88
|
+
// IRubyObject result = app.callMethod(runtime.getCurrentContext(), "call", env.getEnv());
|
89
|
+
try {
|
90
|
+
IRubyObject result = app.callMethod(runtime.getCurrentContext(), "call", rackEnv.getEnv(request, input, ssl));
|
91
|
+
RackResponse response = (RackResponse) JavaEmbedUtils.rubyToJava(runtime, result, RackResponse.class);
|
92
|
+
RubyHttpServerResponse resp = new RubyHttpServerResponse(runtime,
|
93
|
+
httpServerResponseClass,
|
94
|
+
request.response());
|
95
|
+
response.respond(resp);
|
96
|
+
} catch (IOException e) {
|
97
|
+
// noop
|
98
|
+
}
|
99
|
+
}
|
100
|
+
};
|
101
|
+
vertx.startInBackground(task, false);
|
102
|
+
}
|
66
103
|
|
67
|
-
public void shutdown(boolean force) {
|
68
|
-
if (force)
|
69
|
-
exec.shutdownNow();
|
70
|
-
else
|
71
|
-
exec.shutdown();
|
72
|
-
}
|
73
104
|
}
|