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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,3 @@
1
+ h1. README
2
+
3
+ Rack handlers for Java web servers. Currently includes a handler for "Webbit":https://github.com/joewalnes/webbit.
@@ -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
+