jubilee 0.1.2

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.
Files changed (54) hide show
  1. data/.rbenv-version +1 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +54 -0
  4. data/Guardfile +24 -0
  5. data/README.md +61 -0
  6. data/Rakefile +94 -0
  7. data/VERSION +1 -0
  8. data/bin/jubilee +6 -0
  9. data/bin/jubilee_d +10 -0
  10. data/examples/jubilee/keystore.jks +0 -0
  11. data/examples/jubilee/server-keystore.jks +0 -0
  12. data/examples/ssl/ServerTest.java +19 -0
  13. data/examples/ssl/webroot/index.html +10 -0
  14. data/jars/netty-3.6.0.Beta1.jar +0 -0
  15. data/jars/vertx-core-1.3.0.final.jar +0 -0
  16. data/java/.idea/ant.xml +7 -0
  17. data/java/.idea/libraries/jruby.xml +9 -0
  18. data/java/.idea/libraries/netty_3_6_0_Beta1.xml +9 -0
  19. data/java/.idea/libraries/vertx_core_1_3_0_final.xml +9 -0
  20. data/java/src/jubilee/JubileeService.java +21 -0
  21. data/java/src/org/jruby/jubilee/Const.java +148 -0
  22. data/java/src/org/jruby/jubilee/RackApplication.java +78 -0
  23. data/java/src/org/jruby/jubilee/RackEnvironment.java +13 -0
  24. data/java/src/org/jruby/jubilee/RackErrors.java +44 -0
  25. data/java/src/org/jruby/jubilee/RackInput.java +62 -0
  26. data/java/src/org/jruby/jubilee/RackResponse.java +16 -0
  27. data/java/src/org/jruby/jubilee/Server.java +104 -0
  28. data/java/src/org/jruby/jubilee/deploy/Starter.java +26 -0
  29. data/java/src/org/jruby/jubilee/impl/DefaultRackEnvironment.java +98 -0
  30. data/java/src/org/jruby/jubilee/impl/NullIO.java +111 -0
  31. data/java/src/org/jruby/jubilee/impl/RubyIORackErrors.java +68 -0
  32. data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +164 -0
  33. data/lib/jubilee.rb +11 -0
  34. data/lib/jubilee/application.rb +13 -0
  35. data/lib/jubilee/cli.rb +74 -0
  36. data/lib/jubilee/configuration.rb +52 -0
  37. data/lib/jubilee/const.rb +39 -0
  38. data/lib/jubilee/jubilee.jar +0 -0
  39. data/lib/jubilee/response.rb +64 -0
  40. data/lib/jubilee/server.rb +16 -0
  41. data/lib/rack/handler/jubilee.rb +43 -0
  42. data/test/.rbenv-version +1 -0
  43. data/test/config/app.rb +5 -0
  44. data/test/jubilee/test_cli.rb +11 -0
  45. data/test/jubilee/test_config.rb +14 -0
  46. data/test/jubilee/test_persistent.rb +238 -0
  47. data/test/jubilee/test_rack_server.rb +116 -0
  48. data/test/jubilee/test_server.rb +68 -0
  49. data/test/sinatra_app/app.rb +31 -0
  50. data/test/sinatra_app/config.ru +6 -0
  51. data/test/sinatra_app/public/test.html +10 -0
  52. data/test/sinatra_app/unicorn.conf.rb +29 -0
  53. data/test/test_helper.rb +21 -0
  54. metadata +160 -0
@@ -0,0 +1 @@
1
+ jruby-1.7.0
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source :rubygems
2
+
3
+ gem 'rack'
4
+ gem 'spoon'
5
+
6
+ group :development do
7
+ gem 'jeweler'
8
+ end
9
+
10
+ group :test do
11
+ gem 'guard'
12
+ gem 'guard-minitest'
13
+ gem 'multipart-post'
14
+ gem 'pry'
15
+ gem 'rcov'
16
+ end
@@ -0,0 +1,54 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ coderay (1.0.8)
5
+ git (1.2.5)
6
+ guard (1.5.4)
7
+ listen (>= 0.4.2)
8
+ lumberjack (>= 1.0.2)
9
+ pry (>= 0.9.10)
10
+ thor (>= 0.14.6)
11
+ guard-minitest (0.5.0)
12
+ guard (>= 0.4)
13
+ jeweler (1.8.4)
14
+ bundler (~> 1.0)
15
+ git (>= 1.2.5)
16
+ rake
17
+ rdoc
18
+ json (1.7.5)
19
+ json (1.7.5-java)
20
+ listen (0.5.3)
21
+ lumberjack (1.0.2)
22
+ method_source (0.8.1)
23
+ multipart-post (1.1.5)
24
+ pry (0.9.10)
25
+ coderay (~> 1.0.5)
26
+ method_source (~> 0.8)
27
+ slop (~> 3.3.1)
28
+ pry (0.9.10-java)
29
+ coderay (~> 1.0.5)
30
+ method_source (~> 0.8)
31
+ slop (~> 3.3.1)
32
+ spoon (~> 0.0)
33
+ rack (1.4.1)
34
+ rake (10.0.2)
35
+ rcov (0.9.11)
36
+ rcov (0.9.11-java)
37
+ rdoc (3.12)
38
+ json (~> 1.4)
39
+ slop (3.3.3)
40
+ spoon (0.0.1)
41
+ thor (0.16.0)
42
+
43
+ PLATFORMS
44
+ java
45
+
46
+ DEPENDENCIES
47
+ guard
48
+ guard-minitest
49
+ jeweler
50
+ multipart-post
51
+ pry
52
+ rack
53
+ rcov
54
+ spoon
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest' do
5
+ # with Minitest::Unit
6
+ watch(%r|^test/(.*)\/?test_(.*)\.rb|)
7
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ watch(%r|^test/test_helper\.rb|) { "test" }
9
+
10
+ # with Minitest::Spec
11
+ # watch(%r|^spec/(.*)_spec\.rb|)
12
+ # watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
13
+ # watch(%r|^spec/spec_helper\.rb|) { "spec" }
14
+
15
+ # Rails 3.2
16
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
17
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
18
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
19
+
20
+ # Rails
21
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
22
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
23
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
24
+ end
@@ -0,0 +1,61 @@
1
+ Jubilee
2
+ =========
3
+
4
+ A fast rack server build upon [vertx](http://vertx.io)
5
+
6
+ Known Issues
7
+ ----------
8
+
9
+ * Direct use of HttpServerResponse object in Ruby Response class is
10
+ potentially slow. see [Improving Java Integration
11
+ Performance](https://github.com/jruby/jruby/wiki/ImprovingJavaIntegrationPerformance)
12
+
13
+ TODO
14
+ ----------
15
+
16
+ * Daemon mode
17
+ * Try non-block IO
18
+ * Site(WIP)
19
+ * benchmark: Get, static file, post
20
+
21
+ * EventBus
22
+ * WebSocket [need test]
23
+
24
+ Fixed
25
+ -----------
26
+
27
+ * Long running request get reset, as connection timed out. Fix by increase
28
+ default connection timeout from 5 seconds to 10 seconds, cannot be higher, or
29
+ it just doesn't respond. donno why.
30
+ * Failed to serve uploaded images. Fixed by use vertx sendfile
31
+ * Rack handler still need a latch. Fixed by execute a unblock hook in
32
+ server#stop
33
+ * If-Modified-Since doesn't work. All headers were added.
34
+
35
+
36
+ Installation
37
+ -----------
38
+
39
+ ```gem install jubilee```
40
+
41
+ Performance
42
+ ===========
43
+
44
+ Get request for test/sinatra_app
45
+ -----------
46
+
47
+ Got rival performance as puma.
48
+ (ab -c 20 -n 10000)
49
+
50
+ jubilee: 1750rps after warm
51
+ puma: 1327rps after warm
52
+
53
+ unicorn (worker 10): 1440rps
54
+
55
+ Serve static file
56
+ -----------
57
+
58
+ Requirement
59
+ ===========
60
+
61
+ JRuby '~> 1.7.0'
@@ -0,0 +1,94 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ include\
7
+ begin
8
+ RbConfig
9
+ rescue NameError
10
+ Config
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:default, :development)
15
+ rescue Bundler::BundlerError => e
16
+ $stderr.puts e.message
17
+ $stderr.puts "Run `bundle install` to install missing gems"
18
+ exit e.status_code
19
+ end
20
+ require 'rake'
21
+
22
+ require 'jeweler'
23
+ Jeweler::Tasks.new do |gem|
24
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
25
+ gem.name = "jubilee"
26
+ gem.homepage = "http://github.com/isaiah/jubilee"
27
+ gem.license = "MIT"
28
+ gem.summary = %Q{JRuby webserver based on Vertx}
29
+ gem.description = %Q{Web Server that rocks!}
30
+ gem.email = "issaria@gmail.com"
31
+ gem.authors = ["Isaiah Peng"]
32
+ # dependencies defined in Gemfile
33
+ end
34
+ Jeweler::RubygemsDotOrgTasks.new
35
+
36
+ require 'rake/testtask'
37
+ Rake::TestTask.new(:test) do |test|
38
+ test.libs << 'lib' << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ end
42
+
43
+ task :test => :jar
44
+
45
+ #require 'rcov/rcovtask'
46
+ #Rcov::RcovTask.new do |test|
47
+ # test.libs << 'test'
48
+ # test.pattern = 'test/**/test_*.rb'
49
+ # test.verbose = true
50
+ # test.rcov_opts << '--exclude "gems/*"'
51
+ #end
52
+
53
+ task :default => :test
54
+
55
+ require 'rdoc/task'
56
+ Rake::RDocTask.new do |rdoc|
57
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
58
+
59
+ rdoc.rdoc_dir = 'rdoc'
60
+ rdoc.title = "rbtree-jruby #{version}"
61
+ rdoc.rdoc_files.include('README*')
62
+ rdoc.rdoc_files.include('lib/**/*.rb')
63
+ end
64
+
65
+ require 'ant'
66
+
67
+ directory "pkg/classes"
68
+
69
+ desc "Clean up build artifacts"
70
+ task :clean do
71
+ rm_rf "pkg/classes"
72
+ rm_rf "lib/jubilee/*.jar"
73
+ end
74
+
75
+ BUILDTIME_LIB_DIR = File.join(File.dirname(__FILE__), "jars")
76
+
77
+ desc "Compile the extension, need jdk7 because vertx relies on it"
78
+ task :compile => "pkg/classes" do |t|
79
+ ant.javac :srcdir => "java", :destdir => t.prerequisites.first,
80
+ :source => "1.7", :target => "1.7", :debug => true,
81
+ :classpath => "${java.class.path}:${sun.boot.class.path}:jars/vertx-core-1.3.0.final.jar:jars/netty-3.6.0.Beta1.jar"
82
+ end
83
+
84
+ desc "Build the jar"
85
+ task :jar => [:clean, :compile] do
86
+ ant.jar :basedir => "pkg/classes", :destfile => "lib/jubilee/jubilee.jar", :includes => "**/*.class"
87
+ end
88
+
89
+ task :package => :jar
90
+
91
+ desc "Run the specs"
92
+ task :spec => :jar do
93
+ ruby "-S", "spec", "spec"
94
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'jubilee/cli'
4
+
5
+ cli = Jubilee::CLI.new ARGV
6
+ cli.run
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'spoon'
4
+
5
+ file_actions = Spoon::FileActions.new
6
+ file_actions.close(1)
7
+ file_actions.open(1, "log/development.log", File::WRONLY | File::TRUNC | File::CREAT, 0600)
8
+ spawn_attr = Spoon::SpawnAttributes.new
9
+ pid = Spoon.posix_spawn('jubilee', file_actions, spawn_attr, *ARGV)
10
+ open("tmp/jubilee.pid"){|f| f.write(pid) }
@@ -0,0 +1,19 @@
1
+ // -*- Mode: java; c-basic-offset: 4 -*- vim:set ft=java sw=4 sts=4:
2
+ // $Id$
3
+ import org.vertx.java.core.*;
4
+ import org.vertx.java.core.http.*;
5
+ public class ServerTest {
6
+ public static void main(String[] args) throws InterruptedException {
7
+ System.out.println("starting...");
8
+ Vertx vertx = Vertx.newVertx();
9
+ vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
10
+ public void handle(HttpServerRequest req) {
11
+ req.response.end("hello world");
12
+ //String file = req.path.equals("/") ? "index.html" : req.path;
13
+ //req.response.sendFile("webroot/" + file);
14
+ }
15
+ }).setSSL(true).setKeyStorePath("../jubilee/server-keystore.jks").setKeyStorePassword("wibble").listen(8080);
16
+ while (true)
17
+ Thread.currentThread().sleep(1);
18
+ }
19
+ }
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Index</title>
6
+ </head>
7
+ <body>
8
+ <h1>Hello world!</h1>
9
+ </body>
10
+ </html>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AntConfiguration">
4
+ <defaultAnt bundledAnt="true" />
5
+ </component>
6
+ </project>
7
+
@@ -0,0 +1,9 @@
1
+ <component name="libraryTable">
2
+ <library name="jruby">
3
+ <CLASSES>
4
+ <root url="jar://$USER_HOME$/.rbenv/versions/jruby-1.7.0/lib/jruby.jar!/" />
5
+ </CLASSES>
6
+ <JAVADOC />
7
+ <SOURCES />
8
+ </library>
9
+ </component>
@@ -0,0 +1,9 @@
1
+ <component name="libraryTable">
2
+ <library name="netty-3.6.0.Beta1">
3
+ <CLASSES>
4
+ <root url="jar://$PROJECT_DIR$/../jars/netty-3.6.0.Beta1.jar!/" />
5
+ </CLASSES>
6
+ <JAVADOC />
7
+ <SOURCES />
8
+ </library>
9
+ </component>
@@ -0,0 +1,9 @@
1
+ <component name="libraryTable">
2
+ <library name="vertx-core-1.3.0.final">
3
+ <CLASSES>
4
+ <root url="jar://$PROJECT_DIR$/../jars/vertx-core-1.3.0.final.jar!/" />
5
+ </CLASSES>
6
+ <JAVADOC />
7
+ <SOURCES />
8
+ </library>
9
+ </component>
@@ -0,0 +1,21 @@
1
+ package jubilee;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.jubilee.impl.NullIO;
5
+ import org.jruby.jubilee.impl.RubyIORackErrors;
6
+ import org.jruby.jubilee.impl.RubyIORackInput;
7
+ import org.jruby.runtime.load.BasicLibraryService;
8
+
9
+ import org.jruby.jubilee.Server;
10
+
11
+ import java.io.IOException;
12
+
13
+ public class JubileeService implements BasicLibraryService {
14
+ public boolean basicLoad(final Ruby ruby) throws IOException {
15
+ Server.createServerClass(ruby);
16
+ RubyIORackErrors.createRubyIORackErrorsClass(ruby);
17
+ RubyIORackInput.createRubyIORackInputClass(ruby);
18
+ NullIO.createNullIOClass(ruby);
19
+ return true;
20
+ }
21
+ }
@@ -0,0 +1,148 @@
1
+ package org.jruby.jubilee;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyArray;
5
+
6
+ import java.util.HashMap;
7
+ import java.util.Map;
8
+
9
+ /**
10
+ * Created with IntelliJ IDEA.
11
+ * User: isaiah
12
+ * Date: 11/26/12
13
+ * Time: 11:45 AM
14
+ */
15
+ public final class Const {
16
+
17
+ public static final String JUBILEE_VERSION = "Jubilee 0.1.0";
18
+ public static final String HTTP_11 = "HTTP/1.1";
19
+ public static final String HTTP_10 = "HTTP/1.0";
20
+
21
+ public static final String SERVER_SOFTWARE = "SERVER_SOFTWARE";
22
+ public static final String SERVER_PROTOCOL = "SERVER_PROTOCOL";
23
+ public static final String GATEWAY_INTERFACE = "GATEWAY_INTERFACE";
24
+ public static final String SERVER_NAME = "SERVER_NAME";
25
+ public static final String SERVER_PORT = "SERVER_PORT";
26
+
27
+ public static final String CGI_VER = "CGI/1.2";
28
+
29
+ public static final String RACK_INPUT = "rack.input";
30
+
31
+ public static final String REQUEST_METHOD = "REQUEST_METHOD";
32
+ public static final String GET = "GET";
33
+ public static final String POST = "POST";
34
+ public static final String REQUEST_PATH = "REQUEST_PATH";
35
+ public static final String REQUEST_URI = "REQUEST_URI";
36
+ public static final String PATH_INFO = "PATH_INFO";
37
+ public static final String QUERY_STRING = "QUERY_STRING";
38
+ public static final String LOCALHOST = "localhost";
39
+ public static final String PORT_80 = "80";
40
+
41
+ public static final String REMOTE_ADDR = "REMOTE_ADDR";
42
+ public static final String HTTP_HOST = "HTTP_HOST";
43
+ public static final String HTTP_USER_AGENT = "HTTP_USER_AGENT";
44
+ public static final String HTTP_ACCEPT = "HTTP_ACCEPT";
45
+ public static final String HTTP_COOKIE = "HTTP_COOKIE";
46
+ public static final String HTTP_ACCEPT_LANGUAGE = "HTTP_ACCEPT_LANGUAGE";
47
+ public static final String HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING";
48
+ public static final String HTTP_CONNECTION = "HTTP_CONNECTION";
49
+ public static final String HTTP_CONTENT_TYPE = "CONTENT_TYPE";
50
+ public static final String HTTP_CONTENT_LENGTH = "CONTENT_LENGTH";
51
+
52
+ public static class Rack {
53
+ public static final String HTTP_DATE = "HTTP_DATE";
54
+ public static final String HTTP_EXPECT = "HTTP_EXPECT";
55
+ public static final String HTTP_IF_MATCH = "HTTP_IF_MATCH";
56
+ public static final String HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE";
57
+ public static final String HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH";
58
+ public static final String HTTP_IF_RANGE = "HTTP_IF_RANGE";
59
+ public static final String HTTP_IF_UNMODIFIED_SINCE = "HTTP_IF_UNMODIFIED_SINCE";
60
+ public static final String HTTP_RANGE = "HTTP_RANGE";
61
+ public static final String HTTP_PRAGMA = "HTTP_PRAGMA";
62
+ public static final String HTTP_MAX_FORWARDS = "HTTP_MAX_FORWARDS";
63
+ public static final String HTTP_REFERER = "HTTP_REFERER";
64
+ public static final String HTTP_VIA = "HTTP_VIA";
65
+ public static final String HTTP_WARNING = "HTTP_WARNING";
66
+
67
+ public static final String HTTP_X_REQUESTED_WITH = "HTTP_X_REQUESTED_WITH"; // xhr
68
+ public static final String HTTP_DNT = "HTTP_DNT"; // do-not-track
69
+ public static final String HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR"; // original ip
70
+ }
71
+
72
+ public static class Vertx {
73
+ // all lower case since vertx has converted them
74
+ public static final String COOKIE = "cookie";
75
+ public static final String USER_AGENT = "user-agent";
76
+ public static final String ACCEPT = "accept";
77
+ public static final String ACCEPT_LANGUAGE = "accept-language";
78
+ public static final String ACCEPT_ENCODING = "accept-encoding";
79
+ public static final String CONNECTION = "connection";
80
+ public static final String CONTENT_TYPE = "content-type";
81
+ public static final String CONTENT_LENGTH = "content-length";
82
+ public static final String HOST = "host";
83
+
84
+ public static final String DATE = "date";
85
+ public static final String EXPECT = "expect";
86
+ public static final String IF_MATCH = "if-match";
87
+ public static final String IF_MODIFIED_SINCE = "if-modified-since";
88
+ public static final String IF_NONE_MATCH = "if-none-match";
89
+ public static final String IF_RANGE = "if-range";
90
+ public static final String IF_UNMODIFIED_SINCE = "if-unmodified-since";
91
+ public static final String RANGE = "range";
92
+ public static final String PRAGMA = "pragma";
93
+ public static final String MAX_FORWARDS = "max-forwards";
94
+ public static final String REFERER = "referer";
95
+ public static final String VIA = "via";
96
+ public static final String WARNING = "warning";
97
+
98
+ // Non-standard request headers http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Common_non-standard_request_headers
99
+ public static final String X_REQUESTED_WITH = "x-requested-with"; // xhr
100
+ public static final String DNT = "dnt"; // do-not-track
101
+ public static final String X_FORWARDED_FOR = "x-forwarded-for"; // original ip
102
+ }
103
+
104
+ public static Map<String, String> ADDITIONAL_HEADERS = new HashMap<String, String>();
105
+
106
+ static {
107
+ ADDITIONAL_HEADERS.put(Vertx.DATE, Rack.HTTP_DATE);
108
+ ADDITIONAL_HEADERS.put(Vertx.EXPECT, Rack.HTTP_EXPECT);
109
+ ADDITIONAL_HEADERS.put(Vertx.IF_MATCH, Rack.HTTP_IF_MATCH);
110
+ ADDITIONAL_HEADERS.put(Vertx.IF_MODIFIED_SINCE, Rack.HTTP_IF_MODIFIED_SINCE);
111
+ ADDITIONAL_HEADERS.put(Vertx.IF_NONE_MATCH, Rack.HTTP_IF_NONE_MATCH);
112
+ ADDITIONAL_HEADERS.put(Vertx.IF_RANGE, Rack.HTTP_IF_RANGE);
113
+ ADDITIONAL_HEADERS.put(Vertx.IF_UNMODIFIED_SINCE, Rack.HTTP_IF_UNMODIFIED_SINCE);
114
+ ADDITIONAL_HEADERS.put(Vertx.RANGE, Rack.HTTP_RANGE);
115
+ ADDITIONAL_HEADERS.put(Vertx.PRAGMA, Rack.HTTP_PRAGMA);
116
+ ADDITIONAL_HEADERS.put(Vertx.MAX_FORWARDS, Rack.HTTP_MAX_FORWARDS);
117
+ ADDITIONAL_HEADERS.put(Vertx.REFERER, Rack.HTTP_REFERER);
118
+ ADDITIONAL_HEADERS.put(Vertx.VIA, Rack.HTTP_VIA);
119
+ ADDITIONAL_HEADERS.put(Vertx.WARNING, Rack.HTTP_WARNING);
120
+ ADDITIONAL_HEADERS.put(Vertx.X_REQUESTED_WITH, Rack.HTTP_X_REQUESTED_WITH);
121
+ ADDITIONAL_HEADERS.put(Vertx.DNT, Rack.HTTP_DNT);
122
+ ADDITIONAL_HEADERS.put(Vertx.X_FORWARDED_FOR, Rack.HTTP_X_FORWARDED_FOR);
123
+ }
124
+
125
+ public static RubyArray RackVersion(Ruby runtime) {
126
+ RubyArray version = RubyArray.newArray(runtime, 2);
127
+ version.add("1");
128
+ version.add("4");
129
+ return version;
130
+ }
131
+
132
+ public static final String HTTP = "http";
133
+ public static final String HTTPS = "https";
134
+ public static final String URL_SCHEME = "rack.url_scheme";
135
+ public static final String RACK_VERSION = "rack.version";
136
+ public static final String RACK_ERRORS = "rack.errors";
137
+ public static final String RACK_MULTITHREAD = "rack.multithread";
138
+ public static final String RACK_MULTIPROCESS = "rack.multiprocess";
139
+ public static final String RACK_RUNONCE = "rack.run_once";
140
+ public static final String SCRIPT_NAME = "SCRIPT_NAME";
141
+
142
+ private Const() {
143
+ }
144
+
145
+ // Internal
146
+ public static final String END_OF_BODY = "__EOF__";
147
+ public static final byte EOL = '\n';
148
+ }