unicorn 0.95.1 → 0.95.2

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
@@ -15,3 +15,4 @@ lib
15
15
  ext/unicorn_http/unicorn_http.c
16
16
  unicorn.1
17
17
  unicorn_rails.1
18
+ ISSUES
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.95.1.GIT
4
+ DEF_VER=v0.95.2.GIT
5
5
 
6
6
  LF='
7
7
  '
@@ -1,4 +1,4 @@
1
- # use GNU Make to run tests in parallel, and without depending on Rubygems
1
+ # use GNU Make to run tests in parallel, and without depending on RubyGems
2
2
  all:: test
3
3
  ruby = ruby
4
4
  rake = rake
@@ -157,9 +157,12 @@ NEWS: GIT-VERSION-FILE
157
157
  mv $@+ $@
158
158
 
159
159
  SINCE = 0.94.0
160
- ChangeLog: log_range = $(shell test -n "$(SINCE)" && echo v$(SINCE)..)
160
+ ChangeLog: LOG_VERSION = \
161
+ $(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \
162
+ echo $(GIT_VERSION) || git describe)
163
+ ChangeLog: log_range = v$(SINCE)..$(LOG_VERSION)
161
164
  ChangeLog: GIT-VERSION-FILE
162
- @echo "ChangeLog from $(GIT_URL) ($(SINCE)..$(GIT_VERSION))" > $@+
165
+ @echo "ChangeLog from $(GIT_URL) ($(log_range))" > $@+
163
166
  @echo >> $@+
164
167
  git log $(log_range) | sed -e 's/^/ /' >> $@+
165
168
  mv $@+ $@
@@ -261,9 +264,14 @@ $(pkgtgz): manifest fix-perms
261
264
  package: $(pkgtgz) $(pkggem)
262
265
 
263
266
  release: verify package $(release_notes) $(release_changes)
267
+ # make tgz release on RubyForge
264
268
  rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
265
269
  $(rfproject) $(rfpackage) $(VERSION) $(pkgtgz)
266
- @echo do something with gemcutter for: $(pkggem)
270
+ # push gem to Gemcutter
271
+ gem push $(pkggem)
272
+ # in case of gem downloads from RubyForge releases page
273
+ -rubyforge add_file \
274
+ $(rfproject) $(rfpackage) $(VERSION) $(pkggem)
267
275
  else
268
276
  gem install-gem: GIT-VERSION-FILE
269
277
  $(MAKE) $@ VERSION=$(GIT_VERSION)
data/HACKING CHANGED
@@ -14,14 +14,14 @@ done.
14
14
 
15
15
  Tests are good, but slow tests make development slow, so we make tests
16
16
  faster (in parallel) with GNU make (instead of Rake) and avoiding
17
- Rubygems.
17
+ RubyGems.
18
18
 
19
19
  Users of GNU-based systems (such as GNU/Linux) usually have GNU make installed
20
20
  as "make" instead of "gmake".
21
21
 
22
22
  Since we don't load RubyGems by default, loading Rack properly requires
23
23
  setting up RUBYLIB to point to where Rack is located. Not loading
24
- Rubygems drastically lowers the time to run the full test suite. You
24
+ RubyGems drastically lowers the time to run the full test suite. You
25
25
  may setup a "local.mk" file in the top-level working directory to setup
26
26
  your RUBYLIB and any other environment variables. A "local.mk.sample"
27
27
  file is provided for reference.
@@ -91,7 +91,7 @@ user and developer feedback and bug reports.
91
91
  Follow conventions already established in the code and do not exceed 80
92
92
  characters per line.
93
93
 
94
- Inline patches (from "git format-patch") to the mailing list are
94
+ Inline patches (from "git format-patch -M") to the mailing list are
95
95
  preferred because they allow code review and comments in the reply to
96
96
  the patch.
97
97
 
data/ISSUES ADDED
@@ -0,0 +1,36 @@
1
+ = Issues
2
+
3
+ The {mailing list}[mailto:mongrel-unicorn@rubyforge.org] is the best
4
+ place to report bugs, submit patches and/or obtain support after you
5
+ have searched the mailing list archives and
6
+ {documentation}[http://unicorn.bogomips.org].
7
+
8
+ * No subscription is needed to post to the mailing list,
9
+ let us know that we need to Cc: replies to you if you're unsubscribed.
10
+ * Do not {top post}[http://catb.org/jargon/html/T/top-post.html] in replies
11
+ * Quote only the relevant portions of the message you're replying to
12
+ * Do not send HTML mail
13
+
14
+ If your issue is of a sensitive nature or you're just shy in public,
15
+ then feel free to email us privately at mailto:unicorn@bogomips.org
16
+ instead and your issue will be handled discreetly.
17
+
18
+ If you don't get a response within a few days, we may have forgotten
19
+ about it so feel free to ask again.
20
+
21
+ == Submitting Patches
22
+
23
+ See the HACKING document (and additionally, the
24
+ Documentation/SubmittingPatches document distributed with git) on
25
+ guidelines for patch submission.
26
+
27
+ == Mailing List Info
28
+
29
+ * subscribe: http://rubyforge.org/mailman/listinfo/mongrel-unicorn
30
+ * post: mailto:mongrel-unicorn@rubyforge.org
31
+ * private: mailto:unicorn@bogomips.org
32
+
33
+ == Mailing List Archives
34
+
35
+ * nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
36
+ * http://rubyforge.org/pipermail/mongrel-unicorn
@@ -1,5 +1,8 @@
1
1
  = Known Issues
2
2
 
3
+ Occasionally odd {issues}[link:ISSUES.html] arise without a transparent or
4
+ acceptable solution. Those issues are documented here.
5
+
3
6
  * Rails 2.3.2 bundles its own version of Rack. This may cause subtle
4
7
  bugs when simultaneously loaded with the system-wide Rack Rubygem
5
8
  which Unicorn depends on. Upgrading to Rails 2.3.4 (or later) is
data/README CHANGED
@@ -1,6 +1,6 @@
1
1
  = Unicorn: Rack HTTP server for fast clients and Unix
2
2
 
3
- Unicorn is a HTTP server for Rack applications designed to only serve
3
+ Unicorn is an HTTP server for Rack applications designed to only serve
4
4
  fast clients on low-latency, high-bandwidth connections and take
5
5
  advantage of features in Unix/Unix-like kernels. Slow clients should
6
6
  only be served by placing a reverse proxy capable of fully buffering
@@ -78,7 +78,7 @@ and run setup.rb after unpacking it:
78
78
 
79
79
  http://rubyforge.org/frs/?group_id=1306
80
80
 
81
- You may also install it via Rubygems on Rubyforge:
81
+ You may also install it via RubyGems on Gemcutter:
82
82
 
83
83
  gem install unicorn
84
84
 
@@ -86,9 +86,7 @@ You can get the latest source via git from the following locations
86
86
  (these versions may not be stable):
87
87
 
88
88
  git://git.bogomips.org/unicorn.git
89
- http://git.bogomips.org/unicorn.git
90
89
  git://repo.or.cz/unicorn.git (mirror)
91
- http://repo.or.cz/r/unicorn.git (mirror)
92
90
 
93
91
  You may browse the code from the web and download the latest snapshot
94
92
  tarballs here:
@@ -96,6 +94,9 @@ tarballs here:
96
94
  * http://git.bogomips.org/cgit/unicorn.git (cgit)
97
95
  * http://repo.or.cz/w/unicorn.git (gitweb)
98
96
 
97
+ See the HACKING guide on how to contribute and build prerelease gems
98
+ from git.
99
+
99
100
  == Usage
100
101
 
101
102
  === non-Rails Rack applications
@@ -130,9 +131,8 @@ options.
130
131
 
131
132
  == Disclaimer
132
133
 
133
- Like the creatures themselves, production deployments of Unicorn are
134
- rare. There is NO WARRANTY whatsoever if anything goes wrong, but let
135
- us know and we'll try our best to fix it.
134
+ There is NO WARRANTY whatsoever if anything goes wrong, but
135
+ {let us know}[link:ISSUES.html] and we'll try our best to fix it.
136
136
 
137
137
  Unicorn is designed to only serve fast clients either on the local host
138
138
  or a fast LAN. See the PHILOSOPHY and DESIGN documents for more details
@@ -141,13 +141,9 @@ regarding this.
141
141
  == Contact
142
142
 
143
143
  All feedback (bug reports, user/development dicussion, patches, pull
144
- requests) go to the mailing list/newsgroup. Patches must be sent inline
145
- (git format-patch -M + git send-email). No subscription is necessary
146
- to post on the mailing list. No top posting. Address replies +To:+
147
- the mailing list.
148
-
149
- * email: mailto:mongrel-unicorn@rubyforge.org
150
- * nntp: nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
151
- * archives: http://rubyforge.org/pipermail/mongrel-unicorn/
152
- * subscribe: http://rubyforge.org/mailman/listinfo/mongrel-unicorn/
153
- * finger: unicorn@bogomips.org
144
+ requests) go to the mailing list/newsgroup. See the ISSUES document for
145
+ information on the {mailing list}[mailto:mongrel-unicorn@rubyforge.org].
146
+
147
+ For the latest on Unicorn releases, you may also finger us at
148
+ unicorn@bogomips.org or check our NEWS page (and subscribe to our Atom
149
+ feed).
data/Rakefile CHANGED
@@ -59,7 +59,9 @@ task :news_atom do
59
59
  url = "#{cgit_url}/tag/?id=#{tag[:tag]}"
60
60
  link! :rel => "alternate", :type => "text/html", :href =>url
61
61
  id! url
62
- content({:type => 'text'}, tag[:body])
62
+ message_only = tag[:body].split(/\n.+\(\d+\):\n {6}/s).first.strip
63
+ content({:type =>:text}, message_only)
64
+ content(:type =>:xhtml) { pre tag[:body] }
63
65
  end
64
66
  end
65
67
  end
@@ -143,3 +145,20 @@ task :raa_update do
143
145
  p res
144
146
  puts res.body
145
147
  end
148
+
149
+ # optional rake-compiler support in case somebody needs to cross compile
150
+ begin
151
+ require 'rubygems'
152
+ spec = Gem::Specification.load('unicorn.gemspec')
153
+ require 'rake/extensiontask'
154
+ unless test ?r, "ext/unicorn_http/unicorn_http.c"
155
+ abort "run 'gmake ragel' or 'make ragel' to generate the Ragel source"
156
+ end
157
+ mk = "ext/unicorn_http/Makefile"
158
+ if test ?r, mk
159
+ abort "run 'gmake -C ext/unicorn_http clean' and " \
160
+ "remove #{mk} before using rake-compiler"
161
+ end
162
+ Rake::ExtensionTask.new('unicorn_http', spec)
163
+ rescue LoadError
164
+ end
@@ -0,0 +1,139 @@
1
+ # This is example contains the bare mininum to get nginx going with
2
+ # Unicorn or Rainbows! servers. Generally these configuration settings
3
+ # are applicable to other HTTP application servers (and not just Ruby
4
+ # ones), so if you have one working well for proxying another app
5
+ # server, feel free to continue using it.
6
+ #
7
+ # The only setting we feel strongly about is the fail_timeout=0
8
+ # directive in the "upstream" block. max_fails=0 also has the same
9
+ # effect as fail_timeout=0 for current versions of nginx and may be
10
+ # used in its place.
11
+ #
12
+ # Users are strongly encouraged to refer to nginx documentation for more
13
+ # details and search for other example configs.
14
+
15
+ # you generally only need one nginx worker unless you're serving
16
+ # large amounts of static files which require blocking disk reads
17
+ worker_processes 1;
18
+
19
+ # # drop privileges, root is needed on most systems for binding to port 80
20
+ # # (or anything < 1024). Capability-based security may be available for
21
+ # # your system and worth checking out so you won't need to be root to
22
+ # # start nginx to bind on 80
23
+ user nobody nogroup; # for systems with a "nogroup"
24
+ # user nobody nobody; # for systems with "nobody" as a group instead
25
+
26
+ # Feel free to change all paths to suite your needs here, of course
27
+ pid /tmp/nginx.pid;
28
+ error_log /tmp/nginx.error.log;
29
+
30
+ events {
31
+ worker_connections 1024; # increase if you have lots of clients
32
+ accept_mutex off; # "on" if nginx worker_processes > 1
33
+ # use epoll; # enable for Linux 2.6+
34
+ # use kqueue; # enable for FreeBSD, OSX
35
+ }
36
+
37
+ http {
38
+ # nginx will find this file in the config directory set at nginx build time
39
+ include mime.types;
40
+
41
+ # fallback in case we can't determine a type
42
+ default_type application/octet-stream;
43
+
44
+ # click tracking!
45
+ access_log /tmp/nginx.access.log combined;
46
+
47
+ # you generally want to serve static files with nginx since neither
48
+ # Unicorn nor Rainbows! is optimized for it at the moment
49
+ sendfile on;
50
+
51
+ tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
52
+ tcp_nodelay off; # on may be better for some Comet/long-poll stuff
53
+
54
+ # we haven't checked to see if Rack::Deflate on the app server is
55
+ # faster or not than doing compression via nginx. It's easier
56
+ # to configure it all in one place here for static files and also
57
+ # to disable gzip for clients who don't get gzip/deflate right.
58
+ # There are other other gzip settings that may be needed used to deal with
59
+ # bad clients out there, see http://wiki.nginx.org/NginxHttpGzipModule
60
+ gzip on;
61
+ gzip_http_version 1.0;
62
+ gzip_proxied any;
63
+ gzip_min_length 500;
64
+ gzip_disable "MSIE [1-6]\.";
65
+ gzip_types text/plain text/html text/xml text/css
66
+ text/comma-separated-values
67
+ text/javascript application/x-javascript
68
+ application/atom+xml;
69
+
70
+ # this can be any application server, not just Unicorn/Rainbows!
71
+ upstream app_server {
72
+ # fail_timeout=0 means we always retry an upstream even if it failed
73
+ # to return a good HTTP response (in case the Unicorn master nukes a
74
+ # single worker for timing out).
75
+
76
+ # for UNIX domain socket setups:
77
+ server unix:/tmp/.sock fail_timeout=0;
78
+
79
+ # for TCP setups, point these to your backend servers
80
+ # server 192.168.0.7:8080 fail_timeout=0;
81
+ # server 192.168.0.8:8080 fail_timeout=0;
82
+ # server 192.168.0.9:8080 fail_timeout=0;
83
+ }
84
+
85
+ server {
86
+ # listen 80 default deferred; # for Linux
87
+ # listen 80 default accept_filter=httpready; # for FreeBSD
88
+ listen 80 default;
89
+
90
+ client_max_body_size 4G;
91
+ server_name _;
92
+
93
+ # ~2 seconds is often enough for most folks to parse HTML/CSS and
94
+ # retrieve needed images/icons/frames, connections are cheap in
95
+ # nginx so increasing this is generally safe...
96
+ keepalive_timeout 5;
97
+
98
+ # path for static files
99
+ root /path/to/app/current/public;
100
+
101
+ location / {
102
+ # an HTTP header important enough to have its own Wikipedia entry:
103
+ # http://en.wikipedia.org/wiki/X-Forwarded-For
104
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
105
+
106
+ # enable this if and only if you use HTTPS, this helps Rack
107
+ # set the proper protocol for doing redirects:
108
+ # proxy_set_header X-Forwarded-Proto https;
109
+
110
+ # pass the Host: header from the client right along so redirects
111
+ # can be set properly within the Rack application
112
+ proxy_set_header Host $http_host;
113
+
114
+ # we don't want nginx trying to do something clever with
115
+ # redirects, we set the Host: header above already.
116
+ proxy_redirect off;
117
+
118
+ # set "proxy_buffering off" *only* for Rainbows! when doing
119
+ # Comet/long-poll stuff. It's also safe to set if you're
120
+ # using only serving fast clients with Unicorn + nginx.
121
+ # Otherwise you _want_ nginx to buffer responses to slow
122
+ # clients, really.
123
+ # proxy_buffering off;
124
+
125
+ # Try to serve static files from nginx, no point in making an
126
+ # *application* server like Unicorn/Rainbows! serve static files.
127
+ if (!-f $request_filename) {
128
+ proxy_pass http://app_server;
129
+ break;
130
+ }
131
+ }
132
+
133
+ # Rails error pages
134
+ error_page 500 502 503 504 /500.html;
135
+ location = /500.html {
136
+ root /path/to/app/current/public;
137
+ }
138
+ }
139
+ }
@@ -0,0 +1,78 @@
1
+ # Sample configuration file for Unicorn (not Rack)
2
+ #
3
+ # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
4
+ # documentation.
5
+
6
+ # Use at least one worker per core if you're on a dedicated server,
7
+ # more will usually help for _short_ waits on databases/caches.
8
+ worker_processes 4
9
+
10
+ # Help ensure your application will always spawn in the symlinked
11
+ # "current" directory that Capistrano sets up.
12
+ working_directory "/path/to/app/current" # available in 0.94.0+
13
+
14
+ # listen on both a Unix domain socket and a TCP port,
15
+ # we use a shorter backlog for quicker failover when busy
16
+ listen "/tmp/.sock", :backlog => 64
17
+ listen 8080, :tcp_nopush => true
18
+
19
+ # nuke workers after 30 seconds instead of 60 seconds (the default)
20
+ timeout 30
21
+
22
+ # feel free to point this anywhere accessible on the filesystem
23
+ pid "/path/to/app/shared/pids/unicorn.pid"
24
+
25
+ # some applications/frameworks log to stderr or stdout, so prevent
26
+ # them from going to /dev/null when daemonized here:
27
+ stderr_path "/path/to/app/shared/log/unicorn.stderr.log"
28
+ stdout_path "/path/to/app/shared/log/unicorn.stdout.log"
29
+
30
+ # combine REE with "preload_app true" for memory savings
31
+ # http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
32
+ preload_app true
33
+ GC.respond_to?(:copy_on_write_friendly=) and
34
+ GC.copy_on_write_friendly = true
35
+
36
+ before_fork do |server, worker|
37
+ # the following is highly recomended for Rails + "preload_app true"
38
+ # as there's no need for the master process to hold a connection
39
+ defined?(ActiveRecord::Base) and
40
+ ActiveRecord::Base.connection.disconnect!
41
+
42
+ # The following is only recommended for memory/DB-constrained
43
+ # installations. It is not needed if your system can house
44
+ # twice as many worker_processes as you have configured.
45
+ #
46
+ # # This allows a new master process to incrementally
47
+ # # phase out the old master process with SIGTTOU to avoid a
48
+ # # thundering herd (especially in the "preload_app false" case)
49
+ # # when doing a transparent upgrade. The last worker spawned
50
+ # # will then kill off the old master process with a SIGQUIT.
51
+ # old_pid = "#{server.config[:pid]}.oldbin"
52
+ # if old_pid != server.pid
53
+ # begin
54
+ # sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
55
+ # Process.kill(sig, File.read(old_pid).to_i)
56
+ # rescue Errno::ENOENT, Errno::ESRCH
57
+ # end
58
+ # end
59
+ #
60
+ # # *optionally* throttle the master from forking too quickly by sleeping
61
+ # sleep 1
62
+ end
63
+
64
+ after_fork do |server, worker|
65
+ # per-process listener ports for debugging/admin/migrations
66
+ # addr = "127.0.0.1:#{9293 + worker.nr}"
67
+ # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
68
+
69
+ # the following is *required* for Rails + "preload_app true",
70
+ defined?(ActiveRecord::Base) and
71
+ ActiveRecord::Base.establish_connection
72
+
73
+ # if preload_app is true, then you may also want to check and
74
+ # restart any other shared sockets/descriptors such as Memcached,
75
+ # and Redis. TokyoCabinet file handles are safe to reuse
76
+ # between any number of forked children (assuming your kernel
77
+ # correctly implements pread()/pwrite() system calls)
78
+ end
@@ -14,6 +14,9 @@
14
14
  #endif /* !RUBINIUS */
15
15
 
16
16
  #ifndef HAVE_RB_STR_SET_LEN
17
+ # ifdef RUBINIUS
18
+ # define rb_str_set_len(str,len) rb_str_resize(str,len)
19
+ # else /* 1.8.6 optimized version */
17
20
  /* this is taken from Ruby 1.8.7, 1.8.6 may not have it */
18
21
  static void rb_18_str_set_len(VALUE str, long len)
19
22
  {
@@ -21,7 +24,8 @@ static void rb_18_str_set_len(VALUE str, long len)
21
24
  RSTRING(str)->ptr[len] = '\0';
22
25
  rb_str_flush(str);
23
26
  }
24
- # define rb_str_set_len(str,len) rb_18_str_set_len(str,len)
27
+ # define rb_str_set_len(str,len) rb_18_str_set_len(str,len)
28
+ # endif /* ! RUBINIUS */
25
29
  #endif /* !defined(HAVE_RB_STR_SET_LEN) */
26
30
 
27
31
  /* not all Ruby implementations support frozen objects (Rubinius does not) */
@@ -33,7 +33,7 @@
33
33
  query = ( uchar | reserved )* %query_string ;
34
34
  param = ( pchar | "/" )* ;
35
35
  params = ( param ( ";" param )* ) ;
36
- rel_path = ( path? %request_path (";" params)? ) ("?" %start_query query)?;
36
+ rel_path = (path? (";" params)? %request_path) ("?" %start_query query)?;
37
37
  absolute_path = ( "/"+ rel_path );
38
38
  path_uri = absolute_path > mark %request_uri;
39
39
  Absolute_URI = (scheme "://" host_with_port path_uri);
@@ -300,7 +300,7 @@ module Unicorn
300
300
  end
301
301
  logger.info "listening on addr=#{sock_name(io)} fd=#{io.fileno}"
302
302
  LISTENERS << io
303
- return io
303
+ io
304
304
  rescue Errno::EADDRINUSE => err
305
305
  logger.error "adding listener failed addr=#{address} (in use)"
306
306
  raise err if tries == 0
@@ -703,7 +703,7 @@ module Unicorn
703
703
  wpid <= 0 and return nil
704
704
  begin
705
705
  Process.kill(0, wpid)
706
- return wpid
706
+ wpid
707
707
  rescue Errno::ESRCH
708
708
  # don't unlink stale pid files, racy without non-portable locking...
709
709
  end
@@ -46,11 +46,7 @@ class Unicorn::App::OldRails::Static < Struct.new(:app, :root, :file_server)
46
46
  end
47
47
 
48
48
  # then try the cached version:
49
-
50
- # grab the semi-colon REST operator used by old versions of Rails
51
- # this is the reason we didn't just copy the new Rails::Rack::Static
52
- env[REQUEST_URI] =~ /^#{Regexp.escape(path_info)}(;[^\?]+)/
53
- path_info << "#$1#{ActionController::Base.page_cache_extension}"
49
+ path_info << ActionController::Base.page_cache_extension
54
50
 
55
51
  if File.file?("#{root}/#{::Rack::Utils.unescape(path_info)}")
56
52
  env[PATH_INFO] = path_info
@@ -7,63 +7,9 @@ module Unicorn
7
7
 
8
8
  # Implements a simple DSL for configuring a Unicorn server.
9
9
  #
10
- # Example (when used with the Unicorn config file):
11
- # worker_processes 4
12
- # working_directory "/path/to/deploy/app/current"
13
- # listen '/tmp/my_app.sock', :backlog => 1
14
- # listen 9292, :tcp_nopush => true
15
- # timeout 10
16
- # pid "/tmp/my_app.pid"
17
- #
18
- # # combine REE with "preload_app true" for memory savings
19
- # # http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
20
- # preload_app true
21
- # GC.respond_to?(:copy_on_write_friendly=) and
22
- # GC.copy_on_write_friendly = true
23
- #
24
- # before_fork do |server, worker|
25
- # # the following is highly recomended for Rails + "preload_app true"
26
- # # as there's no need for the master process to hold a connection
27
- # defined?(ActiveRecord::Base) and
28
- # ActiveRecord::Base.connection.disconnect!
29
- #
30
- # # The following is only recommended for memory/DB-constrained
31
- # # installations. It is not needed if your system can house
32
- # # twice as many worker_processes as you have configured.
33
- #
34
- # # This allows a new master process to incrementally
35
- # # phase out the old master process with SIGTTOU to avoid a
36
- # # thundering herd (especially in the "preload_app false" case)
37
- # # when doing a transparent upgrade. The last worker spawned
38
- # # will then kill off the old master process with a SIGQUIT.
39
- # old_pid = "#{server.config[:pid]}.oldbin"
40
- # if old_pid != server.pid
41
- # begin
42
- # sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
43
- # Process.kill(sig, File.read(old_pid).to_i)
44
- # rescue Errno::ENOENT, Errno::ESRCH
45
- # end
46
- # end
47
- #
48
- # # *optionally* throttle the master from forking too quickly by sleeping
49
- # sleep 1
50
- # end
51
- #
52
- # after_fork do |server, worker|
53
- # # per-process listener ports for debugging/admin/migrations
54
- # addr = "127.0.0.1:#{9293 + worker.nr}"
55
- # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
56
- #
57
- # # the following is *required* for Rails + "preload_app true",
58
- # defined?(ActiveRecord::Base) and
59
- # ActiveRecord::Base.establish_connection
60
- #
61
- # # if preload_app is true, then you may also want to check and
62
- # # restart any other shared sockets/descriptors such as Memcached,
63
- # # and Redis. TokyoCabinet file handles are safe to reuse
64
- # # between any number of forked children (assuming your kernel
65
- # # correctly implements pread()/pwrite() system calls)
66
- # end
10
+ # See http://unicorn.bogomips.org/examples/unicorn.conf.rb for an
11
+ # example config file. An example config file for use with nginx is
12
+ # also available at http://unicorn.bogomips.org/examples/nginx.conf
67
13
  class Configurator < Struct.new(:set, :config_file)
68
14
 
69
15
  # Default settings for Unicorn
@@ -7,7 +7,7 @@ module Unicorn
7
7
  # gave about a 3% to 10% performance improvement over using the strings directly.
8
8
  # Symbols did not really improve things much compared to constants.
9
9
  module Const
10
- UNICORN_VERSION="0.95.1"
10
+ UNICORN_VERSION="0.95.2"
11
11
 
12
12
  DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
13
13
  DEFAULT_PORT = 8080 # default TCP listen port
@@ -57,12 +57,10 @@ module Unicorn
57
57
 
58
58
  # short circuit the common case with small GET requests first
59
59
  if PARSER.headers(REQ, socket.readpartial(Const::CHUNK_SIZE, BUF)).nil?
60
- data = BUF.dup # socket.readpartial will clobber data
61
-
62
60
  # Parser is not done, queue up more data to read and continue parsing
63
61
  # an Exception thrown from the PARSER will throw us out of the loop
64
62
  begin
65
- BUF << socket.readpartial(Const::CHUNK_SIZE, data)
63
+ BUF << socket.readpartial(Const::CHUNK_SIZE)
66
64
  end while PARSER.headers(REQ, BUF).nil?
67
65
  end
68
66
  REQ[Const::RACK_INPUT] = 0 == PARSER.content_length ?
@@ -42,19 +42,19 @@ latest: NEWS
42
42
  # publishes docs to http://unicorn.bogomips.org
43
43
  publish_doc:
44
44
  -git set-file-times
45
- $(RM) -r doc
46
- $(MAKE) doc
45
+ $(RM) -r doc ChangeLog NEWS
46
+ $(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1)
47
47
  $(MAKE) -s latest > doc/LATEST
48
48
  find doc/images doc/js -type f | \
49
49
  TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css
50
50
  $(MAKE) doc_gz
51
+ tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
51
52
  chmod 644 $$(find doc -type f)
52
- rsync -av --delete doc/ dcvr:/srv/unicorn/
53
+ rsync -av doc/ dcvr:/srv/unicorn/
53
54
  git ls-files | xargs touch
54
55
 
55
56
  # Create gzip variants of the same timestamp as the original so nginx
56
57
  # "gzip_static on" can serve the gzipped versions directly.
57
- doc_gz: suf := html js css
58
58
  doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
59
59
  doc_gz:
60
60
  touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
@@ -910,11 +910,11 @@ EOF
910
910
  bodies[pid] += 1
911
911
  }
912
912
  }
913
- sleep 1 # racy
913
+ sleep 5 # racy
914
914
  daemon_pid = File.read(pid_file.path).to_i
915
915
  assert daemon_pid > 0
916
916
  Process.kill(:HUP, daemon_pid)
917
- sleep 1 # racy
917
+ sleep 5 # racy
918
918
  assert_nothing_raised { Process.kill(:TERM, hitter) }
919
919
  _, hitter_status = Process.waitpid2(hitter)
920
920
  assert hitter_status.success?
@@ -371,4 +371,50 @@ class HttpParserNgTest < Test::Unit::TestCase
371
371
  assert ! parser.headers?
372
372
  end
373
373
 
374
+ def test_path_info_semicolon
375
+ qs = "QUERY_STRING"
376
+ pi = "PATH_INFO"
377
+ req = {}
378
+ str = "GET %s HTTP/1.1\r\nHost: example.com\r\n\r\n"
379
+ {
380
+ "/1;a=b?c=d&e=f" => { qs => "c=d&e=f", pi => "/1;a=b" },
381
+ "/1?c=d&e=f" => { qs => "c=d&e=f", pi => "/1" },
382
+ "/1;a=b" => { qs => "", pi => "/1;a=b" },
383
+ "/1;a=b?" => { qs => "", pi => "/1;a=b" },
384
+ "/1?a=b;c=d&e=f" => { qs => "a=b;c=d&e=f", pi => "/1" },
385
+ "*" => { qs => "", pi => "" },
386
+ }.each do |uri,expect|
387
+ assert_equal req, @parser.headers(req.clear, str % [ uri ])
388
+ @parser.reset
389
+ assert_equal uri, req["REQUEST_URI"], "REQUEST_URI mismatch"
390
+ assert_equal expect[qs], req[qs], "#{qs} mismatch"
391
+ assert_equal expect[pi], req[pi], "#{pi} mismatch"
392
+ next if uri == "*"
393
+ uri = URI.parse("http://example.com#{uri}")
394
+ assert_equal uri.query.to_s, req[qs], "#{qs} mismatch URI.parse disagrees"
395
+ assert_equal uri.path, req[pi], "#{pi} mismatch URI.parse disagrees"
396
+ end
397
+ end
398
+
399
+ def test_path_info_semicolon_absolute
400
+ qs = "QUERY_STRING"
401
+ pi = "PATH_INFO"
402
+ req = {}
403
+ str = "GET http://example.com%s HTTP/1.1\r\nHost: www.example.com\r\n\r\n"
404
+ {
405
+ "/1;a=b?c=d&e=f" => { qs => "c=d&e=f", pi => "/1;a=b" },
406
+ "/1?c=d&e=f" => { qs => "c=d&e=f", pi => "/1" },
407
+ "/1;a=b" => { qs => "", pi => "/1;a=b" },
408
+ "/1;a=b?" => { qs => "", pi => "/1;a=b" },
409
+ "/1?a=b;c=d&e=f" => { qs => "a=b;c=d&e=f", pi => "/1" },
410
+ }.each do |uri,expect|
411
+ assert_equal req, @parser.headers(req.clear, str % [ uri ])
412
+ @parser.reset
413
+ assert_equal uri, req["REQUEST_URI"], "REQUEST_URI mismatch"
414
+ assert_equal "example.com", req["HTTP_HOST"], "Host: mismatch"
415
+ assert_equal expect[qs], req[qs], "#{qs} mismatch"
416
+ assert_equal expect[pi], req[pi], "#{pi} mismatch"
417
+ end
418
+ end
419
+
374
420
  end
@@ -49,5 +49,5 @@ Gem::Specification.new do |s|
49
49
  # *strongly* recommended for security reasons.
50
50
  s.add_dependency(%q<rack>)
51
51
 
52
- # s.licenses = %w(GPLv2 Ruby) # licenses= method is not in older Rubygems
52
+ # s.licenses = %w(GPLv2 Ruby) # licenses= method is not in older RubyGems
53
53
  end
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.95.1
4
+ version: 0.95.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Unicorn hackers
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-21 00:00:00 -08:00
12
+ date: 2009-12-07 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,7 +23,7 @@ dependencies:
23
23
  version: "0"
24
24
  version:
25
25
  description: |-
26
- Unicorn is a HTTP server for Rack applications designed to only serve
26
+ Unicorn is an HTTP server for Rack applications designed to only serve
27
27
  fast clients on low-latency, high-bandwidth connections and take
28
28
  advantage of features in Unix/Unix-like kernels. Slow clients should
29
29
  only be served by placing a reverse proxy capable of fully buffering
@@ -63,6 +63,7 @@ extra_rdoc_files:
63
63
  - lib/unicorn/tee_input.rb
64
64
  - lib/unicorn/util.rb
65
65
  - ext/unicorn_http/unicorn_http.c
66
+ - ISSUES
66
67
  files:
67
68
  - .CHANGELOG.old
68
69
  - .document
@@ -82,6 +83,7 @@ files:
82
83
  - GIT-VERSION-GEN
83
84
  - GNUmakefile
84
85
  - HACKING
86
+ - ISSUES
85
87
  - KNOWN_ISSUES
86
88
  - LICENSE
87
89
  - NEWS
@@ -96,6 +98,8 @@ files:
96
98
  - examples/echo.ru
97
99
  - examples/git.ru
98
100
  - examples/init.sh
101
+ - examples/nginx.conf
102
+ - examples/unicorn.conf.rb
99
103
  - ext/unicorn_http/c_util.h
100
104
  - ext/unicorn_http/common_field_optimization.h
101
105
  - ext/unicorn_http/ext_help.h