jubilee 1.0.2 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG +17 -0
  4. data/Gemfile +19 -1
  5. data/Gemfile.lock +189 -31
  6. data/LICENSE.txt +20 -0
  7. data/README.md +44 -5
  8. data/ROADMAP +5 -0
  9. data/Rakefile +6 -5
  10. data/examples/chatapp/Gemfile +2 -1
  11. data/examples/chatapp/Gemfile.lock +8 -6
  12. data/examples/chatapp/README.md +5 -2
  13. data/examples/chatapp/app.rb +24 -0
  14. data/examples/chatapp/public/assets/javascripts/application.js +59 -6
  15. data/examples/chatapp/public/assets/stylesheets/application.css +25 -0
  16. data/examples/jubilee.conf.rb +0 -3
  17. data/jars/{hazelcast-2.6.jar → hazelcast-2.6.3.jar} +0 -0
  18. data/jars/{netty-all-4.0.4.Final.jar → netty-all-4.0.13.Final.jar} +0 -0
  19. data/jars/vertx-core-2.1M3-SNAPSHOT.jar +0 -0
  20. data/jars/vertx-hazelcast-2.1M3-SNAPSHOT.jar +0 -0
  21. data/java/src/jubilee/JubileeService.java +7 -7
  22. data/java/src/org/jruby/jubilee/Const.java +10 -35
  23. data/java/src/org/jruby/jubilee/RackApplication.java +77 -46
  24. data/java/src/org/jruby/jubilee/RackResponse.java +1 -3
  25. data/java/src/org/jruby/jubilee/RubyHttpServerResponse.java +88 -0
  26. data/java/src/org/jruby/jubilee/{Server.java → RubyServer.java} +17 -14
  27. data/java/src/org/jruby/jubilee/impl/RackEnvironment.java +157 -0
  28. data/java/src/org/jruby/jubilee/impl/RackEnvironmentHash.java +449 -0
  29. data/java/src/org/jruby/jubilee/impl/RubyIORackInput.java +5 -5
  30. data/java/src/org/jruby/jubilee/impl/{NullIO.java → RubyNullIO.java} +5 -9
  31. data/java/src/org/jruby/jubilee/utils/RubyHelper.java +37 -0
  32. data/jubilee.gemspec +101 -14
  33. data/lib/jubilee.rb +4 -3
  34. data/lib/jubilee/cli.rb +2 -1
  35. data/lib/jubilee/configuration.rb +4 -9
  36. data/lib/jubilee/const.rb +2 -2
  37. data/lib/jubilee/jubilee.jar +0 -0
  38. data/lib/jubilee/response.rb +9 -8
  39. data/lib/jubilee/server.rb +1 -1
  40. data/lib/jubilee/version.rb +8 -1
  41. data/lib/rack/chunked.rb +38 -0
  42. data/spec/apps/rack/basic/config.ru +50 -0
  43. data/spec/apps/rails4/basic/.gitignore +16 -0
  44. data/spec/apps/rails4/basic/Gemfile +41 -0
  45. data/spec/apps/rails4/basic/Gemfile.lock +127 -0
  46. data/spec/apps/rails4/basic/README.rdoc +28 -0
  47. data/spec/apps/rails4/basic/Rakefile +6 -0
  48. data/spec/apps/rails4/basic/app/assets/images/.keep +0 -0
  49. data/spec/apps/rails4/basic/app/assets/images/rails.png +0 -0
  50. data/spec/apps/rails4/basic/app/assets/javascripts/application.js +16 -0
  51. data/spec/apps/rails4/basic/app/assets/stylesheets/application.css +13 -0
  52. data/spec/apps/rails4/basic/app/controllers/application_controller.rb +5 -0
  53. data/spec/apps/rails4/basic/app/controllers/concerns/.keep +0 -0
  54. data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb +11 -0
  55. data/spec/apps/rails4/basic/app/controllers/reloader_controller.rb.erb +11 -0
  56. data/spec/apps/rails4/basic/app/controllers/root_controller.rb +14 -0
  57. data/spec/apps/rails4/basic/app/helpers/application_helper.rb +2 -0
  58. data/spec/apps/rails4/basic/app/mailers/.keep +0 -0
  59. data/spec/apps/rails4/basic/app/models/.keep +0 -0
  60. data/spec/apps/rails4/basic/app/models/concerns/.keep +0 -0
  61. data/spec/apps/rails4/basic/app/views/layouts/application.html.erb +14 -0
  62. data/spec/apps/rails4/basic/app/views/reloader/index.html.erb +1 -0
  63. data/spec/apps/rails4/basic/app/views/root/index.html.erb +8 -0
  64. data/spec/apps/rails4/basic/app/views/root/streaming.html.erb +6 -0
  65. data/spec/apps/rails4/basic/bin/bundle +3 -0
  66. data/spec/apps/rails4/basic/bin/rails +4 -0
  67. data/spec/apps/rails4/basic/bin/rake +4 -0
  68. data/spec/apps/rails4/basic/config.ru +4 -0
  69. data/spec/apps/rails4/basic/config/application.rb +23 -0
  70. data/spec/apps/rails4/basic/config/boot.rb +4 -0
  71. data/spec/apps/rails4/basic/config/database.yml +20 -0
  72. data/spec/apps/rails4/basic/config/environment.rb +5 -0
  73. data/spec/apps/rails4/basic/config/environments/development.rb +29 -0
  74. data/spec/apps/rails4/basic/config/environments/production.rb +80 -0
  75. data/spec/apps/rails4/basic/config/environments/test.rb +36 -0
  76. data/spec/apps/rails4/basic/config/initializers/backtrace_silencers.rb +7 -0
  77. data/spec/apps/rails4/basic/config/initializers/filter_parameter_logging.rb +4 -0
  78. data/spec/apps/rails4/basic/config/initializers/inflections.rb +16 -0
  79. data/spec/apps/rails4/basic/config/initializers/mime_types.rb +5 -0
  80. data/spec/apps/rails4/basic/config/initializers/secret_token.rb +12 -0
  81. data/spec/apps/rails4/basic/config/initializers/session_store.rb +2 -0
  82. data/spec/apps/rails4/basic/config/initializers/wrap_parameters.rb +14 -0
  83. data/spec/apps/rails4/basic/config/locales/en.yml +23 -0
  84. data/spec/apps/rails4/basic/config/routes.rb +5 -0
  85. data/spec/apps/rails4/basic/db/seeds.rb +7 -0
  86. data/spec/apps/rails4/basic/lib/assets/.keep +0 -0
  87. data/spec/apps/rails4/basic/lib/tasks/.keep +0 -0
  88. data/spec/apps/rails4/basic/public/404.html +58 -0
  89. data/spec/apps/rails4/basic/public/422.html +58 -0
  90. data/spec/apps/rails4/basic/public/500.html +57 -0
  91. data/spec/apps/rails4/basic/public/favicon.ico +0 -0
  92. data/spec/apps/rails4/basic/public/robots.txt +5 -0
  93. data/spec/apps/rails4/basic/public/some_page.html +7 -0
  94. data/spec/apps/rails4/basic/test/controllers/.keep +0 -0
  95. data/spec/apps/rails4/basic/test/fixtures/.keep +0 -0
  96. data/spec/apps/rails4/basic/test/helpers/.keep +0 -0
  97. data/spec/apps/rails4/basic/test/integration/.keep +0 -0
  98. data/spec/apps/rails4/basic/test/mailers/.keep +0 -0
  99. data/spec/apps/rails4/basic/test/models/.keep +0 -0
  100. data/spec/apps/rails4/basic/test/test_helper.rb +15 -0
  101. data/spec/apps/rails4/basic/vendor/assets/javascripts/.keep +0 -0
  102. data/spec/apps/rails4/basic/vendor/assets/stylesheets/.keep +0 -0
  103. data/spec/apps/sinatra/basic/Gemfile +4 -0
  104. data/spec/apps/sinatra/basic/Gemfile.lock +20 -0
  105. data/spec/apps/sinatra/basic/basic.rb +27 -0
  106. data/spec/apps/sinatra/basic/config.ru +7 -0
  107. data/spec/apps/sinatra/basic/public/some_page.html +7 -0
  108. data/spec/apps/sinatra/basic/views/index.erb +4 -0
  109. data/spec/apps/sinatra/basic/views/posted.haml +2 -0
  110. data/spec/apps/sinatra/basic/views/poster.haml +4 -0
  111. data/spec/apps/sinatra/basic/views/request_mapping.haml +4 -0
  112. data/spec/integration/basic_rack_spec.rb +89 -0
  113. data/spec/integration/basic_rails4_spec.rb +64 -0
  114. data/spec/integration/basic_sinatra_spec.rb +80 -0
  115. data/spec/spec_helper.rb +13 -0
  116. data/test/jubilee/test_cli.rb +1 -1
  117. data/test/jubilee/test_configuration.rb +18 -1
  118. data/test/jubilee/test_rack_server.rb +7 -7
  119. data/test/jubilee/test_response.rb +35 -36
  120. data/test/jubilee/test_server.rb +1 -1
  121. data/test/jubilee/test_upload.rb +14 -11
  122. data/test/test_helper.rb +1 -0
  123. metadata +97 -18
  124. data/VERSION +0 -1
  125. data/jars/vertx-core-2.1.0-SNAPSHOT.jar +0 -0
  126. data/java/src/org/jruby/jubilee/RackErrors.java +0 -44
  127. data/java/src/org/jruby/jubilee/impl/DefaultRackEnvironment.java +0 -99
  128. data/java/src/org/jruby/jubilee/impl/RubyIORackErrors.java +0 -68
File without changes
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-agent: *
5
+ # Disallow: /
@@ -0,0 +1,7 @@
1
+ <html>
2
+ <body>
3
+ <div class="default" id="success">
4
+ static page
5
+ </div>
6
+ </body>
7
+ </html>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,15 @@
1
+ ENV["RAILS_ENV"] ||= "test"
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ require 'rails/test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+ ActiveRecord::Migration.check_pending!
7
+
8
+ # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
9
+ #
10
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
11
+ # -- they do not yet inherit this setting
12
+ fixtures :all
13
+
14
+ # Add more helper methods to be used by all tests here...
15
+ end
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gem "sinatra"
4
+ gem "haml"
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ haml (4.0.4)
5
+ tilt
6
+ rack (1.5.2)
7
+ rack-protection (1.5.1)
8
+ rack
9
+ sinatra (1.4.4)
10
+ rack (~> 1.4)
11
+ rack-protection (~> 1.4)
12
+ tilt (~> 1.3, >= 1.3.4)
13
+ tilt (1.4.1)
14
+
15
+ PLATFORMS
16
+ java
17
+
18
+ DEPENDENCIES
19
+ haml
20
+ sinatra
@@ -0,0 +1,27 @@
1
+
2
+ require 'rubygems'
3
+ require 'sinatra'
4
+
5
+ disable :logging
6
+
7
+ options '/' do
8
+ response.headers['Access-Control-Allow-Origin'] = '*'
9
+ response.headers['Access-Control-Allow-Methods'] = 'POST'
10
+ end
11
+
12
+ get '/' do
13
+ headers 'Biscuit' => 'Gravy'
14
+ erb :index
15
+ end
16
+
17
+ get '/request-mapping' do
18
+ haml :request_mapping
19
+ end
20
+
21
+ get '/poster' do
22
+ haml :poster
23
+ end
24
+
25
+ post '/poster' do
26
+ haml :posted
27
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'haml'
4
+
5
+ require_relative './basic'
6
+
7
+ run Sinatra::Application
@@ -0,0 +1,7 @@
1
+ <html>
2
+ <body>
3
+ <div class="default" id="success">
4
+ static page
5
+ </div>
6
+ </body>
7
+ </html>
@@ -0,0 +1,4 @@
1
+
2
+ <div class="sinatra-basic" id="success">
3
+ it worked with a view
4
+ </div>
@@ -0,0 +1,2 @@
1
+
2
+ #success= "you posted #{params[:field]}"
@@ -0,0 +1,4 @@
1
+
2
+ %form#success{:method=>'POST'}
3
+ %input{:type=>'text', :name=>'field', :value=>'nothing'}
4
+ %input#submit{:type=>'submit'}
@@ -0,0 +1,4 @@
1
+
2
+ #success
3
+ #scheme
4
+ = request.scheme
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ feature "basic rack at non-root context" do
4
+
5
+ before(:all) do
6
+ configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/rack/basic")
7
+ @server = Jubilee::Server.new(configurator.app, configurator.options)
8
+ @server.start
9
+ end
10
+
11
+ after(:all) do
12
+ @server.stop
13
+ end
14
+
15
+ it "should work for basic requests" do
16
+ visit "/basic-rack"
17
+ page.should have_content('it worked')
18
+ page.find("#success")[:class].strip.should == 'basic-rack'
19
+ page.find("#script_name").text.strip.should == ''
20
+ page.find("#path_info").text.strip.should == '/basic-rack'
21
+ page.find("#request_uri").text.strip.should == '/basic-rack'
22
+ end
23
+
24
+ it "should work for subcontext root with trailing slash" do
25
+ visit "/basic-rack/"
26
+ page.should have_content('it worked')
27
+ page.find("#success")[:class].strip.should == 'basic-rack'
28
+ page.find("#script_name").text.strip.should == ''
29
+ page.find("#path_info").text.strip.should == '/basic-rack/'
30
+ page.find("#request_uri").text.strip.should == '/basic-rack/'
31
+ end
32
+
33
+ it "should be running under the proper ruby version" do
34
+ visit "/basic-rack/"
35
+ page.find("#ruby-version").text.strip.should == RUBY_VERSION
36
+ end
37
+
38
+ it "should not have a vfs path for __FILE__" do
39
+ visit "/basic-rack/"
40
+ page.find("#path").text.strip.should_not match(/^vfs:/)
41
+ end
42
+
43
+ it "should not decode characters in URL" do
44
+ visit "/basic-rack/foo%23%2C"
45
+ page.find("#path_info").text.strip.should == '/basic-rack/foo%23%2C'
46
+ page.find("#request_uri").text.strip.should == '/basic-rack/foo%23%2C'
47
+ end
48
+
49
+ it "should contain correct request headers" do
50
+ uri = URI.parse("#{Capybara.app_host}/basic-rack/")
51
+ Net::HTTP.start(uri.host, uri.port) do |http|
52
+ accept = 'text/html;q=0.9,*/*;q=0.7'
53
+ response = http.get(uri.request_uri, {'Accept' => accept})
54
+ response.code.should == "200"
55
+ response.body.should include("<div id='accept_header'>#{accept}</div>")
56
+ end
57
+ end
58
+
59
+ it "should read post bodies via gets" do
60
+ uri = URI.parse("#{Capybara.app_host}/basic-rack/gets")
61
+ Net::HTTP.start(uri.host, uri.port) do |http|
62
+ request = Net::HTTP::Post.new(uri.request_uri)
63
+ request.form_data = {'field' => 'nothing'}
64
+ response = http.request(request)
65
+ response.body.should include("<div id='posted'>field=nothing</div>")
66
+ end
67
+ end
68
+
69
+ it "should read post bodies via read" do
70
+ uri = URI.parse("#{Capybara.app_host}/basic-rack/read")
71
+ Net::HTTP.start(uri.host, uri.port) do |http|
72
+ request = Net::HTTP::Post.new(uri.request_uri)
73
+ request.form_data = {'field' => 'nothing'}
74
+ response = http.request(request)
75
+ response.body.should include("<div id='posted'>field=nothing</div>")
76
+ end
77
+ end
78
+
79
+ it "should read post bodies via each" do
80
+ uri = URI.parse("#{Capybara.app_host}/basic-rack/each")
81
+ Net::HTTP.start(uri.host, uri.port) do |http|
82
+ request = Net::HTTP::Post.new(uri.request_uri)
83
+ request.form_data = {'field' => 'nothing'}
84
+ response = http.request(request)
85
+ response.body.should include("<div id='posted'>field=nothing</div>")
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'basic rails4 test' do
4
+
5
+ before(:all) do
6
+ configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/rails4/basic")
7
+ @server = Jubilee::Server.new(configurator.app, configurator.options)
8
+ @server.start
9
+ sleep 0.1
10
+ end
11
+
12
+ after(:all) do
13
+ @server.stop
14
+ end
15
+
16
+ it 'should do a basic get' do
17
+ visit '/'
18
+ page.should have_content('It works')
19
+ page.find('#success')[:class].should == 'basic-rails4'
20
+ end
21
+
22
+ context 'streaming' do
23
+ it "should work for small responses" do
24
+ verify_streaming("/root/streaming?count=0")
25
+ end
26
+
27
+ it "should work for large responses" do
28
+ verify_streaming("/root/streaming?count=500")
29
+ end
30
+
31
+ def verify_streaming(url)
32
+ uri = URI.parse("#{Capybara.app_host}#{url}")
33
+ Net::HTTP.get_response(uri) do |response|
34
+ response.should be_chunked
35
+ response.header['transfer-encoding'].should == 'chunked'
36
+ chunk_count, body = 0, ""
37
+ response.read_body do |chunk|
38
+ chunk_count += 1
39
+ body += chunk
40
+ end
41
+ body.should include('It works')
42
+ body.each_line do |line|
43
+ line.should_not match(/^\d+\s*$/)
44
+ end
45
+ chunk_count.should be > 1
46
+ end
47
+ end
48
+ end
49
+
50
+ it 'should return a static page beneath default public dir' do
51
+ visit "/some_page.html"
52
+ element = page.find('#success')
53
+ element.should_not be_nil
54
+ element.text.should == 'static page'
55
+ end
56
+
57
+ it "should support setting multiple cookies" do
58
+ visit "/root/multiple_cookies"
59
+ page.driver.cookies['foo1'].value.should == 'bar1'
60
+ page.driver.cookies['foo2'].value.should == 'bar2'
61
+ page.driver.cookies['foo3'].value.should == 'bar3'
62
+ end
63
+
64
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ feature "basic sinatra test" do
4
+
5
+ before(:all) do
6
+ configurator = Jubilee::Configuration.new(chdir: "#{apps_dir}/sinatra/basic")
7
+ @server = Jubilee::Server.new(configurator.app, configurator.options)
8
+ @server.start
9
+ end
10
+
11
+ after(:all) do
12
+ @server.stop
13
+ end
14
+
15
+ it "should work" do
16
+ visit ""
17
+ page.should have_content('it worked')
18
+ page.should have_selector('div.sinatra-basic')
19
+ find("#success").should have_content('it worked')
20
+ end
21
+
22
+ it "should return a valid request scheme" do
23
+ visit "/request-mapping"
24
+ find("#success #scheme").text.should eql("http")
25
+ end
26
+
27
+ it "should return a static page beneath default 'public' dir" do
28
+ visit "/some_page.html"
29
+ page.find('#success')[:class].should == 'default'
30
+ end
31
+
32
+ it "should return 304 for unmodified static assets" do
33
+ uri = URI.parse("#{Capybara.app_host}/some_page.html")
34
+ Net::HTTP.start(uri.host, uri.port) do |http|
35
+ request = Net::HTTP::Get.new(uri.request_uri)
36
+ request.add_field('If-Modified-Since', 'Sat, 31 Dec 2050 00:00:00 GMT')
37
+ response = http.request(request)
38
+ response.code.should == "304"
39
+ end
40
+ end
41
+
42
+ it "should post something" do
43
+ visit "/poster"
44
+ fill_in 'field', :with => 'something'
45
+ click_button 'submit'
46
+ find('#success').should have_content("you posted something")
47
+ end
48
+
49
+
50
+ it "should allow headers through" do
51
+ uri = URI.parse("#{Capybara.app_host}/")
52
+ response = Net::HTTP.get_response(uri)
53
+ response['Biscuit'].should == 'Gravy'
54
+ end
55
+
56
+ it "should allow OPTIONS requests" do
57
+ uri = URI.parse("#{Capybara.app_host}/")
58
+ Net::HTTP.start(uri.host, uri.port) do |http|
59
+ request = Net::HTTP::Options.new(uri.request_uri)
60
+ response = http.request(request)
61
+ response['access-control-allow-origin'].should == '*'
62
+ response['access-control-allow-methods'].should == 'POST'
63
+ end
64
+
65
+ end
66
+
67
+ it "should test Sir Postalot" do
68
+ uri = URI.parse("#{Capybara.app_host}/poster")
69
+ Net::HTTP.start(uri.host, uri.port) do |http|
70
+ 100.times do |i|
71
+ http.request(Net::HTTP::Get.new(uri.request_uri))
72
+ request = Net::HTTP::Post.new(uri.request_uri)
73
+ request.form_data = {'field' => 'nothing'}
74
+ response = http.request(request)
75
+ response.body.should include("<div id='success'>you posted nothing</div>")
76
+ end
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,13 @@
1
+ require 'jubilee'
2
+ require 'capybara/poltergeist'
3
+ require 'capybara/rspec'
4
+ require 'ostruct'
5
+ require 'net/http'
6
+
7
+ Capybara.app_host = "http://localhost:8080"
8
+ Capybara.run_server = false
9
+ Capybara.default_driver = :poltergeist
10
+
11
+ def apps_dir
12
+ File.expand_path("../apps", __FILE__)
13
+ end
@@ -6,6 +6,6 @@ class TestJubileeCLI < MiniTest::Unit::TestCase
6
6
  cli = Jubilee::CLI.new(["app.rb"])
7
7
  cli.parse_options
8
8
  assert_equal "app.rb", cli.options[:rackup]
9
- assert_equal 3215, cli.options[:Port]
9
+ assert_equal 8080, cli.options[:Port]
10
10
  end
11
11
  end
@@ -4,11 +4,28 @@ require 'jubilee/configuration'
4
4
  class TestConfig < MiniTest::Unit::TestCase
5
5
 
6
6
  def setup
7
- @config = Jubilee::Configuration.new({rackup: "config/app.rb"})
8
7
  end
9
8
 
10
9
  def test_load
10
+ @config = Jubilee::Configuration.new({rackup: "config/app.rb"})
11
11
  resp = [200, {"Content-Type" => "text/plain"}, ["embeded app"]]
12
12
  assert_equal resp, @config.app.call({})
13
13
  end
14
+
15
+ def test_config_invalid
16
+ tmp = Tempfile.new("jubilee_config")
17
+ tmp.syswrite(%q(abcd "helloword"))
18
+ assert_raises(NoMethodError) do
19
+ Jubilee::Configuration.new(config_file: tmp.path)
20
+ end
21
+ end
22
+
23
+ def test_config_non_exist
24
+ tmp = Tempfile.new("jubilee_config")
25
+ path = tmp.path
26
+ tmp.close!
27
+ assert_raises(Errno::ENOENT) do
28
+ Jubilee::Configuration.new(config_file: path)
29
+ end
30
+ end
14
31
  end