jubilee 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }