unicorn 0.7.0 → 0.7.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.
data/.document CHANGED
@@ -1,4 +1,5 @@
1
1
  README
2
+ TUNING
2
3
  PHILOSOPHY
3
4
  DESIGN
4
5
  CONTRIBUTORS
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.7.1 - minor fixes, cleanups and documentation improvements
1
2
  v0.7.0 - rack.version is 1.0
2
3
  v0.6.0 - cleanups + optimizations, signals to {in,de}crement processes
3
4
  v0.5.4 - fix data corruption with some small uploads (not curl)
@@ -53,8 +53,10 @@ $(test_prefix)/.stamp: $(inst_deps)
53
53
  $(MAKE) -C $(test_prefix) http11 shebang
54
54
  > $@
55
55
 
56
+ bins := $(wildcard bin/*)
57
+
56
58
  # this is only intended to be run within $(test_prefix)
57
- shebang: bin/unicorn bin/unicorn_rails
59
+ shebang: $(bins)
58
60
  $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
59
61
 
60
62
  t_log := $(T_log) $(T_n_log)
@@ -97,7 +99,7 @@ $(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
97
99
  $(T): $(test_prefix)/.stamp
98
100
  $(run_test)
99
101
 
100
- install: bin/unicorn bin/unicorn_rails
102
+ install: $(bins)
101
103
  $(prep_setup_rb)
102
104
  $(RM) -r .install-tmp
103
105
  mkdir .install-tmp
data/Manifest CHANGED
@@ -11,8 +11,10 @@ README
11
11
  Rakefile
12
12
  SIGNALS
13
13
  TODO
14
+ TUNING
14
15
  bin/unicorn
15
16
  bin/unicorn_rails
17
+ examples/init.sh
16
18
  ext/unicorn/http11/ext_help.h
17
19
  ext/unicorn/http11/extconf.rb
18
20
  ext/unicorn/http11/http11.c
@@ -127,3 +129,4 @@ test/unit/test_server.rb
127
129
  test/unit/test_signals.rb
128
130
  test/unit/test_socket_helper.rb
129
131
  test/unit/test_upload.rb
132
+ test/unit/test_util.rb
data/README CHANGED
@@ -103,7 +103,7 @@ In RAILS_ROOT, run:
103
103
  unicorn_rails
104
104
 
105
105
  Unicorn will bind to all interfaces TCP port 8080 by default.
106
- You may use the '-l/--listen' switch to bind to a different
106
+ You may use the +-l/--listen+ switch to bind to a different
107
107
  address:port or a UNIX socket.
108
108
 
109
109
  === Configuration File(s)
@@ -111,7 +111,7 @@ address:port or a UNIX socket.
111
111
  Unicorn will look for the config.ru file used by rackup in APP_ROOT.
112
112
 
113
113
  For deployments, it can use a config file for Unicorn-specific options
114
- specified by the --config-file/-c command-line switch. See
114
+ specified by the +--config-file/-c+ command-line switch. See
115
115
  Unicorn::Configurator for the syntax of the Unicorn-specific options.
116
116
  The default settings are designed for maximum out-of-the-box
117
117
  compatibility with existing applications.
data/TODO CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  * integration tests with nginx including bad client handling
4
4
 
5
- * tests for timeout
6
-
7
5
  * manpages (why do so few Ruby executables come with proper manpages?)
8
6
 
9
7
  == 1.1.0
data/TUNING ADDED
@@ -0,0 +1,63 @@
1
+ = Tuning Unicorn
2
+
3
+ Unicorn performance is generally as good as a (mostly) Ruby web server
4
+ can provide. Most often the performance bottleneck is in the web
5
+ application running on Unicorn rather than Unicorn itself.
6
+
7
+ == Unicorn Configuration
8
+
9
+ See Unicorn::Configurator for details on the config file format.
10
+
11
+ * Setting a very low value for the :backlog parameter in "listen"
12
+ directives can allow failover to happen more quickly if your
13
+ cluster is configured for it.
14
+
15
+ * :rcvbuf and :sndbuf parameters generally do not need to be set for TCP
16
+ listeners under Linux 2.6 because auto-tuning is enabled. UNIX domain
17
+ sockets do not have auto-tuning buffer sizes; so increasing those will
18
+ allow syscalls and task switches to be saved for larger requests
19
+ and responses.
20
+
21
+ * Setting "preload_app true" can allow copy-on-write-friendly GC to
22
+ be used to save memory. It will probably not work out of the box with
23
+ applications that open sockets or perform random I/O on files.
24
+ Databases like TokyoCabinet use concurrency-safe pread()/pwrite()
25
+ functions for safe sharing of database file descriptors across
26
+ processes.
27
+
28
+ * On POSIX-compliant filesystems, it is safe for multiple threads or
29
+ processes to append to one log file as long as all the processes are
30
+ have them unbuffered (File#sync = true) or they are
31
+ record(line)-buffered in userspace.
32
+
33
+ * worker_processes should be scaled to the number of processes your
34
+ backend system(s) can support. DO NOT scale it to the number of
35
+ external network clients your application expects to be serving.
36
+ Unicorn is NOT for serving slow clients, that is the job of nginx.
37
+
38
+ == Kernel Parameters (Linux sysctl)
39
+
40
+ WARNING: Do not change system parameters unless you know what you're doing!
41
+
42
+ * net.core.rmem_max and net.core.wmem_max can increase the allowed
43
+ size of :rcvbuf and :sndbuf respectively. This is mostly only useful
44
+ for UNIX domain sockets which do not have auto-tuning buffer sizes.
45
+
46
+ * For load testing/benchmarking with UNIX domain sockets, you should
47
+ consider increasing net.core.somaxconn or else nginx will start
48
+ failing to connect under heavy load.
49
+
50
+ * If you're running out of local ports, consider lowering
51
+ net.ipv4.tcp_fin_timeout to 20-30 (default: 60 seconds). Also
52
+ consider widening the usable port range by changing
53
+ net.ipv4.ip_local_port_range.
54
+
55
+ * Setting net.ipv4.tcp_timestamps=1 will also allow setting
56
+ net.ipv4.tcp_tw_reuse=1 and net.ipv4.tcp_tw_recycle=1, which along
57
+ with the above settings can slow down port exhaustion. Not all
58
+ networks are compatible with these settings, check with your friendly
59
+ network administrator before changing these.
60
+
61
+ * Increasing the MTU size can reduce framing overhead for larger
62
+ transfers. One often-overlooked detail is that the loopback
63
+ device (usually "lo") can have its MTU increased, too.
@@ -0,0 +1,54 @@
1
+ #!/bin/sh
2
+ set -u
3
+ set -e
4
+ # Example init script, this can be used with nginx, too,
5
+ # since nginx and unicorn accept the same signals
6
+
7
+ # Feel free to change any of the following variables for your app:
8
+ APP_ROOT=/home/x/my_app/current
9
+ PID=$APP_ROOT/tmp/pids/unicorn.pid
10
+ CMD="/usr/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb"
11
+ INIT_CONF=$APP_ROOT/config/init.conf
12
+
13
+ test -f "$INIT_CONF" && . $INIT_CONF
14
+
15
+ old_pid="$PID.oldbin"
16
+
17
+ cd $APP_ROOT || exit 1
18
+
19
+ sig () {
20
+ test -s "$PID" && kill -$1 `cat $PID`
21
+ }
22
+
23
+ oldsig () {
24
+ test -s $old_pid && kill -$1 `cat $old_pid`
25
+ }
26
+
27
+ case $1 in
28
+ start)
29
+ sig 0 && echo >&2 "Already running" && exit 0
30
+ $CMD
31
+ ;;
32
+ stop)
33
+ sig QUIT && exit 0
34
+ echo >&2 "Not running"
35
+ ;;
36
+ force-stop)
37
+ sig TERM && exit 0
38
+ echo >&2 "Not running"
39
+ ;;
40
+ restart|reload)
41
+ sig HUP && echo reloaded OK && exit 0
42
+ echo >&2 "Couldn't reload, starting '$CMD' instead"
43
+ $CMD
44
+ ;;
45
+ upgrade)
46
+ sig USR2 && sleep 2 && sig 0 && oldsig QUIT && exit 0
47
+ echo >&2 "Couldn't upgrade, starting '$CMD' instead"
48
+ $CMD
49
+ ;;
50
+ *)
51
+ echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop>"
52
+ exit 1
53
+ ;;
54
+ esac
@@ -64,6 +64,7 @@ module Unicorn
64
64
  # incoming requests on the socket.
65
65
  def initialize(app, options = {})
66
66
  @app = app
67
+ @pid = nil
67
68
  @reexec_pid = 0
68
69
  @init_listeners = options[:listeners] ? options[:listeners].dup : []
69
70
  @config = Configurator.new(options.merge(:use_defaults => true))
@@ -375,9 +376,8 @@ module Unicorn
375
376
  # is stale for >@timeout seconds, then we'll kill the corresponding
376
377
  # worker.
377
378
  def murder_lazy_workers
378
- now = Time.now
379
379
  WORKERS.each_pair do |pid, worker|
380
- (now - worker.tempfile.ctime) <= @timeout and next
380
+ Time.now - worker.tempfile.ctime <= @timeout and next
381
381
  logger.error "worker=#{worker.nr} PID:#{pid} is too old, killing"
382
382
  kill_worker(:KILL, pid) # take no prisoners for @timeout violations
383
383
  worker.tempfile.close rescue nil
@@ -444,7 +444,7 @@ module Unicorn
444
444
  # traps for USR1, USR2, and HUP may be set in the @after_fork Proc
445
445
  # by the user.
446
446
  def init_worker_process(worker)
447
- QUEUE_SIGS.each { |sig| trap(sig, 'DEFAULT') }
447
+ QUEUE_SIGS.each { |sig| trap(sig, 'IGNORE') }
448
448
  trap(:CHLD, 'DEFAULT')
449
449
  SIG_QUEUE.clear
450
450
  proc_name "worker[#{worker.nr}]"
@@ -69,9 +69,9 @@ module Unicorn::App
69
69
  ENV['GATEWAY_INTERFACE'] = 'CGI/1.1'
70
70
  env.keys.grep(/^HTTP_/) { |key| ENV[key] = env[key] }
71
71
 
72
- IO.new(0).reopen(inp)
73
- IO.new(1).reopen(out)
74
- IO.new(2).reopen(err)
72
+ a = IO.new(0).reopen(inp)
73
+ b = IO.new(1).reopen(out)
74
+ c = IO.new(2).reopen(err)
75
75
  exec(*@args)
76
76
  end
77
77
 
@@ -19,8 +19,8 @@ class Unicorn::App::OldRails
19
19
  cgi.body)
20
20
  rescue Object => e
21
21
  err = env['rack.errors']
22
- out.write("#{e} #{e.message}\n")
23
- e.backtrace.each { |line| out.write("#{line}\n") }
22
+ err.write("#{e} #{e.message}\n")
23
+ e.backtrace.each { |line| err.write("#{line}\n") }
24
24
  end
25
25
  cgi.out # finalize the response
26
26
  cgi.rack_response
@@ -143,12 +143,14 @@ module Unicorn
143
143
  # handling the request/app.call/response cycle taking longer than
144
144
  # this time period will be forcibly killed (via SIGKILL). This
145
145
  # timeout is enforced by the master process itself and not subject
146
- # to the scheduling limitations by the worker process.
146
+ # to the scheduling limitations by the worker process. Due the
147
+ # low-complexity, low-overhead implementation, timeouts of less
148
+ # than 3.0 seconds can be considered inaccurate and unsafe.
147
149
  def timeout(seconds)
148
150
  Numeric === seconds or raise ArgumentError,
149
151
  "not numeric: timeout=#{seconds.inspect}"
150
- seconds > 0 or raise ArgumentError,
151
- "not positive: timeout=#{seconds.inspect}"
152
+ seconds >= 3 or raise ArgumentError,
153
+ "too low: timeout=#{seconds.inspect}"
152
154
  @set[:timeout] = seconds
153
155
  end
154
156
 
@@ -179,32 +181,32 @@ module Unicorn
179
181
  #
180
182
  # +backlog+: this is the backlog of the listen() syscall.
181
183
  #
182
- # Some operating systems allow negative values here to specify the
183
- # maximum allowable value. In most cases, this number is only
184
- # recommendation and there are other OS-specific tunables and
185
- # variables that can affect this number. See the listen(2)
186
- # syscall documentation of your OS for the exact semantics of
187
- # this.
184
+ # Some operating systems allow negative values here to specify the
185
+ # maximum allowable value. In most cases, this number is only
186
+ # recommendation and there are other OS-specific tunables and
187
+ # variables that can affect this number. See the listen(2)
188
+ # syscall documentation of your OS for the exact semantics of
189
+ # this.
188
190
  #
189
- # If you are running unicorn on multiple machines, lowering this number
190
- # can help your load balancer detect when a machine is overloaded
191
- # and give requests to a different machine.
191
+ # If you are running unicorn on multiple machines, lowering this number
192
+ # can help your load balancer detect when a machine is overloaded
193
+ # and give requests to a different machine.
192
194
  #
193
- # Default: 1024
195
+ # Default: 1024
194
196
  #
195
197
  # +rcvbuf+, +sndbuf+: maximum send and receive buffer sizes of sockets
196
198
  #
197
- # These correspond to the SO_RCVBUF and SO_SNDBUF settings which
198
- # can be set via the setsockopt(2) syscall. Some kernels
199
- # (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
200
- # there is no need (and it is sometimes detrimental) to specify them.
199
+ # These correspond to the SO_RCVBUF and SO_SNDBUF settings which
200
+ # can be set via the setsockopt(2) syscall. Some kernels
201
+ # (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
202
+ # there is no need (and it is sometimes detrimental) to specify them.
201
203
  #
202
- # See the socket API documentation of your operating system
203
- # to determine the exact semantics of these settings and
204
- # other operating system-specific knobs where they can be
205
- # specified.
204
+ # See the socket API documentation of your operating system
205
+ # to determine the exact semantics of these settings and
206
+ # other operating system-specific knobs where they can be
207
+ # specified.
206
208
  #
207
- # Defaults: operating system defaults
209
+ # Defaults: operating system defaults
208
210
  def listen(address, opt = { :backlog => 1024 })
209
211
  address = expand_addr(address)
210
212
  if String === address
@@ -59,7 +59,7 @@ module Unicorn
59
59
  REQUEST_URI='REQUEST_URI'.freeze
60
60
  REQUEST_PATH='REQUEST_PATH'.freeze
61
61
 
62
- UNICORN_VERSION="0.7.0".freeze
62
+ UNICORN_VERSION="0.7.1".freeze
63
63
 
64
64
  DEFAULT_HOST = "0.0.0.0".freeze # default TCP listen host address
65
65
  DEFAULT_PORT = "8080".freeze # default TCP listen port
@@ -31,7 +31,7 @@ module Unicorn
31
31
  # writes the rack_response to socket as an HTTP response
32
32
  def self.write(socket, rack_response)
33
33
  status, headers, body = rack_response
34
- status = HTTP_STATUS_CODES[status]
34
+ status = HTTP_STATUS_CODES[status.to_i]
35
35
  OUT.clear
36
36
 
37
37
  # Don't bother enforcing duplicate supression, it's a Hash most of
@@ -4,6 +4,8 @@ module Unicorn
4
4
  class Util
5
5
  class << self
6
6
 
7
+ APPEND_FLAGS = File::WRONLY | File::APPEND
8
+
7
9
  # this reopens logs that have been rotated (using logrotate(8) or
8
10
  # similar). It is recommended that you install
9
11
  # A +File+ object is considered for reopening if it is:
@@ -17,17 +19,20 @@ module Unicorn
17
19
  ObjectSpace.each_object(File) do |fp|
18
20
  next if fp.closed?
19
21
  next unless (fp.sync && fp.path[0..0] == "/")
20
-
21
- flags = fp.fcntl(Fcntl::F_GETFL)
22
- open_flags = File::WRONLY | File::APPEND
23
- next unless (flags & open_flags) == open_flags
22
+ next unless (fp.fcntl(Fcntl::F_GETFL) & APPEND_FLAGS) == APPEND_FLAGS
24
23
 
25
24
  begin
26
25
  a, b = fp.stat, File.stat(fp.path)
27
26
  next if a.ino == b.ino && a.dev == b.dev
28
27
  rescue Errno::ENOENT
29
28
  end
30
- fp.reopen(fp.path, "a")
29
+
30
+ open_arg = 'a'
31
+ if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
32
+ open_arg << ":#{enc.to_s}"
33
+ enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
34
+ end
35
+ fp.reopen(fp.path, open_arg)
31
36
  fp.sync = true
32
37
  nr += 1
33
38
  end # each_object
@@ -1,11 +1,6 @@
1
1
  # Copyright (c) 2009 Eric Wong
2
2
  # You can redistribute it and/or modify it under the same terms as Ruby.
3
3
 
4
- if RUBY_VERSION =~ /1\.9/
5
- warn "#$0 current broken under Ruby 1.9 with Rack"
6
- exit 0
7
- end
8
-
9
4
  require 'test/test_helper'
10
5
  begin
11
6
  require 'rack'
@@ -18,11 +18,19 @@ class ResponseTest < Test::Unit::TestCase
18
18
  assert out.length > 0, "output didn't have data"
19
19
  end
20
20
 
21
+ def test_response_string_status
22
+ out = StringIO.new
23
+ HttpResponse.write(out,['200', {}, []])
24
+ assert out.closed?
25
+ assert out.length > 0, "output didn't have data"
26
+ assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/).size
27
+ end
28
+
21
29
  def test_response_OFS_set
22
30
  old_ofs = $,
23
31
  $, = "\f\v"
24
32
  out = StringIO.new
25
- HttpResponse.write(out,[200, {"X-Whatever" => "stuff"}, ["cool"]])
33
+ HttpResponse.write(out,[200, {"X-k" => "cd","X-y" => "z"}, ["cool"]])
26
34
  assert out.closed?
27
35
  resp = out.string
28
36
  assert ! resp.include?("\f\v"), "output didn't use $, ($OFS)"
@@ -19,12 +19,28 @@ class UploadTest < Test::Unit::TestCase
19
19
  @sha1_app = lambda do |env|
20
20
  input = env['rack.input']
21
21
  resp = { :pos => input.pos, :size => input.size, :class => input.class }
22
+
23
+ # sysread
22
24
  @sha1.reset
23
25
  begin
24
26
  loop { @sha1.update(input.sysread(@bs)) }
25
27
  rescue EOFError
26
28
  end
27
29
  resp[:sha1] = @sha1.hexdigest
30
+
31
+ # read
32
+ input.sysseek(0) if input.respond_to?(:sysseek)
33
+ input.rewind
34
+ @sha1.reset
35
+ loop {
36
+ buf = input.read(@bs) or break
37
+ @sha1.update(buf)
38
+ }
39
+
40
+ if resp[:sha1] == @sha1.hexdigest
41
+ resp[:sysread_read_byte_match] = true
42
+ end
43
+
28
44
  [ 200, @hdr.merge({'X-Resp' => resp.inspect}), [] ]
29
45
  end
30
46
  end
@@ -218,6 +234,7 @@ class UploadTest < Test::Unit::TestCase
218
234
  assert $?.success?, 'curl ran OK'
219
235
  assert_match(%r!\b#{sha1}\b!, resp)
220
236
  assert_match(/Tempfile/, resp)
237
+ assert_match(/sysread_read_byte_match/, resp)
221
238
 
222
239
  # small StringIO path
223
240
  assert(system("dd", "if=#{@random.path}", "of=#{tmp.path}",
@@ -233,6 +250,7 @@ class UploadTest < Test::Unit::TestCase
233
250
  assert $?.success?, 'curl ran OK'
234
251
  assert_match(%r!\b#{sha1}\b!, resp)
235
252
  assert_match(/StringIO/, resp)
253
+ assert_match(/sysread_read_byte_match/, resp)
236
254
  end
237
255
 
238
256
  private
@@ -0,0 +1,87 @@
1
+ require 'test/test_helper'
2
+ require 'tempfile'
3
+
4
+ class TestUtil < Test::Unit::TestCase
5
+
6
+ EXPECT_FLAGS = File::WRONLY | File::APPEND
7
+ def test_reopen_logs_noop
8
+ tmp = Tempfile.new(nil)
9
+ tmp.reopen(tmp.path, 'a')
10
+ tmp.sync = true
11
+ ext = tmp.external_encoding rescue nil
12
+ int = tmp.internal_encoding rescue nil
13
+ before = tmp.stat.inspect
14
+ Unicorn::Util.reopen_logs
15
+ assert_equal before, File.stat(tmp.path).inspect
16
+ assert_equal ext, (tmp.external_encoding rescue nil)
17
+ assert_equal int, (tmp.internal_encoding rescue nil)
18
+ end
19
+
20
+ def test_reopen_logs_renamed
21
+ tmp = Tempfile.new(nil)
22
+ tmp_path = tmp.path.freeze
23
+ tmp.reopen(tmp_path, 'a')
24
+ tmp.sync = true
25
+ ext = tmp.external_encoding rescue nil
26
+ int = tmp.internal_encoding rescue nil
27
+ before = tmp.stat.inspect
28
+ to = Tempfile.new(nil)
29
+ File.rename(tmp_path, to.path)
30
+ assert ! File.exist?(tmp_path)
31
+ Unicorn::Util.reopen_logs
32
+ assert_equal tmp_path, tmp.path
33
+ assert File.exist?(tmp_path)
34
+ assert before != File.stat(tmp_path).inspect
35
+ assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
36
+ assert_equal ext, (tmp.external_encoding rescue nil)
37
+ assert_equal int, (tmp.internal_encoding rescue nil)
38
+ assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
39
+ assert tmp.sync
40
+ end
41
+
42
+ def test_reopen_logs_renamed_with_encoding
43
+ tmp = Tempfile.new(nil)
44
+ tmp_path = tmp.path.dup.freeze
45
+ Encoding.list.each { |encoding|
46
+ tmp.reopen(tmp_path, "a:#{encoding.to_s}")
47
+ tmp.sync = true
48
+ assert_equal encoding, tmp.external_encoding
49
+ assert_nil tmp.internal_encoding
50
+ File.unlink(tmp_path)
51
+ assert ! File.exist?(tmp_path)
52
+ Unicorn::Util.reopen_logs
53
+ assert_equal tmp_path, tmp.path
54
+ assert File.exist?(tmp_path)
55
+ assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
56
+ assert_equal encoding, tmp.external_encoding
57
+ assert_nil tmp.internal_encoding
58
+ assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
59
+ assert tmp.sync
60
+ }
61
+ end if STDIN.respond_to?(:external_encoding)
62
+
63
+ def test_reopen_logs_renamed_with_internal_encoding
64
+ tmp = Tempfile.new(nil)
65
+ tmp_path = tmp.path.dup.freeze
66
+ Encoding.list.each { |ext|
67
+ Encoding.list.each { |int|
68
+ next if ext == int
69
+ tmp.reopen(tmp_path, "a:#{ext.to_s}:#{int.to_s}")
70
+ tmp.sync = true
71
+ assert_equal ext, tmp.external_encoding
72
+ assert_equal int, tmp.internal_encoding
73
+ File.unlink(tmp_path)
74
+ assert ! File.exist?(tmp_path)
75
+ Unicorn::Util.reopen_logs
76
+ assert_equal tmp_path, tmp.path
77
+ assert File.exist?(tmp_path)
78
+ assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
79
+ assert_equal ext, tmp.external_encoding
80
+ assert_equal int, tmp.internal_encoding
81
+ assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
82
+ assert tmp.sync
83
+ }
84
+ }
85
+ end if STDIN.respond_to?(:external_encoding)
86
+
87
+ end
@@ -2,29 +2,29 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{unicorn}
5
- s.version = "0.7.0"
5
+ s.version = "0.7.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Eric Wong"]
9
- s.date = %q{2009-04-25}
9
+ s.date = %q{2009-05-22}
10
10
  s.description = %q{A small fast HTTP library and server for Rack applications.}
11
11
  s.email = %q{normalperson@yhbt.net}
12
12
  s.executables = ["unicorn", "unicorn_rails"]
13
13
  s.extensions = ["ext/unicorn/http11/extconf.rb"]
14
14
  s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "TODO", "bin/unicorn", "bin/unicorn_rails", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb"]
15
- s.files = [".document", ".gitignore", "CHANGELOG", "CONTRIBUTORS", "DESIGN", "GNUmakefile", "LICENSE", "Manifest", "PHILOSOPHY", "README", "Rakefile", "SIGNALS", "TODO", "bin/unicorn", "bin/unicorn_rails", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb", "local.mk.sample", "setup.rb", "test/aggregate.rb", "test/benchmark/README", "test/benchmark/big_request.rb", "test/benchmark/dd.ru", "test/benchmark/request.rb", "test/benchmark/response.rb", "test/exec/README", "test/exec/test_exec.rb", "test/rails/app-1.2.3/.gitignore", "test/rails/app-1.2.3/Rakefile", "test/rails/app-1.2.3/app/controllers/application.rb", "test/rails/app-1.2.3/app/controllers/foo_controller.rb", "test/rails/app-1.2.3/app/helpers/application_helper.rb", "test/rails/app-1.2.3/config/boot.rb", "test/rails/app-1.2.3/config/database.yml", "test/rails/app-1.2.3/config/environment.rb", "test/rails/app-1.2.3/config/environments/development.rb", "test/rails/app-1.2.3/config/environments/production.rb", "test/rails/app-1.2.3/config/routes.rb", "test/rails/app-1.2.3/db/.gitignore", "test/rails/app-1.2.3/log/.gitignore", "test/rails/app-1.2.3/public/404.html", "test/rails/app-1.2.3/public/500.html", "test/rails/app-2.0.2/.gitignore", "test/rails/app-2.0.2/Rakefile", "test/rails/app-2.0.2/app/controllers/application.rb", "test/rails/app-2.0.2/app/controllers/foo_controller.rb", "test/rails/app-2.0.2/app/helpers/application_helper.rb", "test/rails/app-2.0.2/config/boot.rb", "test/rails/app-2.0.2/config/database.yml", "test/rails/app-2.0.2/config/environment.rb", "test/rails/app-2.0.2/config/environments/development.rb", "test/rails/app-2.0.2/config/environments/production.rb", "test/rails/app-2.0.2/config/routes.rb", "test/rails/app-2.0.2/db/.gitignore", "test/rails/app-2.0.2/log/.gitignore", "test/rails/app-2.0.2/public/404.html", "test/rails/app-2.0.2/public/500.html", "test/rails/app-2.1.2/.gitignore", "test/rails/app-2.1.2/Rakefile", "test/rails/app-2.1.2/app/controllers/application.rb", "test/rails/app-2.1.2/app/controllers/foo_controller.rb", "test/rails/app-2.1.2/app/helpers/application_helper.rb", "test/rails/app-2.1.2/config/boot.rb", "test/rails/app-2.1.2/config/database.yml", "test/rails/app-2.1.2/config/environment.rb", "test/rails/app-2.1.2/config/environments/development.rb", "test/rails/app-2.1.2/config/environments/production.rb", "test/rails/app-2.1.2/config/routes.rb", "test/rails/app-2.1.2/db/.gitignore", "test/rails/app-2.1.2/log/.gitignore", "test/rails/app-2.1.2/public/404.html", "test/rails/app-2.1.2/public/500.html", "test/rails/app-2.2.2/.gitignore", "test/rails/app-2.2.2/Rakefile", "test/rails/app-2.2.2/app/controllers/application.rb", "test/rails/app-2.2.2/app/controllers/foo_controller.rb", "test/rails/app-2.2.2/app/helpers/application_helper.rb", "test/rails/app-2.2.2/config/boot.rb", "test/rails/app-2.2.2/config/database.yml", "test/rails/app-2.2.2/config/environment.rb", "test/rails/app-2.2.2/config/environments/development.rb", "test/rails/app-2.2.2/config/environments/production.rb", "test/rails/app-2.2.2/config/routes.rb", "test/rails/app-2.2.2/db/.gitignore", "test/rails/app-2.2.2/log/.gitignore", "test/rails/app-2.2.2/public/404.html", "test/rails/app-2.2.2/public/500.html", "test/rails/app-2.3.2.1/.gitignore", "test/rails/app-2.3.2.1/Rakefile", "test/rails/app-2.3.2.1/app/controllers/application_controller.rb", "test/rails/app-2.3.2.1/app/controllers/foo_controller.rb", "test/rails/app-2.3.2.1/app/helpers/application_helper.rb", "test/rails/app-2.3.2.1/config/boot.rb", "test/rails/app-2.3.2.1/config/database.yml", "test/rails/app-2.3.2.1/config/environment.rb", "test/rails/app-2.3.2.1/config/environments/development.rb", "test/rails/app-2.3.2.1/config/environments/production.rb", "test/rails/app-2.3.2.1/config/routes.rb", "test/rails/app-2.3.2.1/db/.gitignore", "test/rails/app-2.3.2.1/log/.gitignore", "test/rails/app-2.3.2.1/public/404.html", "test/rails/app-2.3.2.1/public/500.html", "test/rails/test_rails.rb", "test/test_helper.rb", "test/tools/trickletest.rb", "test/unit/test_configurator.rb", "test/unit/test_http_parser.rb", "test/unit/test_request.rb", "test/unit/test_response.rb", "test/unit/test_server.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb", "test/unit/test_upload.rb", "unicorn.gemspec"]
15
+ s.files = [".document", ".gitignore", "CHANGELOG", "CONTRIBUTORS", "DESIGN", "GNUmakefile", "LICENSE", "Manifest", "PHILOSOPHY", "README", "Rakefile", "SIGNALS", "TODO", "TUNING", "bin/unicorn", "bin/unicorn_rails", "examples/init.sh", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb", "local.mk.sample", "setup.rb", "test/aggregate.rb", "test/benchmark/README", "test/benchmark/big_request.rb", "test/benchmark/dd.ru", "test/benchmark/request.rb", "test/benchmark/response.rb", "test/exec/README", "test/exec/test_exec.rb", "test/rails/app-1.2.3/.gitignore", "test/rails/app-1.2.3/Rakefile", "test/rails/app-1.2.3/app/controllers/application.rb", "test/rails/app-1.2.3/app/controllers/foo_controller.rb", "test/rails/app-1.2.3/app/helpers/application_helper.rb", "test/rails/app-1.2.3/config/boot.rb", "test/rails/app-1.2.3/config/database.yml", "test/rails/app-1.2.3/config/environment.rb", "test/rails/app-1.2.3/config/environments/development.rb", "test/rails/app-1.2.3/config/environments/production.rb", "test/rails/app-1.2.3/config/routes.rb", "test/rails/app-1.2.3/db/.gitignore", "test/rails/app-1.2.3/log/.gitignore", "test/rails/app-1.2.3/public/404.html", "test/rails/app-1.2.3/public/500.html", "test/rails/app-2.0.2/.gitignore", "test/rails/app-2.0.2/Rakefile", "test/rails/app-2.0.2/app/controllers/application.rb", "test/rails/app-2.0.2/app/controllers/foo_controller.rb", "test/rails/app-2.0.2/app/helpers/application_helper.rb", "test/rails/app-2.0.2/config/boot.rb", "test/rails/app-2.0.2/config/database.yml", "test/rails/app-2.0.2/config/environment.rb", "test/rails/app-2.0.2/config/environments/development.rb", "test/rails/app-2.0.2/config/environments/production.rb", "test/rails/app-2.0.2/config/routes.rb", "test/rails/app-2.0.2/db/.gitignore", "test/rails/app-2.0.2/log/.gitignore", "test/rails/app-2.0.2/public/404.html", "test/rails/app-2.0.2/public/500.html", "test/rails/app-2.1.2/.gitignore", "test/rails/app-2.1.2/Rakefile", "test/rails/app-2.1.2/app/controllers/application.rb", "test/rails/app-2.1.2/app/controllers/foo_controller.rb", "test/rails/app-2.1.2/app/helpers/application_helper.rb", "test/rails/app-2.1.2/config/boot.rb", "test/rails/app-2.1.2/config/database.yml", "test/rails/app-2.1.2/config/environment.rb", "test/rails/app-2.1.2/config/environments/development.rb", "test/rails/app-2.1.2/config/environments/production.rb", "test/rails/app-2.1.2/config/routes.rb", "test/rails/app-2.1.2/db/.gitignore", "test/rails/app-2.1.2/log/.gitignore", "test/rails/app-2.1.2/public/404.html", "test/rails/app-2.1.2/public/500.html", "test/rails/app-2.2.2/.gitignore", "test/rails/app-2.2.2/Rakefile", "test/rails/app-2.2.2/app/controllers/application.rb", "test/rails/app-2.2.2/app/controllers/foo_controller.rb", "test/rails/app-2.2.2/app/helpers/application_helper.rb", "test/rails/app-2.2.2/config/boot.rb", "test/rails/app-2.2.2/config/database.yml", "test/rails/app-2.2.2/config/environment.rb", "test/rails/app-2.2.2/config/environments/development.rb", "test/rails/app-2.2.2/config/environments/production.rb", "test/rails/app-2.2.2/config/routes.rb", "test/rails/app-2.2.2/db/.gitignore", "test/rails/app-2.2.2/log/.gitignore", "test/rails/app-2.2.2/public/404.html", "test/rails/app-2.2.2/public/500.html", "test/rails/app-2.3.2.1/.gitignore", "test/rails/app-2.3.2.1/Rakefile", "test/rails/app-2.3.2.1/app/controllers/application_controller.rb", "test/rails/app-2.3.2.1/app/controllers/foo_controller.rb", "test/rails/app-2.3.2.1/app/helpers/application_helper.rb", "test/rails/app-2.3.2.1/config/boot.rb", "test/rails/app-2.3.2.1/config/database.yml", "test/rails/app-2.3.2.1/config/environment.rb", "test/rails/app-2.3.2.1/config/environments/development.rb", "test/rails/app-2.3.2.1/config/environments/production.rb", "test/rails/app-2.3.2.1/config/routes.rb", "test/rails/app-2.3.2.1/db/.gitignore", "test/rails/app-2.3.2.1/log/.gitignore", "test/rails/app-2.3.2.1/public/404.html", "test/rails/app-2.3.2.1/public/500.html", "test/rails/test_rails.rb", "test/test_helper.rb", "test/tools/trickletest.rb", "test/unit/test_configurator.rb", "test/unit/test_http_parser.rb", "test/unit/test_request.rb", "test/unit/test_response.rb", "test/unit/test_server.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb", "test/unit/test_upload.rb", "test/unit/test_util.rb", "unicorn.gemspec"]
16
16
  s.has_rdoc = true
17
17
  s.homepage = %q{http://unicorn.bogomips.org}
18
18
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Unicorn", "--main", "README"]
19
19
  s.require_paths = ["lib", "ext"]
20
20
  s.rubyforge_project = %q{unicorn}
21
- s.rubygems_version = %q{1.3.1}
21
+ s.rubygems_version = %q{1.3.2}
22
22
  s.summary = %q{A small fast HTTP library and server for Rack applications.}
23
- s.test_files = ["test/unit/test_request.rb", "test/unit/test_http_parser.rb", "test/unit/test_server.rb", "test/unit/test_response.rb", "test/unit/test_configurator.rb", "test/unit/test_upload.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb"]
23
+ s.test_files = ["test/unit/test_configurator.rb", "test/unit/test_response.rb", "test/unit/test_request.rb", "test/unit/test_signals.rb", "test/unit/test_upload.rb", "test/unit/test_http_parser.rb", "test/unit/test_socket_helper.rb", "test/unit/test_util.rb", "test/unit/test_server.rb"]
24
24
 
25
25
  if s.respond_to? :specification_version then
26
26
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
- s.specification_version = 2
27
+ s.specification_version = 3
28
28
 
29
29
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
30
  else
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Wong
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-25 00:00:00 -07:00
12
+ date: 2009-05-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -59,8 +59,10 @@ files:
59
59
  - Rakefile
60
60
  - SIGNALS
61
61
  - TODO
62
+ - TUNING
62
63
  - bin/unicorn
63
64
  - bin/unicorn_rails
65
+ - examples/init.sh
64
66
  - ext/unicorn/http11/ext_help.h
65
67
  - ext/unicorn/http11/extconf.rb
66
68
  - ext/unicorn/http11/http11.c
@@ -175,9 +177,12 @@ files:
175
177
  - test/unit/test_signals.rb
176
178
  - test/unit/test_socket_helper.rb
177
179
  - test/unit/test_upload.rb
180
+ - test/unit/test_util.rb
178
181
  - unicorn.gemspec
179
182
  has_rdoc: true
180
183
  homepage: http://unicorn.bogomips.org
184
+ licenses: []
185
+
181
186
  post_install_message:
182
187
  rdoc_options:
183
188
  - --line-numbers
@@ -204,16 +209,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
209
  requirements: []
205
210
 
206
211
  rubyforge_project: unicorn
207
- rubygems_version: 1.3.1
212
+ rubygems_version: 1.3.2
208
213
  signing_key:
209
- specification_version: 2
214
+ specification_version: 3
210
215
  summary: A small fast HTTP library and server for Rack applications.
211
216
  test_files:
212
- - test/unit/test_request.rb
213
- - test/unit/test_http_parser.rb
214
- - test/unit/test_server.rb
215
- - test/unit/test_response.rb
216
217
  - test/unit/test_configurator.rb
217
- - test/unit/test_upload.rb
218
+ - test/unit/test_response.rb
219
+ - test/unit/test_request.rb
218
220
  - test/unit/test_signals.rb
221
+ - test/unit/test_upload.rb
222
+ - test/unit/test_http_parser.rb
219
223
  - test/unit/test_socket_helper.rb
224
+ - test/unit/test_util.rb
225
+ - test/unit/test_server.rb