yahns 0.0.0 → 0.0.1

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.
@@ -12,45 +12,51 @@ class TestConfig < Testcase
12
12
  end
13
13
 
14
14
  def test_multi_conf_example
15
- tmpdir = Dir.mktmpdir
15
+ pid = fork do
16
+ tmpdir = Dir.mktmpdir
16
17
 
17
- # modify the example config file for testing
18
- path = "examples/yahns_multi.conf.rb"
19
- cfgs = File.read(path)
20
- cfgs.gsub!(%r{/path/to/}, "#{tmpdir}/")
21
- conf = File.open("#{tmpdir}/yahns_multi.conf.rb", "w")
22
- conf.sync = true
23
- conf.write(cfgs)
24
- File.open("#{tmpdir}/another.ru", "w") do |fp|
25
- fp.puts("run Rack::Lobster.new\n")
26
- end
27
- FileUtils.mkpath("#{tmpdir}/another")
18
+ # modify the example config file for testing
19
+ path = "examples/yahns_multi.conf.rb"
20
+ cfgs = File.read(path)
21
+ cfgs.gsub!(%r{/path/to/}, "#{tmpdir}/")
22
+ conf = File.open("#{tmpdir}/yahns_multi.conf.rb", "w")
23
+ conf.sync = true
24
+ conf.write(cfgs)
25
+ File.open("#{tmpdir}/another.ru", "w") do |fp|
26
+ fp.puts("run Rack::Lobster.new\n")
27
+ end
28
+ FileUtils.mkpath("#{tmpdir}/another")
28
29
 
29
- cfg = GTL.synchronize { Yahns::Config.new(conf.path) }
30
- assert_instance_of Yahns::Config, cfg
31
- ensure
32
- FileUtils.rm_rf(tmpdir) if tmpdir
30
+ cfg = Yahns::Config.new(conf.path)
31
+ FileUtils.rm_rf(tmpdir)
32
+ exit!(Yahns::Config === cfg)
33
+ end
34
+ _, status = Process.waitpid2(pid)
35
+ assert status.success?
33
36
  end
34
37
 
35
38
  def test_rack_basic_conf_example
36
- tmpdir = Dir.mktmpdir
39
+ pid = fork do
40
+ tmpdir = Dir.mktmpdir
37
41
 
38
- # modify the example config file for testing
39
- path = "examples/yahns_rack_basic.conf.rb"
40
- cfgs = File.read(path)
41
- cfgs.gsub!(%r{/path/to/}, "#{tmpdir}/")
42
- Dir.mkdir("#{tmpdir}/my_app")
43
- Dir.mkdir("#{tmpdir}/my_logs")
44
- Dir.mkdir("#{tmpdir}/my_pids")
45
- conf = File.open("#{tmpdir}/yahns_rack_basic.conf.rb", "w")
46
- conf.sync = true
47
- conf.write(cfgs)
48
- File.open("#{tmpdir}/my_app/config.ru", "w") do |fp|
49
- fp.puts("run Rack::Lobster.new\n")
42
+ # modify the example config file for testing
43
+ path = "examples/yahns_rack_basic.conf.rb"
44
+ cfgs = File.read(path)
45
+ cfgs.gsub!(%r{/path/to/}, "#{tmpdir}/")
46
+ Dir.mkdir("#{tmpdir}/my_app")
47
+ Dir.mkdir("#{tmpdir}/my_logs")
48
+ Dir.mkdir("#{tmpdir}/my_pids")
49
+ conf = File.open("#{tmpdir}/yahns_rack_basic.conf.rb", "w")
50
+ conf.sync = true
51
+ conf.write(cfgs)
52
+ File.open("#{tmpdir}/my_app/config.ru", "w") do |fp|
53
+ fp.puts("run Rack::Lobster.new\n")
54
+ end
55
+ cfg = Yahns::Config.new(conf.path)
56
+ FileUtils.rm_rf(tmpdir) if tmpdir
57
+ exit!(Yahns::Config === cfg)
50
58
  end
51
- cfg = GTL.synchronize { Yahns::Config.new(conf.path) }
52
- assert_instance_of Yahns::Config, cfg
53
- ensure
54
- FileUtils.rm_rf(tmpdir) if tmpdir
59
+ _, status = Process.waitpid2(pid)
60
+ assert status.success?
55
61
  end
56
62
  end
@@ -0,0 +1,74 @@
1
+ # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
2
+ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
3
+ require_relative 'server_helper'
4
+
5
+ class TestRackHijack < Testcase
6
+ parallelize_me!
7
+ include ServerHelper
8
+ alias setup server_helper_setup
9
+ alias teardown server_helper_teardown
10
+
11
+ class DieIfUsed
12
+ def each
13
+ abort "body.each called after response hijack\n"
14
+ end
15
+
16
+ def close
17
+ abort "body.close called after response hijack\n"
18
+ end
19
+ end
20
+
21
+ HIJACK_APP = lambda { |env|
22
+ case env["PATH_INFO"]
23
+ when "/hijack_req"
24
+ io = env["rack.hijack"].call
25
+ if io.respond_to?(:read_nonblock) &&
26
+ env["rack.hijack_io"].respond_to?(:read_nonblock)
27
+
28
+ # exercise both, since we Rack::Lint may use different objects
29
+ env["rack.hijack_io"].write("HTTP/1.0 200 OK\r\n\r\n")
30
+ io.write("request.hijacked")
31
+ io.close
32
+ return [ 500, {}, DieIfUsed.new ]
33
+ end
34
+ [ 500, {}, [ "hijack BAD\n" ] ]
35
+ when "/hijack_res"
36
+ r = "response.hijacked"
37
+ [ 200,
38
+ {
39
+ "X-Test" => "zzz",
40
+ "Content-Length" => r.bytesize.to_s,
41
+ "rack.hijack" => proc { |x| x.write(r); x.close }
42
+ },
43
+ DieIfUsed.new
44
+ ]
45
+ end
46
+ }
47
+
48
+ def test_hijack
49
+ err = @err
50
+ cfg = Yahns::Config.new
51
+ host, port = @srv.addr[3], @srv.addr[1]
52
+ cfg.instance_eval do
53
+ GTL.synchronize { app(:rack, HIJACK_APP) { listen "#{host}:#{port}" } }
54
+ logger(Logger.new(err.path))
55
+ end
56
+ srv = Yahns::Server.new(cfg)
57
+ pid = fork do
58
+ ENV["YAHNS_FD"] = @srv.fileno.to_s
59
+ srv.start.join
60
+ end
61
+ res = Net::HTTP.start(host, port) { |h| h.get("/hijack_req") }
62
+ assert_equal "request.hijacked", res.body
63
+ assert_equal 200, res.code.to_i
64
+ assert_equal "1.0", res.http_version
65
+
66
+ res = Net::HTTP.start(host, port) { |h| h.get("/hijack_res") }
67
+ assert_equal "response.hijacked", res.body
68
+ assert_equal 200, res.code.to_i
69
+ assert_equal "zzz", res["X-Test"]
70
+ assert_equal "1.1", res.http_version
71
+ ensure
72
+ quit_wait(pid)
73
+ end
74
+ end
@@ -0,0 +1,64 @@
1
+ # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
2
+ # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
3
+ require_relative 'server_helper'
4
+ require 'rack/commonlogger'
5
+
6
+ class TestReopenLogs < Testcase
7
+ parallelize_me!
8
+ include ServerHelper
9
+ alias setup server_helper_setup
10
+ alias teardown server_helper_teardown
11
+
12
+ def test_reopen_logs_noworker; reopen(false); end
13
+ def test_reopen_logs_worker; reopen(true); end
14
+
15
+ def reopen(worker)
16
+ err = @err
17
+ out = tmpfile(%w(log .out))
18
+ opath = out.path
19
+ cfg = Yahns::Config.new
20
+ host, port = @srv.addr[3], @srv.addr[1]
21
+ cfg.instance_eval do
22
+ stderr_path err.path
23
+ stdout_path opath
24
+ GTL.synchronize do
25
+ app = Rack::Builder.new do
26
+ use Rack::CommonLogger, $stdout
27
+ use Rack::ContentLength
28
+ use Rack::ContentType, "text/plain"
29
+ run lambda { |_| [ 200, {}, [ "#$$" ] ] }
30
+ end
31
+ app(:rack, app.to_app) { listen "#{host}:#{port}" }
32
+ end
33
+ worker_processes 1 if worker
34
+ end
35
+ pid = fork do
36
+ ENV["YAHNS_FD"] = @srv.fileno.to_s
37
+ Yahns::Server.new(cfg).start.join
38
+ end
39
+ Net::HTTP.start(host, port) do |http|
40
+ res = http.request(Net::HTTP::Get.new("/aaa"))
41
+ assert_equal 200, res.code.to_i
42
+ orig = res.body
43
+ Timeout.timeout(10) { Thread.pass until File.read(opath) =~ /aaa/ }
44
+ File.unlink(opath)
45
+ Process.kill(:USR1, pid)
46
+ Timeout.timeout(10) { sleep(0.01) until File.exist?(opath) }
47
+
48
+ # we need to repeat the HTTP request since the worker_processes
49
+ # may not have switched to the new file, yet.
50
+ Timeout.timeout(10) do
51
+ begin
52
+ res = http.request(Net::HTTP::Get.new("/bbb"))
53
+ assert_equal 200, res.code.to_i
54
+ assert_equal orig, res.body
55
+ end until File.read(opath) =~ /bbb/
56
+ end
57
+ end
58
+ rescue => e
59
+ Yahns::Log.exception(Logger.new($stderr), "test", e)
60
+ raise
61
+ ensure
62
+ quit_wait(pid)
63
+ end
64
+ end
@@ -51,8 +51,11 @@ class TestServer < Testcase
51
51
  end
52
52
  end
53
53
  Process.kill(:QUIT, pid)
54
- "GET / HTTP/1.1\r\n\r\n".each_byte { |x| Thread.pass; c.write(x.chr) }
55
- buf = Timeout.timeout(10) { c.read }
54
+ "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".each_byte do |x|
55
+ sleep(0.01)
56
+ c.write(x.chr)
57
+ end
58
+ buf = Timeout.timeout(30) { c.read }
56
59
  assert_match(/Connection: close/, buf)
57
60
  _, status = Timeout.timeout(10) { Process.waitpid2(pid) }
58
61
  assert status.success?, status.inspect
@@ -287,6 +290,7 @@ class TestServer < Testcase
287
290
 
288
291
  # Linux blocking accept() has fair behavior between multiple tasks
289
292
  def test_mp_balance
293
+ skip("this fails occasionally on Linux, still...")
290
294
  skip("linux-only test") unless RUBY_PLATFORM =~ /linux/
291
295
  pid, host, port = new_mp_server(2)
292
296
  seen = {}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yahns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - yahns hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-18 00:00:00.000000000 Z
11
+ date: 2013-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kgio
@@ -96,6 +96,7 @@ files:
96
96
  - examples/yahns_rack_basic.conf.rb
97
97
  - lib/yahns.rb
98
98
  - lib/yahns/acceptor.rb
99
+ - lib/yahns/cap_input.rb
99
100
  - lib/yahns/client_expire.rb
100
101
  - lib/yahns/client_expire_portable.rb
101
102
  - lib/yahns/config.rb
@@ -105,6 +106,9 @@ files:
105
106
  - lib/yahns/http_context.rb
106
107
  - lib/yahns/http_response.rb
107
108
  - lib/yahns/log.rb
109
+ - lib/yahns/max_body.rb
110
+ - lib/yahns/max_body/rewindable_wrapper.rb
111
+ - lib/yahns/max_body/wrapper.rb
108
112
  - lib/yahns/queue.rb
109
113
  - lib/yahns/queue_egg.rb
110
114
  - lib/yahns/queue_epoll.rb
@@ -128,11 +132,13 @@ files:
128
132
  - test/server_helper.rb
129
133
  - test/test_bin.rb
130
134
  - test/test_client_expire.rb
135
+ - test/test_client_max_body_size.rb
131
136
  - test/test_config.rb
132
137
  - test/test_fdmap.rb
133
138
  - test/test_output_buffering.rb
134
- - test/test_queue.rb
135
139
  - test/test_rack.rb
140
+ - test/test_rack_hijack.rb
141
+ - test/test_reopen_logs.rb
136
142
  - test/test_serve_static.rb
137
143
  - test/test_server.rb
138
144
  - test/test_stream_file.rb
@@ -158,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
164
  version: '0'
159
165
  requirements: []
160
166
  rubyforge_project:
161
- rubygems_version: 2.1.9
167
+ rubygems_version: 2.1.3
162
168
  signing_key:
163
169
  specification_version: 4
164
170
  summary: sleepy, multi-threaded, non-blocking application server
@@ -1,59 +0,0 @@
1
- # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
2
- # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
3
- require_relative 'helper'
4
- require 'timeout'
5
- require 'stringio'
6
-
7
- class TestQueue < Testcase
8
- parallelize_me!
9
-
10
- def setup
11
- @q = Yahns::Queue.new
12
- @err = StringIO.new
13
- @logger = Logger.new(@err)
14
- @q.fdmap = @fdmap = Yahns::Fdmap.new(@logger, 0.5)
15
- assert @q.close_on_exec?
16
- end
17
-
18
- def test_queue
19
- r, w = IO.pipe
20
- assert_equal 0, @fdmap.size
21
- @q.queue_add(r, Yahns::Queue::QEV_RD)
22
- assert_equal 1, @fdmap.size
23
- def r.yahns_step
24
- begin
25
- case read_nonblock(11)
26
- when "delete"
27
- return :delete
28
- end
29
- rescue Errno::EAGAIN
30
- return :wait_readable
31
- rescue EOFError
32
- return nil
33
- end while true
34
- end
35
- w.write('.')
36
- Timeout.timeout(10) do
37
- Thread.pass until r.nread > 0
38
- @q.spawn_worker_threads(@logger, 1, 1)
39
- Thread.pass until r.nread == 0
40
-
41
- w.write("delete")
42
- Thread.pass until r.nread == 0
43
- Thread.pass until @fdmap.size == 0
44
-
45
- # should not raise
46
- @q.queue_add(r, Yahns::Queue::QEV_RD)
47
- assert_equal 1, @fdmap.size
48
- w.close
49
- Thread.pass until @fdmap.size == 0
50
- end
51
- assert r.closed?
52
- ensure
53
- [ r, w ].each { |io| io.close unless io.closed? }
54
- end
55
-
56
- def teardown
57
- @q.close
58
- end
59
- end