thin 0.6.2-x86-mswin32-60 → 0.6.3-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of thin might be problematic. Click here for more details.

Files changed (48) hide show
  1. data/CHANGELOG +34 -1
  2. data/bin/thin +2 -164
  3. data/example/config.ru +4 -1
  4. data/example/ramaze.ru +12 -0
  5. data/example/thin.god +70 -66
  6. data/lib/rack/adapter/rails.rb +0 -3
  7. data/lib/rack/handler/thin.rb +6 -1
  8. data/lib/thin.rb +13 -4
  9. data/lib/thin/command.rb +9 -5
  10. data/lib/thin/connection.rb +5 -14
  11. data/lib/thin/connectors/connector.rb +61 -0
  12. data/lib/thin/connectors/tcp_server.rb +29 -0
  13. data/lib/thin/connectors/unix_server.rb +48 -0
  14. data/lib/thin/controllers/cluster.rb +115 -0
  15. data/lib/thin/controllers/controller.rb +85 -0
  16. data/lib/thin/controllers/service.rb +73 -0
  17. data/lib/thin/controllers/service.sh.erb +39 -0
  18. data/lib/thin/daemonizing.rb +9 -4
  19. data/lib/thin/headers.rb +2 -2
  20. data/lib/thin/runner.rb +166 -0
  21. data/lib/thin/server.rb +109 -89
  22. data/lib/thin/stats.html.erb +216 -0
  23. data/lib/thin/stats.rb +1 -249
  24. data/lib/thin/version.rb +10 -3
  25. data/lib/thin_parser.so +0 -0
  26. data/spec/command_spec.rb +0 -1
  27. data/spec/configs/cluster.yml +9 -0
  28. data/spec/configs/single.yml +9 -0
  29. data/spec/{cluster_spec.rb → controllers/cluster_spec.rb} +22 -10
  30. data/spec/controllers/controller_spec.rb +85 -0
  31. data/spec/controllers/service_spec.rb +51 -0
  32. data/spec/daemonizing_spec.rb +73 -9
  33. data/spec/request/mongrel_spec.rb +39 -0
  34. data/spec/{request_spec.rb → request/parser_spec.rb} +11 -143
  35. data/spec/request/perf_spec.rb +50 -0
  36. data/spec/request/processing_spec.rb +46 -0
  37. data/spec/runner_spec.rb +135 -0
  38. data/spec/server/builder_spec.rb +38 -0
  39. data/spec/server/stopping_spec.rb +45 -0
  40. data/spec/server/tcp_spec.rb +54 -0
  41. data/spec/server/unix_socket_spec.rb +30 -0
  42. data/spec/spec_helper.rb +49 -16
  43. data/tasks/announce.rake +7 -3
  44. data/tasks/email.erb +8 -18
  45. data/tasks/stats.rake +21 -8
  46. metadata +33 -7
  47. data/lib/thin/cluster.rb +0 -123
  48. data/spec/server_spec.rb +0 -200
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Server, 'app builder' do
4
+ it "should build app from constructor" do
5
+ server = Server.new('0.0.0.0', 3000, :works)
6
+
7
+ server.app.should == :works
8
+ end
9
+
10
+ it "should build app from builder block" do
11
+ server = Server.new '0.0.0.0', 3000 do
12
+ run(proc { |env| :works })
13
+ end
14
+
15
+ server.app.call({}).should == :works
16
+ end
17
+
18
+ it "should use middlewares in builder block" do
19
+ server = Server.new '0.0.0.0', 3000 do
20
+ use Rack::ShowExceptions
21
+ run(proc { |env| :works })
22
+ end
23
+
24
+ server.app.class.should == Rack::ShowExceptions
25
+ server.app.call({}).should == :works
26
+ end
27
+
28
+ it "should work with Rack url mapper" do
29
+ server = Server.new '0.0.0.0', 3000 do
30
+ map '/test' do
31
+ run(proc { |env| :works })
32
+ end
33
+ end
34
+
35
+ server.app.call({})[0].should == 404
36
+ server.app.call({'PATH_INFO' => '/test'}).should == :works
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Server, "stopping" do
4
+ before do
5
+ start_server do |env|
6
+ [200, { 'Content-Type' => 'text/html', 'Content-Length' => '2' }, ['ok']]
7
+ end
8
+ end
9
+
10
+ it "should wait for current requests before soft stopping" do
11
+ socket = TCPSocket.new('0.0.0.0', 3333)
12
+ socket.write("GET / HTTP/1.1")
13
+ @server.stop # Stop the server in the middle of a request
14
+ socket.write("\r\n\r\n")
15
+
16
+ out = socket.read
17
+ socket.close
18
+
19
+ out.should_not be_empty
20
+ end
21
+
22
+ it "should not accept new requests when soft stopping" do
23
+ socket = TCPSocket.new('0.0.0.0', 3333)
24
+ socket.write("GET / HTTP/1.1")
25
+ @server.stop # Stop the server in the middle of a request
26
+
27
+ EventMachine.next_tick do
28
+ proc { get('/') }.should raise_error(Errno::ECONNRESET)
29
+ end
30
+
31
+ socket.close
32
+ end
33
+
34
+ it "should drop current requests when hard stopping" do
35
+ socket = TCPSocket.new('0.0.0.0', 3333)
36
+ socket.write("GET / HTTP/1.1")
37
+ @server.stop! # Force stop the server in the middle of a request
38
+
39
+ EventMachine.next_tick { socket.should be_closed }
40
+ end
41
+
42
+ after do
43
+ stop_server
44
+ end
45
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Server, 'on TCP socket' do
4
+ before do
5
+ start_server do |env|
6
+ body = env.inspect + env['rack.input'].read
7
+ [200, { 'Content-Type' => 'text/html', 'Content-Length' => body.size.to_s }, body]
8
+ end
9
+ end
10
+
11
+ it 'should GET from Net::HTTP' do
12
+ get('/?cthis').should include('cthis')
13
+ end
14
+
15
+ it 'should GET from TCPSocket' do
16
+ send_data("GET /?this HTTP/1.1\r\n\r\n").
17
+ should include("HTTP/1.1 200 OK",
18
+ "Content-Type: text/html", "Content-Length: ",
19
+ "Connection: close", "this")
20
+ end
21
+
22
+ it 'should return empty string on incomplete headers' do
23
+ send_data("GET /?this HTTP/1.1\r\nHost:").should be_empty
24
+ end
25
+
26
+ it 'should return empty string on incorrect Content-Length' do
27
+ send_data("POST / HTTP/1.1\r\nContent-Length: 300\r\n\r\naye").should be_empty
28
+ end
29
+
30
+ it 'should POST from Net::HTTP' do
31
+ post('/', :arg => 'pirate').should include('arg=pirate')
32
+ end
33
+
34
+ it 'should handle big POST' do
35
+ big = 'X' * (20 * 1024)
36
+ post('/', :big => big).should include(big)
37
+ end
38
+
39
+ it "should handle GET in less then #{get_request_time = 0.004} RubySecond" do
40
+ proc { get('/') }.should be_faster_then(get_request_time)
41
+ end
42
+
43
+ it "should handle POST in less then #{post_request_time = 0.007} RubySecond" do
44
+ proc { post('/', :file => 'X' * 1000) }.should be_faster_then(post_request_time)
45
+ end
46
+
47
+ it "should retreive remote address" do
48
+ get('/').should include('"REMOTE_ADDR"=>"127.0.0.1"')
49
+ end
50
+
51
+ after do
52
+ stop_server
53
+ end
54
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Server, "on UNIX domain socket" do
4
+ before do
5
+ start_server('/tmp/thin_test.sock') do |env|
6
+ [200, { 'Content-Type' => 'text/html', 'Content-Length' => env.inspect.size.to_s }, [env.inspect]]
7
+ end
8
+ end
9
+
10
+ it "should accept GET request" do
11
+ get("/?this").should include('this')
12
+ end
13
+
14
+ it "should retreive remote address" do
15
+ get('/').should include('"REMOTE_ADDR"=>""') # Is that right?
16
+ end
17
+
18
+ it "should handle GET in less then #{get_request_time = 0.002} RubySecond" do
19
+ proc { get('/') }.should be_faster_then(get_request_time)
20
+ end
21
+
22
+ it "should remove socket file after server stops" do
23
+ @server.stop!
24
+ File.exist?('/tmp/thin_test.sock').should be_false
25
+ end
26
+
27
+ after do
28
+ stop_server
29
+ end
30
+ end
@@ -5,26 +5,13 @@ require 'benchmark'
5
5
  require 'timeout'
6
6
  require 'fileutils'
7
7
  require 'benchmark_unit'
8
+ require 'net/http'
9
+ require 'socket'
8
10
 
9
11
  include Thin
10
12
 
11
13
  FileUtils.mkdir_p File.dirname(__FILE__) + '/../log'
12
-
13
- class TestRequest < Thin::Request
14
- def initialize(path, verb='GET', params={})
15
- @path = path
16
- @verb = verb.to_s.upcase
17
- @params = {
18
- 'HTTP_HOST' => 'localhost:3000',
19
- 'REQUEST_URI' => @path,
20
- 'REQUEST_PATH' => @path,
21
- 'REQUEST_METHOD' => @verb,
22
- 'SCRIPT_NAME' => @path
23
- }.merge(params)
24
-
25
- @body = "#{@verb} #{path} HTTP/1.1"
26
- end
27
- end
14
+ Command.script = File.dirname(__FILE__) + '/../bin/thin'
28
15
 
29
16
  module Matchers
30
17
  class BeFasterThen
@@ -139,6 +126,52 @@ module Helpers
139
126
  ensure
140
127
  stream.reopen(old_stream)
141
128
  end
129
+
130
+ # Create and parse a request
131
+ def R(raw, convert_line_feed=false)
132
+ raw.gsub!("\n", "\r\n") if convert_line_feed
133
+ request = Thin::Request.new
134
+ request.parse(raw)
135
+ request
136
+ end
137
+
138
+ def start_server(*args, &app)
139
+ @server = Thin::Server.new(args[0] || '0.0.0.0', args[1] || 3333, app)
140
+ @server.timeout = 3
141
+ @server.silent = true
142
+
143
+ @thread = Thread.new { @server.start }
144
+ sleep 0.1 until @thread.status == 'sleep'
145
+ end
146
+
147
+ def stop_server
148
+ @server.stop!
149
+ @thread.kill
150
+ end
151
+
152
+ def send_data(data)
153
+ if @server.connector.class == Connectors::UnixServer
154
+ socket = UNIXSocket.new(@server.socket)
155
+ else
156
+ socket = TCPSocket.new(@server.host, @server.port)
157
+ end
158
+ socket.write data
159
+ out = socket.read
160
+ socket.close
161
+ out
162
+ end
163
+
164
+ def get(url)
165
+ if @server.connector.class == Connectors::UnixServer
166
+ send_data("GET #{url} HTTP/1.1\r\n\r\n")
167
+ else
168
+ Net::HTTP.get(URI.parse("http://#{@server.host}:#{@server.port}" + url))
169
+ end
170
+ end
171
+
172
+ def post(url, params={})
173
+ Net::HTTP.post_form(URI.parse("http://#{@server.host}:#{@server.port}" + url), params).body
174
+ end
142
175
  end
143
176
 
144
177
  Spec::Runner.configure do |config|
@@ -1,7 +1,7 @@
1
1
  require 'erb'
2
2
 
3
3
  MSG_TEMPLATE = File.dirname(__FILE__) + '/email.erb'
4
- SEND_TO = %w(thin-ruby@googlegroups.com eventmachine-talk@rubyforge.org Rubymtl@lists.artengine.ca ruby-talk@ruby-lang.org)
4
+ SEND_TO = %w(thin-ruby@googlegroups.com eventmachine-talk@rubyforge.org Rubymtl@lists.artengine.ca ruby-talk@ruby-lang.org montreal-on-rails@googlegroups.com)
5
5
 
6
6
  desc 'Generate a template for the new version annoucement'
7
7
  task :ann do
@@ -9,10 +9,14 @@ task :ann do
9
9
 
10
10
  body = <<END_OF_MESSAGE
11
11
  To: #{SEND_TO.join(', ')}
12
- Subject: [ANN] Thin #{Thin::VERSION::STRING} #{Thin::VERSION::CODENAME} released
12
+ Subject: [ANN] Thin #{Thin::VERSION::STRING} #{Thin::VERSION::CODENAME} release
13
13
 
14
14
  #{msg}
15
15
  END_OF_MESSAGE
16
16
 
17
- puts body
17
+ `echo "#{body}" | mate`
18
+ end
19
+
20
+ def changelog
21
+ File.read('CHANGELOG').split("==")[1].split("\n")[1..-1].join("\n")
18
22
  end
@@ -6,37 +6,27 @@ http://code.macournoyer.com/thin/
6
6
 
7
7
  == What's new?
8
8
 
9
- Bug fix in daemon mode and speed boost for all!
10
-
11
- * Don't read the full body, use direct streaming when sending response.
12
- See: Response#each
13
- As a result, the Content-Length can not be calculated anymore.
14
- You have to do set this in your adapter. All frameworks do it anyway.
15
- It improve memory usage and boost speed for low concurrency.
16
- Thanks to Kent Sibilev and Ezra for their help on that one.
17
- * Add 'Server' response header
18
- * Fix --user and --group option not changing daemon process privileges
9
+ <%= changelog %>
19
10
 
20
11
  == Get it!
21
12
 
22
13
  sudo gem install thin
23
14
 
24
- Might take some time for the gem mirrors to be updated, try adding
25
- --source http://code.macournoyer.com to the command if it doesn't work
15
+ Or using my mirror:
26
16
 
27
- If you installed a previous alpha version (if you have <%= Thin::VERSION::STRING %> already installed)
28
- uninstall it before: sudo gem uninstall thin
17
+ sudo gem install thin --source http://code.macournoyer.com
29
18
 
30
19
  WARNING:
31
- Thin is still alpha software, if you use it on your server you understand the
32
- risks that are involved.
20
+ Thin is still alpha software, if you use it on your server you understand the
21
+ risks that are involved.
33
22
 
34
23
  == Contribute
35
24
 
36
25
  If you're using Thin, let me know and I'll put your site on http://code.macournoyer.com/thin/users/
37
26
 
38
- Thin is driven by an active community of passionate coders and benchmarkers. Please join us, contribute
39
- or share some ideas in Thin Google Group: http://groups.google.com/group/thin-ruby/topics
27
+ Thin is driven by an active community of passionate coders and benchmarkers.
28
+ Please join us, contribute or share some ideas in Thin Google Group:
29
+ http://groups.google.com/group/thin-ruby/topics
40
30
 
41
31
  Also on IRC: #thin on freenode
42
32
 
@@ -3,13 +3,26 @@ task :stats do
3
3
  line_count = proc do |path|
4
4
  Dir[path].collect { |f| File.open(f).readlines.reject { |l| l =~ /(^\s*(\#|\/\*))|^\s*$/ }.size }.inject(0){ |sum,n| sum += n }
5
5
  end
6
- lib = line_count['lib/**/*.rb']
7
- ext = line_count['ext/**/*.{c,h}']
8
- spec = line_count['spec/**/*.rb']
9
- ratio = '%1.2f' % (spec.to_f / lib.to_f)
6
+ comment_count = proc do |path|
7
+ Dir[path].collect { |f| File.open(f).readlines.select { |l| l =~ /^\s*\#/ }.size }.inject(0) { |sum,n| sum += n }
8
+ end
9
+ lib = line_count['lib/**/*.rb']
10
+ comment = comment_count['lib/**/*.rb']
11
+ ext = line_count['ext/**/*.{c,h}']
12
+ spec = line_count['spec/**/*.rb']
13
+
14
+ comment_ratio = '%1.2f' % (comment.to_f / lib.to_f)
15
+ spec_ratio = '%1.2f' % (spec.to_f / lib.to_f)
10
16
 
11
- puts "#{lib.to_s.rjust(6)} LOC of lib"
12
- puts "#{ext.to_s.rjust(6)} LOC of ext"
13
- puts "#{spec.to_s.rjust(6)} LOC of spec"
14
- puts "#{ratio.to_s.rjust(6)} ratio lib/spec"
17
+ puts '/======================\\'
18
+ puts '| Part LOC |'
19
+ puts '|======================|'
20
+ puts "| lib #{lib.to_s.ljust(5)}|"
21
+ puts "| lib comments #{comment.to_s.ljust(5)}|"
22
+ puts "| ext #{ext.to_s.ljust(5)}|"
23
+ puts "| spec #{spec.to_s.ljust(5)}|"
24
+ puts '| ratios: |'
25
+ puts "| lib/comment #{comment_ratio.to_s.ljust(5)}|"
26
+ puts "| lib/spec #{spec_ratio.to_s.ljust(5)}|"
27
+ puts '\======================/'
15
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: x86-mswin32-60
6
6
  authors:
7
7
  - Marc-Andre Cournoyer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-30 00:00:00 -07:00
12
+ date: 2008-02-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,6 +52,7 @@ files:
52
52
  - example/config.ru
53
53
  - example/monit_sockets
54
54
  - example/monit_unixsock
55
+ - example/ramaze.ru
55
56
  - example/thin.god
56
57
  - lib/rack
57
58
  - lib/rack/adapter
@@ -59,21 +60,38 @@ files:
59
60
  - lib/rack/handler
60
61
  - lib/rack/handler/thin.rb
61
62
  - lib/thin
62
- - lib/thin/cluster.rb
63
63
  - lib/thin/command.rb
64
64
  - lib/thin/connection.rb
65
+ - lib/thin/connectors
66
+ - lib/thin/connectors/connector.rb
67
+ - lib/thin/connectors/tcp_server.rb
68
+ - lib/thin/connectors/unix_server.rb
69
+ - lib/thin/controllers
70
+ - lib/thin/controllers/cluster.rb
71
+ - lib/thin/controllers/controller.rb
72
+ - lib/thin/controllers/service.rb
73
+ - lib/thin/controllers/service.sh.erb
65
74
  - lib/thin/daemonizing.rb
66
75
  - lib/thin/headers.rb
67
76
  - lib/thin/logging.rb
68
77
  - lib/thin/request.rb
69
78
  - lib/thin/response.rb
79
+ - lib/thin/runner.rb
70
80
  - lib/thin/server.rb
81
+ - lib/thin/stats.html.erb
71
82
  - lib/thin/stats.rb
72
83
  - lib/thin/statuses.rb
73
84
  - lib/thin/version.rb
74
85
  - lib/thin.rb
75
- - spec/cluster_spec.rb
86
+ - lib/thin_parser.so
76
87
  - spec/command_spec.rb
88
+ - spec/configs
89
+ - spec/configs/cluster.yml
90
+ - spec/configs/single.yml
91
+ - spec/controllers
92
+ - spec/controllers/cluster_spec.rb
93
+ - spec/controllers/controller_spec.rb
94
+ - spec/controllers/service_spec.rb
77
95
  - spec/daemonizing_spec.rb
78
96
  - spec/headers_spec.rb
79
97
  - spec/rack_rails_spec.rb
@@ -132,9 +150,18 @@ files:
132
150
  - spec/rails_app/script/process/spawner
133
151
  - spec/rails_app/script/runner
134
152
  - spec/rails_app/script/server
135
- - spec/request_spec.rb
153
+ - spec/request
154
+ - spec/request/mongrel_spec.rb
155
+ - spec/request/parser_spec.rb
156
+ - spec/request/perf_spec.rb
157
+ - spec/request/processing_spec.rb
136
158
  - spec/response_spec.rb
137
- - spec/server_spec.rb
159
+ - spec/runner_spec.rb
160
+ - spec/server
161
+ - spec/server/builder_spec.rb
162
+ - spec/server/stopping_spec.rb
163
+ - spec/server/tcp_spec.rb
164
+ - spec/server/unix_socket_spec.rb
138
165
  - spec/spec_helper.rb
139
166
  - tasks/announce.rake
140
167
  - tasks/deploy.rake
@@ -152,7 +179,6 @@ files:
152
179
  - ext/thin_parser/extconf.rb
153
180
  - ext/thin_parser/common.rl
154
181
  - ext/thin_parser/parser.rl
155
- - lib/thin_parser.so
156
182
  has_rdoc: false
157
183
  homepage: http://code.macournoyer.com/thin/
158
184
  post_install_message: