jrack_handlers 1.0.1-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.
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/README.textile +3 -0
- data/Rakefile +1 -0
- data/jrack_handlers.gemspec +24 -0
- data/lib/rack/handler/webbit.rb +153 -0
- metadata +70 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.textile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$: << File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'jrack_handlers'
|
8
|
+
s.version = '1.0.1'
|
9
|
+
s.platform = 'java'
|
10
|
+
s.authors = ['Theo Hultberg']
|
11
|
+
s.email = ['theo@burtcorp.com']
|
12
|
+
s.homepage = 'http://github.com/burtcorp/jrack_handlers'
|
13
|
+
s.summary = %q{Rack handlers for Java webservers}
|
14
|
+
s.description = %q{Rack handler implementations for Java webservers, such as Webbit}
|
15
|
+
|
16
|
+
s.rubyforge_project = 'jrack_handlers'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
# s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
# s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = %w(lib)
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'webbit-jars', '>= 0.2.17'
|
24
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'webbit-jars'
|
4
|
+
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module Handler
|
8
|
+
import org.webbitserver.WebServers
|
9
|
+
import org.webbitserver.HttpHandler
|
10
|
+
import java.util.concurrent.Executors
|
11
|
+
|
12
|
+
class Webbit
|
13
|
+
include HttpHandler
|
14
|
+
|
15
|
+
def self.run(app, options={})
|
16
|
+
port = (options[:port] || options[:Port]).to_i
|
17
|
+
worker_threads = options.fetch(:worker_threads, 1).to_i
|
18
|
+
@executor = Executors.new_fixed_thread_pool(worker_threads)
|
19
|
+
@handler = Webbit.new(app)
|
20
|
+
@server = WebServers.create_web_server(@executor, port)
|
21
|
+
@server.add(@handler)
|
22
|
+
@server.start
|
23
|
+
$stderr.puts("Webbit server started on port #{port}, #{worker_threads} worker threads")
|
24
|
+
install_shutdown_hook!
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.shutdown
|
28
|
+
@server.stop
|
29
|
+
$stderr.puts('Webbit server shutting down')
|
30
|
+
@server.join
|
31
|
+
@executor.shutdown
|
32
|
+
@executor, @server, @handler = nil, nil, nil
|
33
|
+
$stderr.puts('Webbit server stopped')
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(app)
|
37
|
+
@app = app
|
38
|
+
end
|
39
|
+
|
40
|
+
def handleHttpRequest(request, response, control)
|
41
|
+
# TODO: there is something not working with chunked responses
|
42
|
+
status, headers, body = @app.call(create_env(request))
|
43
|
+
headers.each do |key, value|
|
44
|
+
response.header(key, value)
|
45
|
+
end
|
46
|
+
body.each do |chunk|
|
47
|
+
response.content(chunk.to_java_bytes)
|
48
|
+
end
|
49
|
+
response.status(status)
|
50
|
+
body.close if body.respond_to?(:close)
|
51
|
+
rescue => e
|
52
|
+
response.content(e.message + "\n\n")
|
53
|
+
response.content(e.backtrace.join("\n"))
|
54
|
+
response.status(500)
|
55
|
+
ensure
|
56
|
+
response.end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
EMPTY_STRING = ''.freeze
|
62
|
+
QUESTION_MARK = '?'.freeze
|
63
|
+
COLON = ':'.freeze
|
64
|
+
SLASH = '/'.freeze
|
65
|
+
HTTP = 'http'.freeze
|
66
|
+
HOST = 'Host'.freeze
|
67
|
+
LOCALHOST = 'localhost'.freeze
|
68
|
+
CONTENT_TYPE = 'Content-Type'.freeze
|
69
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
70
|
+
|
71
|
+
REQUEST_METHOD_KEY = 'REQUEST_METHOD'.freeze
|
72
|
+
SCRIPT_NAME_KEY = 'SCRIPT_NAME'.freeze
|
73
|
+
PATH_INFO_KEY = 'PATH_INFO'.freeze
|
74
|
+
QUERY_STRING_KEY = 'QUERY_STRING'.freeze
|
75
|
+
SERVER_NAME_KEY = 'SERVER_NAME'.freeze
|
76
|
+
SERVER_PORT_KEY = 'SERVER_PORT'.freeze
|
77
|
+
CONTENT_TYPE_KEY = 'CONTENT_TYPE'.freeze
|
78
|
+
CONTENT_LENGTH_KEY = 'CONTENT_LENGTH'.freeze
|
79
|
+
REMOTE_ADDR_KEY = 'REMOTE_ADDR'.freeze
|
80
|
+
REMOTE_HOST_KEY = 'REMOTE_HOST'.freeze
|
81
|
+
REQUEST_URI_KEY = 'REQUEST_URI'.freeze
|
82
|
+
REQUEST_PATH_KEY = 'REQUEST_PATH'.freeze
|
83
|
+
RACK_VERSION_KEY = 'rack.version'.freeze
|
84
|
+
RACK_INPUT_KEY = 'rack.input'.freeze
|
85
|
+
RACK_ERRORS_KEY = 'rack.errors'.freeze
|
86
|
+
RACK_MULTITHREAD_KEY = 'rack.multithread'.freeze
|
87
|
+
RACK_MULTIPROCESS_KEY = 'rack.multiprocess'.freeze
|
88
|
+
RACK_RUN_ONCE_KEY = 'rack.run_once'.freeze
|
89
|
+
RACK_URL_SCHEME_KEY = 'rack.url_scheme'.freeze
|
90
|
+
|
91
|
+
STATIC_ENV = {
|
92
|
+
# Required HTTP environment
|
93
|
+
'SCRIPT_NAME' => EMPTY_STRING,
|
94
|
+
'SERVER_NAME' => LOCALHOST,
|
95
|
+
|
96
|
+
# Rack internal environment
|
97
|
+
'rack.version' => Rack::VERSION,
|
98
|
+
'rack.errors' => $stderr,
|
99
|
+
'rack.multithread' => true,
|
100
|
+
'rack.multiprocess' => false,
|
101
|
+
'rack.run_once' => false,
|
102
|
+
'rack.url_scheme' => HTTP
|
103
|
+
}.freeze
|
104
|
+
|
105
|
+
def self.install_shutdown_hook!
|
106
|
+
java.lang.Runtime.runtime.add_shutdown_hook(java.lang.Thread.new { shutdown })
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_env(request)
|
110
|
+
request_body = String.from_java_bytes(request.body_as_bytes)
|
111
|
+
rack_input = StringIO.new(request_body)
|
112
|
+
rack_input.set_encoding(Encoding::BINARY)
|
113
|
+
|
114
|
+
path_info, query_string = request.uri.split(QUESTION_MARK)
|
115
|
+
query_string ||= EMPTY_STRING
|
116
|
+
host, port = request.header(HOST).split(COLON)
|
117
|
+
port ||= 80
|
118
|
+
|
119
|
+
remote_addr, remote_port = request.remote_address.to_s.split(COLON)
|
120
|
+
remote_host, remote_ip = remote_addr.split(SLASH)
|
121
|
+
remote_host = nil if remote_host.empty?
|
122
|
+
|
123
|
+
env = STATIC_ENV.merge(
|
124
|
+
# Required HTTP environment
|
125
|
+
'REQUEST_METHOD' => request.method,
|
126
|
+
'PATH_INFO' => path_info,
|
127
|
+
'QUERY_STRING' => query_string,
|
128
|
+
'SERVER_PORT' => port,
|
129
|
+
|
130
|
+
# Optional HTTP environment
|
131
|
+
'CONTENT_TYPE' => request.header(CONTENT_TYPE),
|
132
|
+
'CONTENT_LENGTH' => request.header(CONTENT_LENGTH),
|
133
|
+
'REMOTE_ADDR' => remote_ip,
|
134
|
+
'REMOTE_HOST' => remote_host || remote_ip,
|
135
|
+
'REQUEST_URI' => request.uri,
|
136
|
+
'REQUEST_PATH' => path_info,
|
137
|
+
|
138
|
+
# Rack internal environment
|
139
|
+
'rack.input' => rack_input
|
140
|
+
)
|
141
|
+
|
142
|
+
request.all_headers.each do |entry|
|
143
|
+
header_key_name = entry.key.to_s.upcase.gsub('-', '_')
|
144
|
+
env["HTTP_#{header_key_name}"] = entry.value.to_s unless env[header_key_name]
|
145
|
+
end
|
146
|
+
|
147
|
+
env.delete(CONTENT_TYPE_KEY) unless env[CONTENT_TYPE_KEY]
|
148
|
+
env.delete(CONTENT_LENGTH_KEY) unless env[CONTENT_LENGTH_KEY]
|
149
|
+
env
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jrack_handlers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.1
|
6
|
+
platform: java
|
7
|
+
authors:
|
8
|
+
- Theo Hultberg
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-01-17 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: webbit-jars
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.2.17
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
description: Rack handler implementations for Java webservers, such as Webbit
|
27
|
+
email:
|
28
|
+
- theo@burtcorp.com
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- Gemfile
|
38
|
+
- README.textile
|
39
|
+
- Rakefile
|
40
|
+
- jrack_handlers.gemspec
|
41
|
+
- lib/rack/handler/webbit.rb
|
42
|
+
homepage: http://github.com/burtcorp/jrack_handlers
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project: jrack_handlers
|
65
|
+
rubygems_version: 1.8.11
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Rack handlers for Java webservers
|
69
|
+
test_files: []
|
70
|
+
|