jubilee 2.1.0.Alpha1-java → 2.1.0.beta-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.
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