jubilee 2.1.0.Alpha1-java → 2.1.0.beta-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG +9 -0
  4. data/README.md +12 -7
  5. data/jars/vertx-core-2.1.1.jar +0 -0
  6. data/java/src/jubilee/JubileeService.java +3 -3
  7. data/java/src/org/jruby/jubilee/Const.java +1 -1
  8. data/java/src/org/jruby/jubilee/JubileeVerticle.java +29 -4
  9. data/java/src/org/jruby/jubilee/RackApplication.java +38 -35
  10. data/java/src/org/jruby/jubilee/RackEnvironment.java +57 -23
  11. data/java/src/org/jruby/jubilee/RackEnvironmentHash.java +64 -11
  12. data/java/src/org/jruby/jubilee/RackInput.java +13 -10
  13. data/java/src/org/jruby/jubilee/RubyCallable.java +52 -0
  14. data/java/src/org/jruby/jubilee/RubyChannel.java +89 -0
  15. data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +72 -60
  16. data/java/src/org/jruby/jubilee/RubyNetSocket.java +169 -0
  17. data/java/src/org/jruby/jubilee/RubyPlatformManager.java +129 -113
  18. data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +9 -9
  19. data/java/src/org/jruby/jubilee/impl/RubyNullIO.java +1 -1
  20. data/java/src/org/jruby/jubilee/utils/RubyHelper.java +0 -6
  21. data/java/src/org/jruby/jubilee/vertx/JubileeVertx.java +12 -11
  22. data/jubilee.gemspec +43 -20
  23. data/lib/jubilee.rb +0 -1
  24. data/lib/jubilee/cli.rb +5 -3
  25. data/lib/jubilee/configuration.rb +2 -7
  26. data/lib/jubilee/const.rb +30 -28
  27. data/lib/jubilee/response.rb +40 -5
  28. data/lib/jubilee/server.rb +0 -3
  29. data/lib/jubilee/version.rb +1 -1
  30. data/spec/apps/rails4/basic/Gemfile +0 -2
  31. data/spec/apps/rails4/basic/Gemfile.lock +0 -7
  32. data/spec/integration/basic_rack_spec.rb +4 -3
  33. data/spec/integration/basic_rails4_spec.rb +4 -3
  34. data/spec/integration/basic_sinatra_spec.rb +4 -4
  35. data/spec/spec_helper.rb +1 -0
  36. data/test/{config → apps}/app.rb +0 -0
  37. data/test/apps/checker.ru +5 -10
  38. data/test/apps/chunked.ru +3 -0
  39. data/test/{config → apps}/config.ru +0 -0
  40. data/test/apps/content_length.ru +3 -0
  41. data/test/apps/hex.ru +4 -0
  42. data/test/apps/hijack.ru +7 -0
  43. data/test/apps/hijack2.ru +7 -0
  44. data/test/apps/huge.ru +4 -0
  45. data/test/apps/method_override.ru +1 -1
  46. data/test/apps/overwrite_check.ru +3 -2
  47. data/test/apps/persistent.rb +14 -0
  48. data/test/apps/persistent.ru +3 -0
  49. data/test/apps/rack_input.ru +5 -0
  50. data/test/apps/self_chunked.ru +6 -0
  51. data/test/apps/sha1.ru +2 -0
  52. data/test/apps/simple.ru +10 -1
  53. data/test/jubilee/test_cli.rb +1 -1
  54. data/test/jubilee/test_configuration.rb +1 -3
  55. data/test/jubilee/test_hijack.rb +27 -0
  56. data/test/jubilee/test_persistent.rb +208 -0
  57. data/test/jubilee/test_rack_server.rb +29 -68
  58. data/test/jubilee/test_server.rb +49 -15
  59. data/test/jubilee/test_upload.rb +13 -60
  60. data/test/test_helper.rb +2 -2
  61. metadata +19 -9
  62. data/java/src/org/jruby/jubilee/RubyServer.java +0 -159
  63. data/lib/jubilee/jubilee.jar +0 -0
  64. data/lib/rack/chunked.rb +0 -38
  65. data/test/config/app.ru +0 -3
  66. data/test/jubilee/test_response.rb +0 -270
@@ -16,4 +16,3 @@ require 'jubilee/application'
16
16
  require 'jubilee/configuration'
17
17
  require 'jubilee/response'
18
18
  require 'rack/handler/jubilee'
19
- require 'rack/chunked'
@@ -40,7 +40,9 @@ module Jubilee
40
40
  else
41
41
  @config = Jubilee::Configuration.new(@options)
42
42
  server = Jubilee::Server.new(@config.options)
43
- #server.start
43
+ server.start do
44
+ puts "Jubilee is listening on port #{@config.options[:Port]}, press Ctrl+C to quit"
45
+ end
44
46
  thread = Thread.current
45
47
  Signal.trap("INT") do
46
48
  server.stop
@@ -73,7 +75,7 @@ module Jubilee
73
75
  @options[:daemon] = true
74
76
  end
75
77
  o.on "--dir DIR", "Change to DIR before starting" do |arg|
76
- @options[:chdir] = arg
78
+ @options[:root] = arg
77
79
  end
78
80
  o.on "-p", "--port PORT", "Define which PORT the server should bind" do |arg|
79
81
  @options[:Port] = arg.to_i
@@ -84,7 +86,7 @@ module Jubilee
84
86
  o.on "-e", "--environment ENV", "Rack environment" do |arg|
85
87
  @options[:environment] = arg
86
88
  end
87
- o.on "-n", "--instances NUM", "Define how many instances of web servers to run" do |arg|
89
+ o.on "-n", "--instances NUM", "Define how many instances of web servers to run, default 4" do |arg|
88
90
  @options[:instances] = arg.to_i
89
91
  end
90
92
  o.separator ""
@@ -19,7 +19,7 @@ module Jubilee
19
19
 
20
20
  def reload
21
21
  instance_eval(File.read(config_file), config_file) if config_file
22
- load_rack_adapter
22
+ @options[:rackup] = rackup
23
23
  end
24
24
 
25
25
  # sets the host and port jubilee listens to +address+ may be an Integer port
@@ -34,7 +34,7 @@ module Jubilee
34
34
 
35
35
  # sets the working directory for jubilee
36
36
  def working_directory(path)
37
- @options[:chdir] = File.expand_path(path)
37
+ @options[:root] = File.expand_path(path)
38
38
  end
39
39
 
40
40
  # sets the RACK_ENV environment variable
@@ -104,11 +104,6 @@ module Jubilee
104
104
  end
105
105
 
106
106
  private
107
- def load_rack_adapter(&block)
108
- Dir.chdir(@options[:chdir]) if @options[:chdir]
109
- @options[:rackup] = rackup
110
- end
111
-
112
107
  def rackup
113
108
  @options[:rackup] || "config.ru"
114
109
  end
@@ -1,39 +1,41 @@
1
1
  module Jubilee
2
2
  module Const
3
- JUBILEE_VERSION = Version::STRING
4
- HTTP_11 = "HTTP/1.1".freeze
5
- HTTP_10 = "HTTP/1.0".freeze
3
+ JUBILEE_VERSION = Version::STRING
4
+ HTTP_11 = "HTTP/1.1".freeze
5
+ HTTP_10 = "HTTP/1.0".freeze
6
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
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
12
 
13
- CGI_VER = "CGI/1.2".freeze
13
+ CGI_VER = "CGI/1.2".freeze
14
14
 
15
- RACK_INPUT = "rack.input".freeze
15
+ RACK_INPUT = "rack.input".freeze
16
+ HIJACK = "rack.hijack".freeze
16
17
 
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
18
+ REQUEST_METHOD = 'REQUEST_METHOD'.freeze
19
+ GET = 'GET'.freeze
20
+ POST = "POST".freeze
21
+ REQUEST_PATH = "REQUEST_PATH".freeze
22
+ REQUEST_URI = "REQUEST_URI".freeze
23
+ PATH_INFO = "PATH_INFO".freeze
24
+ QUERY_STRING = "QUERY_STRING".freeze
24
25
 
25
- CONTENT_LENGTH = "Content-Length".freeze
26
- TRANSFER_ENCODING = "Transfer-Encoding".freeze
26
+ CONTENT_LENGTH = "Content-Length".freeze
27
+ TRANSFER_ENCODING = "Transfer-Encoding".freeze
27
28
 
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
29
+ HTTP_VERSION = "HTTP_VERSION".freeze
30
+ HTTP_HOST = "HTTP_HOST".freeze
31
+ HTTP_USER_AGENT = "HTTP_USER_AGENT".freeze
32
+ HTTP_ACCEPT = "HTTP_ACCEPT".freeze
33
+ HTTP_COOKIE = "HTTP_COOKIE".freeze
34
+ HTTP_ACCEPT_LANGUAGE = "HTTP_ACCEPT_LANGUAGE".freeze
35
+ HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING".freeze
36
+ HTTP_CONNECTION = "HTTP_CONNECTION".freeze
37
+ NEWLINE = "\n".freeze
38
+ CHUNKED = "chunked".freeze
37
39
 
38
40
  STATUS_WITH_NO_ENTITY_BODY = Hash[[204,205,304].map{|s| [s, true]}]
39
41
  end
@@ -6,8 +6,10 @@ module Jubilee
6
6
 
7
7
  def initialize(array)
8
8
  @status, @headers, @body = *array
9
- @status = @status.to_i
10
- @content_length = nil
9
+ @status = @status.to_i
10
+ @content_length = nil
11
+ @chunked = false
12
+ @hijack = nil
11
13
  if @body.kind_of? Array and @body.size == 1
12
14
  @content_length = @body[0].bytesize
13
15
  end
@@ -18,9 +20,13 @@ module Jubilee
18
20
  no_body = @status < 200 || STATUS_WITH_NO_ENTITY_BODY[@status]
19
21
  write_status(response)
20
22
  write_headers(response)
23
+ if @hijack
24
+ @hijack.call(response.net_socket)
25
+ return
26
+ end
21
27
  if no_body
22
28
  response.end
23
- else
29
+ else
24
30
  if @body.respond_to?(:to_path)
25
31
  response.send_file(@body.to_path)
26
32
  else
@@ -46,7 +52,12 @@ module Jubilee
46
52
  @content_length = values
47
53
  next
48
54
  when TRANSFER_ENCODING
49
- @content_length = nil
55
+ if @chunked = (values == CHUNKED)
56
+ @content_length = nil
57
+ end
58
+ when HIJACK
59
+ @hijack = values
60
+ next
50
61
  end
51
62
  # Multiple values are joined by \n
52
63
  response.put_header(key, values)
@@ -62,7 +73,31 @@ module Jubilee
62
73
  end
63
74
 
64
75
  @body.each do |part|
65
- response.write(part)
76
+ if chunk = @chunked ? self.class.strip_term_markers(part) : part
77
+ response.write(chunk)
78
+ end
79
+ end
80
+ end
81
+
82
+ def self.strip_term_markers(chunk)
83
+ # Heavily copied from jruby-rack's rack/response.rb
84
+ term = "\r\n"
85
+ tail = "0#{term}#{term}".freeze
86
+ term_regex = /^([0-9a-fA-F]+)#{Regexp.escape(term)}(.+)#{Regexp.escape(term)}/mo
87
+ if chunk == tail
88
+ # end of chunking, do nothing
89
+ nil
90
+ elsif chunk =~ term_regex
91
+ # format is (size.to_s(16)) term (chunk) term
92
+ # if the size doesn't match then this is some
93
+ # output that just happened to match our regex
94
+ if $1.to_i(16) == $2.bytesize
95
+ $2
96
+ else
97
+ chunk
98
+ end
99
+ else
100
+ chunk
66
101
  end
67
102
  end
68
103
  end
@@ -9,8 +9,5 @@ module Jubilee
9
9
  options[:Port] = options[:Port].to_i
10
10
  super(options)
11
11
  end
12
-
13
- def start
14
- end
15
12
  end
16
13
  end
@@ -3,7 +3,7 @@ module Jubilee
3
3
  MAJOR = 2
4
4
  MINOR = 1
5
5
  PATCH = 0
6
- BUILD = "Alpha1"
6
+ BUILD = "beta"
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
9
  end
@@ -28,8 +28,6 @@ gem 'turbolinks'
28
28
  # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
29
29
  gem 'jbuilder', '~> 1.2'
30
30
 
31
- gem 'jubilee'
32
-
33
31
  # Use ActiveModel has_secure_password
34
32
  # gem 'bcrypt-ruby', '~> 3.0.0'
35
33
 
@@ -40,7 +40,6 @@ GEM
40
40
  coffee-script-source (1.6.3)
41
41
  erubis (2.7.0)
42
42
  execjs (2.0.2)
43
- ffi (1.9.3-java)
44
43
  hike (1.2.3)
45
44
  i18n (0.6.9)
46
45
  jbuilder (1.5.3)
@@ -52,9 +51,6 @@ GEM
52
51
  thor (>= 0.14, < 2.0)
53
52
  json (1.8.1)
54
53
  json (1.8.1-java)
55
- jubilee (2.0.0-java)
56
- rack (>= 1.4.1)
57
- spoon (~> 0.0.4)
58
54
  mail (2.5.4)
59
55
  mime-types (~> 1.16)
60
56
  treetop (~> 1.4.8)
@@ -84,8 +80,6 @@ GEM
84
80
  railties (>= 4.0.0, < 5.0)
85
81
  sass (>= 3.1.10)
86
82
  sprockets-rails (~> 2.0.0)
87
- spoon (0.0.4)
88
- ffi
89
83
  sprockets (2.10.1)
90
84
  hike (~> 1.2)
91
85
  multi_json (~> 1.0)
@@ -123,7 +117,6 @@ DEPENDENCIES
123
117
  jbuilder (~> 1.2)
124
118
  jdbc-sqlite3
125
119
  jquery-rails (>= 3.0)
126
- jubilee
127
120
  rails (= 4.0.1)
128
121
  sass-rails (~> 4.0.0)
129
122
  therubyrhino
@@ -3,10 +3,11 @@ require 'spec_helper'
3
3
  feature "basic rack at non-root context" do
4
4
 
5
5
  before(:all) do
6
- configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/rack/basic")
6
+ configurator = Jubilee::Configuration.new(root: "#{apps_dir}/rack/basic", instances: 1)
7
7
  @server = Jubilee::Server.new(configurator.options)
8
- @server.start
9
- sleep 0.1
8
+ q = Queue.new
9
+ @server.start{ q << 1 }
10
+ q.pop
10
11
  end
11
12
 
12
13
  after(:all) do
@@ -3,10 +3,11 @@ require 'spec_helper'
3
3
  feature 'basic rails4 test' do
4
4
 
5
5
  before(:all) do
6
- configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/rails4/basic")
6
+ configurator = Jubilee::Configuration.new(root: "#{apps_dir}/rails4/basic", instances: 1)
7
7
  @server = Jubilee::Server.new(configurator.options)
8
- @server.start
9
- sleep 11
8
+ q = Queue.new
9
+ @server.start { q << 1 }
10
+ q.pop
10
11
  end
11
12
 
12
13
  after(:all) do
@@ -3,10 +3,11 @@ require 'spec_helper'
3
3
  feature "basic sinatra test" do
4
4
 
5
5
  before(:all) do
6
- configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/sinatra/basic")
6
+ configurator = Jubilee::Configuration.new(root: "#{apps_dir}/sinatra/basic", instances: 1)
7
7
  @server = Jubilee::Server.new(configurator.options)
8
- @server.start
9
- sleep 1
8
+ q = Queue.new
9
+ @server.start{ q << 1 }
10
+ q.pop
10
11
  end
11
12
 
12
13
  after(:all) do
@@ -71,7 +72,6 @@ feature "basic sinatra test" do
71
72
  uri = URI.parse("#{Capybara.app_host}/poster")
72
73
  Net::HTTP.start(uri.host, uri.port) do |http|
73
74
  100.times do |i|
74
- http.request(Net::HTTP::Get.new(uri.request_uri))
75
75
  request = Net::HTTP::Post.new(uri.request_uri)
76
76
  request.form_data = {'field' => 'nothing'}
77
77
  response = http.request(request)
@@ -1,3 +1,4 @@
1
+ $:.unshift(File.expand_path("../../lib", __FILE__))
1
2
  require 'jubilee'
2
3
  require 'capybara/poltergeist'
3
4
  require 'capybara/rspec'
File without changes
@@ -1,24 +1,18 @@
1
- require 'rack'
1
+ require 'rack/lint'
2
+ require 'json'
2
3
  class ErrorChecker
3
4
  def initialize(app)
4
5
  @app = app
5
- @exception = nil
6
- @env = nil
7
6
  end
8
7
 
9
- attr_reader :exception, :env
10
-
11
8
  def call(env)
12
9
  begin
13
- @env = env
14
10
  return @app.call(env)
15
11
  rescue Exception => e
16
- @exception = e
17
-
18
12
  [
19
13
  500,
20
14
  { "X-Exception" => e.message, "X-Exception-Class" => e.class.to_s },
21
- ["Error detected"]
15
+ [JSON.dump({"exception" => e.message})]
22
16
  ]
23
17
  end
24
18
  end
@@ -35,4 +29,5 @@ end
35
29
 
36
30
  use ServerLint
37
31
  use ErrorChecker
38
- run lambda { |env| [200, { "X-Header" => "Works" }, ["Hello"]] }
32
+ app = lambda { |env| [200, { "X-Header" => "Works" }, [JSON.dump({r:'Hello'})]] }
33
+ run app
@@ -0,0 +1,3 @@
1
+ require_relative './persistent'
2
+
3
+ run Persistent.new(["Hello", "Chunked"])
File without changes
@@ -0,0 +1,3 @@
1
+ require_relative './persistent'
2
+
3
+ run Persistent.new(["hello", " world"], {"X-Header" => "Works", "Content-Length" => 11})
@@ -0,0 +1,4 @@
1
+ require_relative './persistent'
2
+
3
+ str = "This is longer and will be in hex"
4
+ run Persistent.new(["Hello", str])
@@ -0,0 +1,7 @@
1
+ app = lambda do |env|
2
+ io = env["rack.hijack"].call
3
+ io.write "HTTP/1.1 200\r\n\r\nBLAH\n"
4
+ [-1, {}, []]
5
+ end
6
+
7
+ run app
@@ -0,0 +1,7 @@
1
+ # hijack response is not supported by vertx yet
2
+ app = lambda do |env|
3
+ body = lambda {|io| io.write "BLAH\n"; io.close }
4
+ [200, {'rack.hijack' => body}, []]
5
+ end
6
+
7
+ run app
@@ -0,0 +1,4 @@
1
+ require_relative './app.rb'
2
+
3
+ giant = "x" * 2056610
4
+ run App.new(giant)
@@ -1,2 +1,2 @@
1
1
  use Rack::MethodOverride
2
- run lambda { |env| [200, { "X-Header" => "Works" }, ["Hello"]] }
2
+ run lambda { |env| [200, { "X-Header" => "Works" }, [env["REQUEST_METHOD"]]] }
@@ -1,8 +1,9 @@
1
1
  hdr = {'Content-Type' => 'text/plain', 'Content-Length' => '0'}
2
- run lambda do |env|
2
+ app = lambda do |env|
3
3
  nr = 0
4
4
  while buf = env['rack.input'].read(65536)
5
5
  nr += buf.size
6
6
  end
7
- [ 200, hdr.merge('HTTP-X-Read-Length' => nr.length), [] ]
7
+ [ 200, hdr.merge('X-Read-Length' => nr.to_s), [] ]
8
8
  end
9
+ run app
@@ -0,0 +1,14 @@
1
+ class Persistent
2
+ attr_reader :headers, :body
3
+
4
+ def initialize(body = ["Hello"], headers = { "X-Header" => "Works" })
5
+ @body = body
6
+ @headers = headers
7
+ end
8
+
9
+
10
+ def call(env)
11
+ status = Integer(env['HTTP_X_STATUS'] || 200)
12
+ [status, headers, body]
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ require_relative './persistent'
2
+
3
+ run Persistent.new