jubilee 1.1.0-java
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.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG +32 -0
- data/Gemfile +35 -0
- data/Gemfile.lock +244 -0
- data/Guardfile +24 -0
- data/KNOWN_ISSUES +6 -0
- data/LICENSE.txt +20 -0
- data/README.md +147 -0
- data/ROADMAP +5 -0
- data/Rakefile +98 -0
- data/bin/jubilee +6 -0
- data/bin/jubilee_d +13 -0
- data/examples/chatapp/Gemfile +5 -0
- data/examples/chatapp/Gemfile.lock +27 -0
- data/examples/chatapp/README.md +17 -0
- data/examples/chatapp/app.rb +57 -0
- data/examples/chatapp/config.ru +3 -0
- data/examples/chatapp/public/assets/javascripts/application.js +67 -0
- data/examples/chatapp/public/assets/javascripts/jquery.js +5 -0
- data/examples/chatapp/public/assets/javascripts/sockjs-0.3.4.min.js +27 -0
- data/examples/chatapp/public/assets/javascripts/vertxbus.js +216 -0
- data/examples/chatapp/public/assets/stylesheets/application.css +29 -0
- data/examples/client/sockjs-0.3.4.min.js +27 -0
- data/examples/client/vertxbus.js +216 -0
- data/examples/jubilee.conf.rb +12 -0
- data/examples/jubilee/keystore.jks +0 -0
- data/examples/jubilee/server-keystore.jks +0 -0
- data/jars/hazelcast-2.6.3.jar +0 -0
- data/jars/jackson-annotations-2.2.2.jar +0 -0
- data/jars/jackson-core-2.2.2.jar +0 -0
- data/jars/jackson-databind-2.2.2.jar +0 -0
- data/jars/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 +20 -0
- data/java/src/org/jruby/jubilee/Const.java +32 -0
- data/java/src/org/jruby/jubilee/RackApplication.java +103 -0
- data/java/src/org/jruby/jubilee/RackEnvironment.java +150 -0
- data/java/src/org/jruby/jubilee/RackEnvironmentHash.java +449 -0
- data/java/src/org/jruby/jubilee/RackInput.java +62 -0
- data/java/src/org/jruby/jubilee/RackResponse.java +11 -0
- data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +88 -0
- data/java/src/org/jruby/jubilee/RubyServer.java +171 -0
- data/java/src/org/jruby/jubilee/deploy/Starter.java +26 -0
- data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +201 -0
- data/java/src/org/jruby/jubilee/impl/RubyNullIO.java +107 -0
- data/java/src/org/jruby/jubilee/utils/RubyHelper.java +37 -0
- data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +38 -0
- data/jubilee.gemspec +201 -0
- data/lib/jubilee.rb +17 -0
- data/lib/jubilee/application.rb +13 -0
- data/lib/jubilee/cli.rb +127 -0
- data/lib/jubilee/configuration.rb +177 -0
- data/lib/jubilee/const.rb +40 -0
- data/lib/jubilee/jubilee.jar +0 -0
- data/lib/jubilee/response.rb +69 -0
- data/lib/jubilee/server.rb +12 -0
- data/lib/jubilee/version.rb +10 -0
- data/lib/rack/chunked.rb +38 -0
- data/lib/rack/handler/jubilee.rb +44 -0
- data/lib/vertx.rb +26 -0
- data/lib/vertx/README.md +7 -0
- data/lib/vertx/buffer.rb +251 -0
- data/lib/vertx/event_bus.rb +206 -0
- data/lib/vertx/shared_data.rb +214 -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 +12 -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/.ruby-version +1 -0
- data/test/config/app.rb +5 -0
- data/test/jubilee/test_cli.rb +11 -0
- data/test/jubilee/test_configuration.rb +31 -0
- data/test/jubilee/test_rack_server.rb +137 -0
- data/test/jubilee/test_response.rb +272 -0
- data/test/jubilee/test_server.rb +72 -0
- data/test/jubilee/test_upload.rb +301 -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 +93 -0
- metadata +242 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# -*- encoding: binary -*-
|
|
2
|
+
|
|
3
|
+
module Jubilee
|
|
4
|
+
# Implements a simple DSL for configuring a Jubilee server
|
|
5
|
+
#
|
|
6
|
+
# See https://github.com/isaiah/jubilee/examples/jubilee.conf.rb
|
|
7
|
+
# for example configuration files.
|
|
8
|
+
class Configuration
|
|
9
|
+
|
|
10
|
+
attr_accessor :config_file
|
|
11
|
+
attr_reader :options
|
|
12
|
+
|
|
13
|
+
def initialize(options, &block)
|
|
14
|
+
@config_file = options.delete(:config_file)
|
|
15
|
+
@options = options.dup
|
|
16
|
+
@block = block
|
|
17
|
+
|
|
18
|
+
reload
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reload
|
|
22
|
+
instance_eval(File.read(config_file), config_file) if config_file
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def app
|
|
26
|
+
@app ||= load_rack_adapter(@options, &@block)
|
|
27
|
+
if !@options[:quiet] and @options[:environment] == "development"
|
|
28
|
+
logger = @options[:logger] || STDOUT
|
|
29
|
+
Rack::CommonLogger.new(@app, logger)
|
|
30
|
+
else
|
|
31
|
+
@app
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# sets the host and port jubilee listens to +address+ may be an Integer port
|
|
36
|
+
# number for a TCP port or an "IP_ADDRESS:PORT" for TCP listeners
|
|
37
|
+
#
|
|
38
|
+
# listen 3000 # listen to port 3000 on all TCP interfaces
|
|
39
|
+
# listen "127.0.0.1:3000" # listen to port 3000 on the loopback interface
|
|
40
|
+
# listen "[::1]:3000" # listen to port 3000 on the IPv6 loopback interface
|
|
41
|
+
def listen(address)
|
|
42
|
+
@options[:host], @options[:port] = expand_addr(address)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# sets the working directory for jubilee
|
|
46
|
+
def working_directory(path)
|
|
47
|
+
path = File.expand_path(path)
|
|
48
|
+
if config_file && config_file[0] != ?/ && ! File.readable?("#{path}/#{config_file}")
|
|
49
|
+
raise ArgumentError,
|
|
50
|
+
"config_file=#{config_file} would not be accessible in" \
|
|
51
|
+
" working_directory=#{path}"
|
|
52
|
+
end
|
|
53
|
+
@options[:chdir] = path
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# set the event bus bridge prefix, prefix, options
|
|
57
|
+
# eventbus /eventbus, inbound: {foo:bar}, outbound: {foo: bar}
|
|
58
|
+
# will set the event bus prefix as eventbus "/eventbus", it can be
|
|
59
|
+
# connected via new EventBus("http://localhost:8080/eventbus"), inbound and
|
|
60
|
+
# outbound options are security measures that will filter the messages
|
|
61
|
+
def eventbus(prefix, options = {})
|
|
62
|
+
@options[:event_bus][:prefix] = prefix
|
|
63
|
+
@options[:event_bus][:inbound] = options[:inbound]
|
|
64
|
+
@options[:event_bus][:outbound] = options[:outbound]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Set the host and port to be discovered by other jubilee instances in the network
|
|
68
|
+
# +address+ may be an Integer port number for a TCP port or an
|
|
69
|
+
# "IP_ADDRESS:PORT" for TCP listeners, or "IP_ADDRESS" and let the system
|
|
70
|
+
# to assign a port
|
|
71
|
+
#
|
|
72
|
+
# clustering true # enable cluster mode, default to "0.0.0.0:5701"
|
|
73
|
+
# clustering "0.0.0.0"
|
|
74
|
+
# clustering "0.0.0.0:5701"
|
|
75
|
+
# clustering 5701
|
|
76
|
+
def clustering(address)
|
|
77
|
+
if addr == true
|
|
78
|
+
@options[:cluster_host] = "0.0.0.0"
|
|
79
|
+
else
|
|
80
|
+
@options[:cluster_host], @options[:cluster_port] = expand_addr(address)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# enable debug messages
|
|
85
|
+
def debug(bool)
|
|
86
|
+
set_bool(:debug, bool)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# enable daemon mode
|
|
90
|
+
def daemonize(bool)
|
|
91
|
+
set_bool(:debug, bool)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# enable https mode, provide the :keystore path and password
|
|
95
|
+
def ssl(options = {})
|
|
96
|
+
set_path(:ssl_keystore, options[:keystore])
|
|
97
|
+
@options[:ssl_password] = options[:password]
|
|
98
|
+
@options[:ssl] = true
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# sets the path for the PID file of the jubilee event loop
|
|
102
|
+
def pid(path)
|
|
103
|
+
set_path(:pid, path)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Allows redirecting $stderr to a given path, if you are daemonizing and
|
|
107
|
+
# useing the default +logger+, this defautls to log/jubilee.stderr.log
|
|
108
|
+
def stderr_path(path)
|
|
109
|
+
set_path(:stderr_path, path)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# live stderr_path, this defaults to log/jubilee.stdout.log when daemonized
|
|
113
|
+
def stdout_path(path)
|
|
114
|
+
set_path(:stdout_path, path)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
def load_rack_adapter(options, &block)
|
|
119
|
+
if block
|
|
120
|
+
inner_app = Rack::Builder.new(&block).to_app
|
|
121
|
+
else
|
|
122
|
+
if options[:rackup]
|
|
123
|
+
Kernel.load(options[:rackup])
|
|
124
|
+
inner_app = Object.const_get(File.basename(options[:rackup], '.rb').capitalize.to_sym).new
|
|
125
|
+
else
|
|
126
|
+
Dir.chdir options[:chdir] if options[:chdir]
|
|
127
|
+
inner_app, _ = Rack::Builder.parse_file "config.ru"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
inner_app
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def expand_addr(addr)
|
|
134
|
+
return ["0.0.0.0", addr] if addr === Integer
|
|
135
|
+
case addr
|
|
136
|
+
when %r{\A(?:\*:)?(\d+)\z}
|
|
137
|
+
["0.0.0.0", $1]
|
|
138
|
+
when %r{\A\[([a-fA-F0-9:]+)\]:(\d+)\z}, %r{\A(.*):(\d+)\z}
|
|
139
|
+
canonicalize_tcp($1, $2.to_i)
|
|
140
|
+
when %r{\A?:\*\z}
|
|
141
|
+
[addr, nil]
|
|
142
|
+
else
|
|
143
|
+
raise ArgumentError, "unrecognizable address #{var}=#{addr.inspect}"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def set_int(var, n, min)
|
|
148
|
+
Integer === n or raise ArgumentError, "not an integer: #{var}=#{n.inspect}"
|
|
149
|
+
n >= min or raise ArgumentError, "too low (< #{min}): #{var}=#{n.inspect}"
|
|
150
|
+
@options[var] = n
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def set_path(var, path)
|
|
154
|
+
case path
|
|
155
|
+
when NilClass, String
|
|
156
|
+
@options[var] = path
|
|
157
|
+
else
|
|
158
|
+
raise ArgumentError
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def set_bool(var, bool)
|
|
163
|
+
case bool
|
|
164
|
+
when true, false
|
|
165
|
+
@options[var] = bool
|
|
166
|
+
else
|
|
167
|
+
raise ArgumentError, "#{var}=#{bool.inspect} not a boolean"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def canonicalize_tcp(addr, port)
|
|
172
|
+
packed = Socket.pack_sockaddr_in(port, addr)
|
|
173
|
+
port, addr = Socket.unpack_sockaddr_in(packed)
|
|
174
|
+
/:/ =~ addr ? ["[#{addr}]",port] : [addr, port]
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Jubilee
|
|
2
|
+
module Const
|
|
3
|
+
JUBILEE_VERSION = Version::STRING
|
|
4
|
+
HTTP_11 = "HTTP/1.1".freeze
|
|
5
|
+
HTTP_10 = "HTTP/1.0".freeze
|
|
6
|
+
|
|
7
|
+
SERVER_SOFTWARE = "SERVER_SOFTWARE".freeze
|
|
8
|
+
SERVER_PROTOCOL = "SERVER_PROTOCOL".freeze
|
|
9
|
+
GATEWAY_INTERFACE = "GATEWAY_INTERFACE".freeze
|
|
10
|
+
SERVER_NAME = "SERVER_NAME".freeze
|
|
11
|
+
SERVER_PORT = "SERVER_PORT".freeze
|
|
12
|
+
|
|
13
|
+
CGI_VER = "CGI/1.2".freeze
|
|
14
|
+
|
|
15
|
+
RACK_INPUT = "rack.input".freeze
|
|
16
|
+
|
|
17
|
+
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
|
18
|
+
GET = 'GET'.freeze
|
|
19
|
+
POST = "POST".freeze
|
|
20
|
+
REQUEST_PATH = "REQUEST_PATH".freeze
|
|
21
|
+
REQUEST_URI = "REQUEST_URI".freeze
|
|
22
|
+
PATH_INFO = "PATH_INFO".freeze
|
|
23
|
+
QUERY_STRING = "QUERY_STRING".freeze
|
|
24
|
+
|
|
25
|
+
CONTENT_LENGTH = "Content-Length".freeze
|
|
26
|
+
TRANSFER_ENCODING = "Transfer-Encoding".freeze
|
|
27
|
+
|
|
28
|
+
HTTP_VERSION = "HTTP_VERSION".freeze
|
|
29
|
+
HTTP_HOST = "HTTP_HOST".freeze
|
|
30
|
+
HTTP_USER_AGENT = "HTTP_USER_AGENT".freeze
|
|
31
|
+
HTTP_ACCEPT = "HTTP_ACCEPT".freeze
|
|
32
|
+
HTTP_COOKIE = "HTTP_COOKIE".freeze
|
|
33
|
+
HTTP_ACCEPT_LANGUAGE = "HTTP_ACCEPT_LANGUAGE".freeze
|
|
34
|
+
HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING".freeze
|
|
35
|
+
HTTP_CONNECTION = "HTTP_CONNECTION".freeze
|
|
36
|
+
NEWLINE = "\n".freeze
|
|
37
|
+
|
|
38
|
+
STATUS_WITH_NO_ENTITY_BODY = Hash[[204,205,304].map{|s| [s, true]}]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'java'
|
|
2
|
+
module Jubilee
|
|
3
|
+
class Response
|
|
4
|
+
include Const
|
|
5
|
+
include org.jruby.jubilee.RackResponse
|
|
6
|
+
|
|
7
|
+
def initialize(array)
|
|
8
|
+
@status, @headers, @body = *array
|
|
9
|
+
@status = @status.to_i
|
|
10
|
+
@content_length = nil
|
|
11
|
+
if @body.kind_of? Array and @body.size == 1
|
|
12
|
+
@content_length = @body[0].bytesize
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# See Rack::Utils::
|
|
17
|
+
def respond(response)
|
|
18
|
+
no_body = @status < 200 || STATUS_WITH_NO_ENTITY_BODY[@status]
|
|
19
|
+
write_status(response)
|
|
20
|
+
write_headers(response)
|
|
21
|
+
if no_body
|
|
22
|
+
response.end
|
|
23
|
+
else
|
|
24
|
+
if @body.respond_to?(:to_path)
|
|
25
|
+
response.send_file(@body.to_path)
|
|
26
|
+
else
|
|
27
|
+
write_body(response)
|
|
28
|
+
response.end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
rescue NativeException => e
|
|
32
|
+
puts e
|
|
33
|
+
ensure
|
|
34
|
+
@body.close if @body.respond_to?(:close)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
def write_status(response)
|
|
39
|
+
response.status_code = @status
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def write_headers(response)
|
|
43
|
+
@headers.each do |key, values|
|
|
44
|
+
case key
|
|
45
|
+
when CONTENT_LENGTH
|
|
46
|
+
@content_length = values
|
|
47
|
+
next
|
|
48
|
+
when TRANSFER_ENCODING
|
|
49
|
+
@content_length = nil
|
|
50
|
+
end
|
|
51
|
+
# Multiple values are joined by \n
|
|
52
|
+
response.put_header(key, values)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def write_body(response)
|
|
57
|
+
response.put_default_headers
|
|
58
|
+
if @content_length
|
|
59
|
+
response.put_header(CONTENT_LENGTH, @content_length.to_s)
|
|
60
|
+
else
|
|
61
|
+
response.chunked = true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
@body.each do |part|
|
|
65
|
+
response.write(part)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'rack/methodoverride'
|
|
2
|
+
module Jubilee
|
|
3
|
+
class Server < VertxServer
|
|
4
|
+
def initialize(app, opts = {})
|
|
5
|
+
options = {Port: 8080, ssl: false}.merge(opts)
|
|
6
|
+
if (options[:ssl]) && options[:keystore_path].nil?
|
|
7
|
+
raise ArgumentError, "Please provide a keystore for ssl"
|
|
8
|
+
end
|
|
9
|
+
super(Application.new(app), options)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/rack/chunked.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Rails use this to chunk it's streaming response body, which we don't need
|
|
2
|
+
module Rack
|
|
3
|
+
class Chunked
|
|
4
|
+
class Body
|
|
5
|
+
def initialize(body)
|
|
6
|
+
@body = body
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def each
|
|
10
|
+
@body.each {|chunk| yield chunk}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def close
|
|
14
|
+
@body.close if @body.respond_to?(:close)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
include Rack::Utils
|
|
19
|
+
|
|
20
|
+
def initialize(app)
|
|
21
|
+
@app = app
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(env)
|
|
25
|
+
status, headers, body = @app.call(env)
|
|
26
|
+
headers = HeaderHash.new(headers)
|
|
27
|
+
|
|
28
|
+
unless env['HTTP_VERSION'] == 'HTTP/1.0' ||
|
|
29
|
+
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
|
30
|
+
headers['Content-Length'] ||
|
|
31
|
+
headers['Transfer-Encoding']
|
|
32
|
+
headers.delete('Content-Length')
|
|
33
|
+
headers.delete('Transfer-Encoding')
|
|
34
|
+
end
|
|
35
|
+
[status, headers, body]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'rack/handler'
|
|
2
|
+
require 'jubilee'
|
|
3
|
+
require 'java'
|
|
4
|
+
|
|
5
|
+
module Rack
|
|
6
|
+
module Handler
|
|
7
|
+
module Jubilee
|
|
8
|
+
DEFAULT_OPTIONS = {
|
|
9
|
+
:Host => '0.0.0.0',
|
|
10
|
+
:Port => 3000,
|
|
11
|
+
:Verbose => false
|
|
12
|
+
}
|
|
13
|
+
def self.run(app, options = {})
|
|
14
|
+
options = DEFAULT_OPTIONS.merge(options)
|
|
15
|
+
|
|
16
|
+
if options[:Verbose]
|
|
17
|
+
app = Rack::CommonLogger.new(app, STDOUT)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if options[:environment]
|
|
21
|
+
ENV["RACK_ENV"] = options[:environment].to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@server = ::Jubilee::Server.new(app, options)
|
|
25
|
+
|
|
26
|
+
puts "Jubilee #{::Jubilee::Const::JUBILEE_VERSION} starting..."
|
|
27
|
+
puts "* Environment: #{ENV['RACK_ENV']}"
|
|
28
|
+
puts "* Listening on http://#{options[:Host]}:#{options[:Port]}"
|
|
29
|
+
|
|
30
|
+
yield @server if block_given?
|
|
31
|
+
|
|
32
|
+
@server.start
|
|
33
|
+
@starter = org.jruby.jubilee.deploy.Starter.new
|
|
34
|
+
@starter.block
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.shutdown
|
|
38
|
+
@server.stop{ @starter.unblock }
|
|
39
|
+
exit
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
register :jubilee, Jubilee
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/vertx.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright 2011 the original author or authors.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
include Java
|
|
16
|
+
|
|
17
|
+
require 'vertx/buffer'
|
|
18
|
+
require 'vertx/event_bus'
|
|
19
|
+
|
|
20
|
+
# This is the module for vertx related feature like EventBus and SharedData,
|
|
21
|
+
# these features are built into jubilee server, by requiring 'vertx' in your
|
|
22
|
+
# rack application, you get access to the functionalities offered by vertx
|
|
23
|
+
# platform.
|
|
24
|
+
|
|
25
|
+
module Vertx
|
|
26
|
+
end
|
data/lib/vertx/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Because embeded Vertx doesn't support modules, I have to copy the ruby api
|
|
2
|
+
from the [mod-lang-jruby](https://github.com/vert-x/mod-lang-jruby) project.
|
|
3
|
+
|
|
4
|
+
Some of the files that are not required for the jubilee api are removed.
|
|
5
|
+
|
|
6
|
+
These files are exactly the same as the original project, except the directory
|
|
7
|
+
name changed to follow the ruby conversion of namespaces.
|
data/lib/vertx/buffer.rb
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Copyright 2011-2012 the original author or authors.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require 'vertx/shared_data'
|
|
16
|
+
|
|
17
|
+
module Vertx
|
|
18
|
+
|
|
19
|
+
# A Buffer represents a sequence of zero or more bytes that can be written to or read from, and which expands
|
|
20
|
+
# as necessary to accomodate any bytes written to it.
|
|
21
|
+
#
|
|
22
|
+
# Buffers are used in many places in vert.x, for example to read/write data to/from {NetSocket}, {AsyncFile},
|
|
23
|
+
# {WebSocket}, {HttpClientRequest}, {HttpClientResponse}, {HttpServerRequest}, {HttpServerResponse} etc.
|
|
24
|
+
#
|
|
25
|
+
# There are two ways to write data to a Buffer: The first method involves methods that take the form set_XXX.
|
|
26
|
+
# These methods write data into the buffer starting at the specified position. The position does not have to be inside data that
|
|
27
|
+
# has already been written to the buffer; the buffer will automatically expand to encompass the position plus any data that needs
|
|
28
|
+
# to be written. All positions are measured in bytes and start with zero.
|
|
29
|
+
#
|
|
30
|
+
# The second method involves methods that take the form append-XXX; these methods append data at the end of the buffer.
|
|
31
|
+
# Methods exist to both set and append all primitive types, String and other instances of Buffer.
|
|
32
|
+
#
|
|
33
|
+
# Data can be read from a buffer by invoking methods which take the form get_XXX. These methods take a parameter
|
|
34
|
+
# representing the position in the Buffer from where to read data.
|
|
35
|
+
#
|
|
36
|
+
# @author {http://tfox.org Tim Fox}
|
|
37
|
+
class Buffer
|
|
38
|
+
|
|
39
|
+
# @private
|
|
40
|
+
def initialize(j_buffer)
|
|
41
|
+
@buffer = j_buffer
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Creates a new empty buffer. The {#length} of the buffer immediately after creation will be zero.
|
|
45
|
+
# @param initial_size_hint [FixNum] is a hint to the system for how much memory
|
|
46
|
+
# to initially allocate to the buffer to prevent excessive automatic re-allocations as data is written to it.
|
|
47
|
+
def Buffer.create(initial_size_hint = 0)
|
|
48
|
+
Buffer.new(org.vertx.java.core.buffer.Buffer.new(initial_size_hint))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Create a new Buffer from a String
|
|
52
|
+
# @param str [String] The String to encode into the Buffer
|
|
53
|
+
# @param enc [String] Encoding to use. Defaults to "UTF-8"
|
|
54
|
+
def Buffer.create_from_str(str, enc = "UTF-8")
|
|
55
|
+
Buffer.new(org.vertx.java.core.buffer.Buffer.new(str, enc))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Return a String representation of the buffer.
|
|
59
|
+
# @param enc [String] The encoding to use. Defaults to "UTF-8"
|
|
60
|
+
# @return [String] a String representation of the buffer.
|
|
61
|
+
def to_s(enc = "UTF-8")
|
|
62
|
+
@buffer.toString(enc)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Get the byte at position pos in the buffer.
|
|
66
|
+
# @param pos [FixNum] the position in the buffer from where to retrieve the byte
|
|
67
|
+
# @return [FixNum] the byte
|
|
68
|
+
def get_byte(pos)
|
|
69
|
+
@buffer.getByte(pos)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Get the FixNum represented by a sequence of bytes starting at position pos in the buffer.
|
|
73
|
+
# @param pos [FixNum] the position in the buffer from where to retrieve the FixNum.
|
|
74
|
+
# @param bytes [FixNum] the number of bytes to retrieve from position pos to create the FixNum. Valid values are 1, 2, 4 and 8.
|
|
75
|
+
# @return [FixNum] the FixNum
|
|
76
|
+
def get_fixnum(pos, bytes)
|
|
77
|
+
case bytes
|
|
78
|
+
when 1
|
|
79
|
+
@buffer.getByte(pos)
|
|
80
|
+
when 2
|
|
81
|
+
@buffer.getShort(pos)
|
|
82
|
+
when 4
|
|
83
|
+
@buffer.getInt(pos)
|
|
84
|
+
when 8
|
|
85
|
+
@buffer.getLong(pos)
|
|
86
|
+
else
|
|
87
|
+
raise "bytes must be 1, 2, 4, or 8"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Get the Float represented by a sequence of bytes starting at position pos in the buffer.
|
|
92
|
+
# @param pos [Float] the position in the buffer from where to retrieve the Float.
|
|
93
|
+
# @param bytes [Float] the number of bytes to retrieve from position pos to create the Float. Valid values are 4 and 8.
|
|
94
|
+
# @return [Float] the Float
|
|
95
|
+
def get_float(pos, bytes)
|
|
96
|
+
case bytes
|
|
97
|
+
when 4
|
|
98
|
+
@buffer.getFloat(pos)
|
|
99
|
+
when 8
|
|
100
|
+
@buffer.getDouble(pos)
|
|
101
|
+
else
|
|
102
|
+
raise "bytes must be 4 or 8"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Return bytes from the buffer interpreted as a String
|
|
107
|
+
# @param pos [FixNum] the position in the buffer from where to start reading
|
|
108
|
+
# @param end_pos [FixNum] the position in the buffer to end reading
|
|
109
|
+
# @param enc [String] The encoding to use
|
|
110
|
+
# @return [String] the String
|
|
111
|
+
def get_string(pos, end_pos, enc = 'UTF-8')
|
|
112
|
+
@buffer.getString(pos, end_pos, enc)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Return bytes in the buffer as a Buffer
|
|
116
|
+
# @param start_pos [FixNum] - the position in this buffer from where to start the copy.
|
|
117
|
+
# @param end_pos [FixNum] - the copy will be made up to index end_pos - 1
|
|
118
|
+
# @return [Buffer] the copy
|
|
119
|
+
def get_buffer(pos, end_pos)
|
|
120
|
+
j_buff = @buffer.getBuffer(pos, end_pos)
|
|
121
|
+
Buffer.new(j_buff)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Appends another buffer to the end of this buffer. The buffer will expand as necessary to accomodate any bytes
|
|
125
|
+
# written.
|
|
126
|
+
# @param buff [Buffer] the buffer to append.
|
|
127
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
128
|
+
def append_buffer(buff)
|
|
129
|
+
@buffer.appendBuffer(buff._to_java_buffer)
|
|
130
|
+
self
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Appends a FixNum to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
|
134
|
+
# @param num [FixNum] the fixnum to append.
|
|
135
|
+
# @param bytes [FixNum] the number of bytes to write in the buffer to represent the fixnum. Valid values are 1, 2, 4 and 8.
|
|
136
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
137
|
+
def append_fixnum(num, bytes)
|
|
138
|
+
case bytes
|
|
139
|
+
when 1
|
|
140
|
+
@buffer.appendByte(num)
|
|
141
|
+
when 2
|
|
142
|
+
@buffer.appendShort(num)
|
|
143
|
+
when 4
|
|
144
|
+
@buffer.appendInt(num)
|
|
145
|
+
when 8
|
|
146
|
+
@buffer.appendLong(num)
|
|
147
|
+
else
|
|
148
|
+
raise "bytes must be 1, 2, 4, or 8"
|
|
149
|
+
end
|
|
150
|
+
self
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Appends a Float to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
|
154
|
+
# @param num [Float] the float to append.
|
|
155
|
+
# @param bytes [FixNum] the number of bytes to write in the buffer to represent the float. Valid values are 4 and 8.
|
|
156
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
157
|
+
def append_float(num, bytes)
|
|
158
|
+
case bytes
|
|
159
|
+
when 4
|
|
160
|
+
@buffer.appendFloat(num)
|
|
161
|
+
when 8
|
|
162
|
+
@buffer.appendDouble(num)
|
|
163
|
+
else
|
|
164
|
+
raise "bytes must be 4 or 8"
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Appends a string to the end of this buffer. The buffer will expand as necessary to accomodate any bytes written.
|
|
169
|
+
# @param str [String] the string to append.
|
|
170
|
+
# @param enc [String] the encoding to use. Defaults to "UTF-8"
|
|
171
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
172
|
+
def append_str(str, enc = "UTF-8")
|
|
173
|
+
@buffer.appendString(str, enc)
|
|
174
|
+
self
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Sets bytes in the buffer to a representation of a FixNum. The buffer will expand as necessary to accomodate any bytes written.
|
|
178
|
+
# @param pos [FixNum] - the position in the buffer from where to start writing the FixNum
|
|
179
|
+
# @param num [FixNum] - the FixNum to write
|
|
180
|
+
# @param bytes [FixNum] - the number of bytes to write to represent the FixNum. Valid values are 1, 2, 4, and 8
|
|
181
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
182
|
+
def set_fixnum(pos, num, bytes)
|
|
183
|
+
case bytes
|
|
184
|
+
when 1
|
|
185
|
+
@buffer.setByte(pos, num)
|
|
186
|
+
when 2
|
|
187
|
+
@buffer.setShort(pos, num)
|
|
188
|
+
when 4
|
|
189
|
+
@buffer.setInt(pos, num)
|
|
190
|
+
when 8
|
|
191
|
+
@buffer.setLong(pos, num)
|
|
192
|
+
else
|
|
193
|
+
raise "bytes must be 1, 2, 4, or 8"
|
|
194
|
+
end
|
|
195
|
+
self
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Sets bytes in the buffer to a representation of a Float. The buffer will expand as necessary to accomodate any bytes written.
|
|
199
|
+
# @param pos [FixNum] - the position in the buffer from where to start writing the Float
|
|
200
|
+
# @param num [Float] - the Float to write
|
|
201
|
+
# @param bytes [FixNum] - the number of bytes to write to represent the Float. Valid values are 4 and 8
|
|
202
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
203
|
+
def set_float(pos, num, bytes)
|
|
204
|
+
case bytes
|
|
205
|
+
when 4
|
|
206
|
+
@buffer.setFloat(pos, num)
|
|
207
|
+
when 8
|
|
208
|
+
@buffer.setDouble(pos, num)
|
|
209
|
+
else
|
|
210
|
+
raise "bytes must be 4 or 8"
|
|
211
|
+
end
|
|
212
|
+
self
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Sets bytes in this buffer to the bytes of the specified buffer. The buffer will expand as necessary to accomodate any bytes written.
|
|
216
|
+
# @param pos [FixNum] - the position in this buffer from where to start writing the buffer
|
|
217
|
+
# @param buff [Buffer] - the buffer to write into this buffer
|
|
218
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
219
|
+
def set_buffer(pos, buff)
|
|
220
|
+
@buffer.setBytes(pos, buff._to_java_buffer)
|
|
221
|
+
self
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Set bytes in the buffer to the string encoding in the specified encoding
|
|
225
|
+
# @param pos [FixNum] - the position in this buffer from where to start writing the string
|
|
226
|
+
# @param str [String] the string
|
|
227
|
+
# @param enc [String] the encoding
|
|
228
|
+
# @return [Buffer] a reference to self so multiple operations can be appended together.
|
|
229
|
+
def set_string(pos, str, enc = 'UTF-8')
|
|
230
|
+
@buffer.setString(pos, str, enc)
|
|
231
|
+
self
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# @return [FixNum] the length of this buffer, in bytes.
|
|
235
|
+
def length
|
|
236
|
+
@buffer.length
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Get a copy of the entire buffer.
|
|
240
|
+
# @return [Buffer] the copy
|
|
241
|
+
def copy
|
|
242
|
+
Buffer.new(@buffer.copy())
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# @private
|
|
246
|
+
def _to_java_buffer
|
|
247
|
+
@buffer
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
end
|
|
251
|
+
end
|