diff options
-rw-r--r-- | Documentation/unicorn.1.txt | 11 | ||||
-rw-r--r-- | Documentation/unicorn_rails.1.txt | 10 | ||||
-rwxr-xr-x | GIT-VERSION-GEN | 2 | ||||
-rw-r--r-- | GNUmakefile | 44 | ||||
-rwxr-xr-x | bin/unicorn | 4 | ||||
-rwxr-xr-x | bin/unicorn_rails | 4 | ||||
-rw-r--r-- | ext/unicorn_http/unicorn_http_common.rl | 3 | ||||
-rw-r--r-- | lib/unicorn.rb | 17 | ||||
-rw-r--r-- | lib/unicorn/const.rb | 2 | ||||
-rw-r--r-- | lib/unicorn/launcher.rb | 38 | ||||
-rw-r--r-- | lib/unicorn/tee_input.rb | 55 | ||||
-rw-r--r-- | local.mk.sample | 4 | ||||
-rw-r--r-- | test/exec/test_exec.rb | 2 | ||||
-rw-r--r-- | test/rails/app-2.3.5/.gitignore (renamed from test/rails/app-2.3.3.1/.gitignore) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/Rakefile (renamed from test/rails/app-2.3.3.1/Rakefile) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/app/controllers/application_controller.rb (renamed from test/rails/app-2.3.3.1/app/controllers/application_controller.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/app/controllers/foo_controller.rb (renamed from test/rails/app-2.3.3.1/app/controllers/foo_controller.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/app/helpers/application_helper.rb (renamed from test/rails/app-2.3.3.1/app/helpers/application_helper.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/boot.rb (renamed from test/rails/app-2.3.3.1/config/boot.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/database.yml (renamed from test/rails/app-2.3.3.1/config/database.yml) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/environment.rb (renamed from test/rails/app-2.3.3.1/config/environment.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/environments/development.rb (renamed from test/rails/app-2.3.3.1/config/environments/development.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/environments/production.rb (renamed from test/rails/app-2.3.3.1/config/environments/production.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/config/routes.rb (renamed from test/rails/app-2.3.3.1/config/routes.rb) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/db/.gitignore (renamed from test/rails/app-2.3.3.1/db/.gitignore) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/log/.gitignore (renamed from test/rails/app-2.3.3.1/log/.gitignore) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/public/404.html (renamed from test/rails/app-2.3.3.1/public/404.html) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/public/500.html (renamed from test/rails/app-2.3.3.1/public/500.html) | 0 | ||||
-rw-r--r-- | test/rails/app-2.3.5/public/x.txt (renamed from test/rails/app-2.3.3.1/public/x.txt) | 0 | ||||
-rw-r--r-- | test/unit/test_http_parser.rb | 39 |
30 files changed, 174 insertions, 61 deletions
diff --git a/Documentation/unicorn.1.txt b/Documentation/unicorn.1.txt index 7077690..e05a916 100644 --- a/Documentation/unicorn.1.txt +++ b/Documentation/unicorn.1.txt @@ -13,8 +13,8 @@ unicorn [-c CONFIG_FILE] [-E RACK_ENV] [-D] [RACKUP_FILE] # DESCRIPTION A rackup(1)-like command to launch Rack applications using Unicorn. -It is expected to be started in your application root (APP_ROOT), but -"Dir.chdir" may also be executed in the CONFIG_FILE or RACKUP_FILE. +It is expected to be started in your application root (APP_ROOT), +but the "working_directory" directive may be used in the CONFIG_FILE. While Unicorn takes a myriad of command-line options for compatibility with ruby(1) and rackup(1), it is recommended to stick @@ -33,10 +33,9 @@ with rackup(1) but strongly discouraged. # UNICORN OPTIONS -c, \--config-file CONFIG_FILE : Path to the Unicorn-specific config file. The config file is - implemented as a Ruby DSL, so Ruby code may executed (e.g. - "Dir.chdir", "Process::UID.change_privilege"). See the RDoc/ri - for the *Unicorn::Configurator* class for the full list of - directives available from the DSL. + implemented as a Ruby DSL, so Ruby code may executed. + See the RDoc/ri for the *Unicorn::Configurator* class for the full + list of directives available from the DSL. -D, \--daemonize : Run daemonized in the background. The process is detached from diff --git a/Documentation/unicorn_rails.1.txt b/Documentation/unicorn_rails.1.txt index 5ffb4b4..d2d8190 100644 --- a/Documentation/unicorn_rails.1.txt +++ b/Documentation/unicorn_rails.1.txt @@ -14,8 +14,7 @@ unicorn_rails [-c CONFIG_FILE] [-E RAILS_ENV] [-D] [RACKUP_FILE] A rackup(1)-like command to launch Rails applications using Unicorn. It is expected to be started in your Rails application root (RAILS_ROOT), -but "Dir.chdir" may also be executed in the CONFIG_FILE or -optionally, RACKUP_FILE. +but the "working_directory" directive may be used in the CONFIG_FILE. The outward interface resembles rackup(1), the internals and default middleware loading is designed like the `script/server` command @@ -29,10 +28,9 @@ as much as possible. # UNICORN OPTIONS -c, \--config-file CONFIG_FILE : Path to the Unicorn-specific config file. The config file is - implemented as a Ruby DSL, so Ruby code may executed (e.g. - "Dir.chdir", "Process::UID.change_privilege"). See the RDoc/ri - for the *Unicorn::Configurator* class for the full list of - directives available from the DSL. + implemented as a Ruby DSL, so Ruby code may executed. + See the RDoc/ri for the *Unicorn::Configurator* class for the + full list of directives available from the DSL. -D, \--daemonize : Run daemonized in the background. The process is detached from diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 4822e1c..605d9e9 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v0.95.2.GIT +DEF_VER=v0.95.3.GIT LF=' ' diff --git a/GNUmakefile b/GNUmakefile index bd2e0a5..976d728 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,21 +1,28 @@ # use GNU Make to run tests in parallel, and without depending on RubyGems all:: test + ruby = ruby rake = rake ragel = ragel + GIT_URL = git://git.bogomips.org/unicorn.git RLFLAGS = -G2 +# lower-case vars are deprecated +RUBY = $(ruby) +RAKE = $(rake) +RAGEL = $(ragel) + GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE @./GIT-VERSION-GEN -include GIT-VERSION-FILE -include local.mk -ruby_bin := $(shell which $(ruby)) +ruby_bin := $(shell which $(RUBY)) ifeq ($(DLEXT),) # "so" for Linux - DLEXT := $(shell $(ruby) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]') + DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]') endif ifeq ($(RUBY_VERSION),) - RUBY_VERSION := $(shell $(ruby) -e 'puts RUBY_VERSION') + RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION') endif # dunno how to implement this as concisely in Ruby, and hell, I love awk @@ -45,9 +52,9 @@ inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb ragel: $(ext)/unicorn_http.c $(ext)/unicorn_http.c: $(rl_files) - cd $(@D) && $(ragel) unicorn_http.rl -C $(RLFLAGS) -o $(@F) + cd $(@D) && $(RAGEL) unicorn_http.rl -C $(RLFLAGS) -o $(@F) $(ext)/Makefile: $(ext)/extconf.rb $(c_files) - cd $(@D) && $(ruby) extconf.rb + cd $(@D) && $(RUBY) extconf.rb $(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile $(MAKE) -C $(@D) lib/unicorn_http.$(DLEXT): $(ext)/unicorn_http.$(DLEXT) @@ -65,11 +72,11 @@ $(test_prefix)/.stamp: $(inst_deps) # this is only intended to be run within $(test_prefix) shebang: $(bins) - $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^ + $(RUBY) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^ t_log := $(T_log) $(T_n_log) test: $(T) $(T_n) - @cat $(t_log) | $(ruby) test/aggregate.rb + @cat $(t_log) | $(RUBY) test/aggregate.rb @$(RM) $(t_log) test-exec: $(wildcard test/exec/test_*.rb) @@ -87,18 +94,18 @@ else # so we use a stamp file to indicate success and # have rm fail if the stamp didn't get created stamp = $@$(log_suffix).ok - quiet_pre = @echo $(ruby) $(arg) $(TEST_OPTS); ! test -f $(stamp) && ( + quiet_pre = @echo $(RUBY) $(arg) $(TEST_OPTS); ! test -f $(stamp) && ( quiet_post = && > $(stamp) )2>&1 | tee $(t); \ rm $(stamp) 2>/dev/null && $(check_test) endif # not all systems have setsid(8), we need it because we spam signals # stupidly in some tests... -rb_setsid := $(ruby) -e 'Process.setsid' -e 'exec *ARGV' +rb_setsid := $(RUBY) -e 'Process.setsid' -e 'exec *ARGV' # TRACER='strace -f -o $(t).strace -s 100000' run_test = $(quiet_pre) \ - $(rb_setsid) $(TRACER) $(ruby) -w $(arg) $(TEST_OPTS) $(quiet_post) || \ + $(rb_setsid) $(TRACER) $(RUBY) -w $(arg) $(TEST_OPTS) $(quiet_post) || \ (sed "s,^,$(extra): ," >&2 < $(t); exit 1) %.n: arg = $(subst .n,,$(subst --, -n ,$@)) @@ -121,7 +128,7 @@ install: $(bins) $(ext)/unicorn_http.c $(RM) -r .install-tmp mkdir .install-tmp cp -p bin/* .install-tmp - $(ruby) setup.rb all + $(RUBY) setup.rb all $(RM) $^ mv .install-tmp/* bin/ $(RM) -r .install-tmp @@ -152,8 +159,8 @@ manifest: $(pkg_extra) man cmp $@+ $@ || mv $@+ $@ $(RM) $@+ -NEWS: GIT-VERSION-FILE - $(rake) -s news_rdoc > $@+ +NEWS: GIT-VERSION-FILE .manifest + $(RAKE) -s news_rdoc > $@+ mv $@+ $@ SINCE = 0.94.0 @@ -175,6 +182,7 @@ atom = <link rel="alternate" title="Atom feed" href="$(1)" \ # using rdoc 2.4.1+ doc: .document $(ext)/unicorn_http.c NEWS ChangeLog for i in $(man1_bins); do > $$i; done + find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';' rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)" install -m644 COPYING doc/COPYING install -m644 $(shell grep '^[A-Z]' .document) doc/ @@ -183,13 +191,13 @@ doc: .document $(ext)/unicorn_http.c NEWS ChangeLog cd doc && for i in $(base_bins); do \ sed -e '/"documentation">/r man1/'$$i'.1.html' \ < $${i}_1.html > tmp && mv tmp $${i}_1.html; done - $(ruby) -i -p -e \ + $(RUBY) -i -p -e \ '$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \ doc/ChangeLog.html - $(ruby) -i -p -e \ + $(RUBY) -i -p -e \ '$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \ doc/NEWS.html doc/README.html - $(rake) -s news_atom > doc/NEWS.atom.xml + $(RAKE) -s news_atom > doc/NEWS.atom.xml cd doc && ln README.html tmp && mv tmp index.html $(RM) $(man1_bins) @@ -223,10 +231,10 @@ release_changes := release_changes-$(VERSION) release-notes: $(release_notes) release-changes: $(release_changes) $(release_changes): - $(rake) -s release_changes > $@+ + $(RAKE) -s release_changes > $@+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@ $(release_notes): - GIT_URL=$(GIT_URL) $(rake) -s release_notes > $@+ + GIT_URL=$(GIT_URL) $(RAKE) -s release_notes > $@+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@ # ensures we're actually on the tagged $(VERSION), only used for release diff --git a/bin/unicorn b/bin/unicorn index 325afb3..5af021d 100755 --- a/bin/unicorn +++ b/bin/unicorn @@ -1,4 +1,4 @@ -#!/home/ew/bin/ruby +#!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby # -*- encoding: binary -*- require 'unicorn/launcher' require 'optparse' @@ -161,5 +161,5 @@ if $DEBUG }) end -Unicorn::Launcher.daemonize! if daemonize +Unicorn::Launcher.daemonize!(options) if daemonize Unicorn.run(app, options) diff --git a/bin/unicorn_rails b/bin/unicorn_rails index e46de70..b1458fc 100755 --- a/bin/unicorn_rails +++ b/bin/unicorn_rails @@ -1,4 +1,4 @@ -#!/home/ew/bin/ruby +#!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby # -*- encoding: binary -*- require 'unicorn/launcher' require 'optparse' @@ -202,6 +202,6 @@ end if daemonize options[:pid] = rails_pid - Unicorn::Launcher.daemonize! + Unicorn::Launcher.daemonize!(options) end Unicorn.run(app, options) diff --git a/ext/unicorn_http/unicorn_http_common.rl b/ext/unicorn_http/unicorn_http_common.rl index 041dfec..6fca604 100644 --- a/ext/unicorn_http/unicorn_http_common.rl +++ b/ext/unicorn_http/unicorn_http_common.rl @@ -28,6 +28,7 @@ scheme = ( "http"i ("s"i)? ) $downcase_char >mark %scheme; hostname = (alnum | "-" | "." | "_")+; host_with_port = (hostname (":" digit*)?) >mark %host; + userinfo = ((unreserved | escape | ";" | ":" | "&" | "=" | "+")+ "@")*; path = ( pchar+ ( "/" pchar* )* ) ; query = ( uchar | reserved )* %query_string ; @@ -36,7 +37,7 @@ rel_path = (path? (";" params)? %request_path) ("?" %start_query query)?; absolute_path = ( "/"+ rel_path ); path_uri = absolute_path > mark %request_uri; - Absolute_URI = (scheme "://" host_with_port path_uri); + Absolute_URI = (scheme "://" userinfo host_with_port path_uri); Request_URI = ((absolute_path | "*") >mark %request_uri) | Absolute_URI; Fragment = ( uchar | reserved )* >mark %fragment; diff --git a/lib/unicorn.rb b/lib/unicorn.rb index cf58165..7a1ef34 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -38,7 +38,7 @@ module Unicorn :before_fork, :after_fork, :before_exec, :logger, :pid, :app, :preload_app, :reexec_pid, :orig_app, :init_listeners, - :master_pid, :config) + :master_pid, :config, :ready_pipe) include ::Unicorn::SocketHelper # prevents IO objects in here from being GC-ed @@ -162,6 +162,7 @@ module Unicorn def initialize(app, options = {}) self.app = app self.reexec_pid = 0 + self.ready_pipe = options.delete(:ready_pipe) self.init_listeners = options[:listeners] ? options[:listeners].dup : [] self.config = Configurator.new(options.merge(:use_defaults => true)) self.listener_opts = {} @@ -310,6 +311,9 @@ module Unicorn "(#{tries < 0 ? 'infinite' : tries} tries left)" sleep(delay) retry + rescue => err + logger.fatal "error adding listener addr=#{address}" + raise err end end @@ -328,6 +332,11 @@ module Unicorn trap(:CHLD) { |sig_nr| awaken_master } proc_name 'master' logger.info "master process ready" # test_exec.rb relies on this message + if ready_pipe + ready_pipe.syswrite($$.to_s) + ready_pipe.close rescue nil + self.ready_pipe = nil + end begin loop do reap_all_workers @@ -532,7 +541,11 @@ module Unicorn WORKERS.values.include?(worker_nr) and next worker = Worker.new(worker_nr, Unicorn::Util.tmpio) before_fork.call(self, worker) - WORKERS[fork { worker_loop(worker) }] = worker + WORKERS[fork { + ready_pipe.close if ready_pipe + self.ready_pipe = nil + worker_loop(worker) + }] = worker end end diff --git a/lib/unicorn/const.rb b/lib/unicorn/const.rb index 81f61c8..f70502e 100644 --- a/lib/unicorn/const.rb +++ b/lib/unicorn/const.rb @@ -7,7 +7,7 @@ module Unicorn # gave about a 3% to 10% performance improvement over using the strings directly. # Symbols did not really improve things much compared to constants. module Const - UNICORN_VERSION="0.95.2" + UNICORN_VERSION="0.95.3" DEFAULT_HOST = "0.0.0.0" # default TCP listen host address DEFAULT_PORT = 8080 # default TCP listen port diff --git a/lib/unicorn/launcher.rb b/lib/unicorn/launcher.rb index 1229b84..e71f93b 100644 --- a/lib/unicorn/launcher.rb +++ b/lib/unicorn/launcher.rb @@ -1,6 +1,6 @@ # -*- encoding: binary -*- -$stdin.sync = $stdout.sync = $stderr.sync = true +$stdout.sync = $stderr.sync = true $stdin.binmode $stdout.binmode $stderr.binmode @@ -19,21 +19,47 @@ class Unicorn::Launcher # the directory it was started in when being re-executed # to pickup code changes if the original deployment directory # is a symlink or otherwise got replaced. - def self.daemonize! + def self.daemonize!(options = nil) $stdin.reopen("/dev/null") # We only start a new process group if we're not being reexecuted # and inheriting file descriptors from our parent unless ENV['UNICORN_FD'] - exit if fork - Process.setsid - exit if fork + if options + # grandparent - reads pipe, exits when master is ready + # \_ parent - exits immediately ASAP + # \_ unicorn master - writes to pipe when ready + rd, wr = IO.pipe + grandparent = $$ + if fork + wr.close # grandparent does not write + else + rd.close # unicorn master does not read + Process.setsid + exit if fork # parent dies now + end + + if grandparent == $$ + # this will block until HttpServer#join runs (or it dies) + master_pid = (rd.readpartial(16) rescue nil).to_i + unless master_pid > 1 + warn "master failed to start, check stderr log for details" + exit!(1) + end + exit 0 + else # unicorn master process + options[:ready_pipe] = wr + end + else # backwards compat + exit if fork + Process.setsid + exit if fork + end # $stderr/$stderr can/will be redirected separately in the Unicorn config Unicorn::Configurator::DEFAULTS[:stderr_path] = "/dev/null" Unicorn::Configurator::DEFAULTS[:stdout_path] = "/dev/null" end - $stdin.sync = $stdout.sync = $stderr.sync = true end end diff --git a/lib/unicorn/tee_input.rb b/lib/unicorn/tee_input.rb index 0669b48..bb86c40 100644 --- a/lib/unicorn/tee_input.rb +++ b/lib/unicorn/tee_input.rb @@ -3,15 +3,20 @@ module Unicorn # acts like tee(1) on an input input to provide a input-like stream - # while providing rewindable semantics through a File/StringIO - # backing store. On the first pass, the input is only read on demand - # so your Rack application can use input notification (upload progress - # and like). This should fully conform to the Rack::InputWrapper + # while providing rewindable semantics through a File/StringIO backing + # store. On the first pass, the input is only read on demand so your + # Rack application can use input notification (upload progress and + # like). This should fully conform to the Rack::Lint::InputWrapper # specification on the public API. This class is intended to be a - # strict interpretation of Rack::InputWrapper functionality and will - # not support any deviations from it. + # strict interpretation of Rack::Lint::InputWrapper functionality and + # will not support any deviations from it. + # + # When processing uploads, Unicorn exposes a TeeInput object under + # "rack.input" of the Rack environment. class TeeInput < Struct.new(:socket, :req, :parser, :buf) + # Initializes a new TeeInput object. You normally do not have to call + # this unless you are writing an HTTP server. def initialize(*args) super(*args) @size = parser.content_length @@ -24,10 +29,16 @@ module Unicorn end end - # returns the size of the input. This is what the Content-Length - # header value should be, and how large our input is expected to be. - # For TE:chunked, this requires consuming all of the input stream - # before returning since there's no other way + # :call-seq: + # ios.size => Integer + # + # Returns the size of the input. For requests with a Content-Length + # header value, this will not read data off the socket and just return + # the value of the Content-Length header as an Integer. + # + # For Transfer-Encoding:chunked requests, this requires consuming + # all of the input stream before returning since there's no other + # way to determine the size of the request body beforehand. def size @size and return @size @@ -41,8 +52,7 @@ module Unicorn @size = @tmp.size end - # call-seq: - # ios = env['rack.input'] + # :call-seq: # ios.read([length [, buffer ]]) => string, buffer, or nil # # Reads at most length bytes from the I/O stream, or to the end of @@ -82,7 +92,15 @@ module Unicorn end end - # takes zero arguments for strict Rack::Lint compatibility, unlike IO#gets + # :call-seq: + # ios.gets => string or nil + # + # Reads the next ``line'' from the I/O stream; lines are separated + # by the global record separator ($/, typically "\n"). A global + # record separator of nil reads the entire unread contents of ios. + # Returns nil if called at the end of file. + # This takes zero arguments for strict Rack::Lint compatibility, + # unlike IO#gets. def gets socket or return @tmp.gets nil == $/ and return read @@ -109,6 +127,11 @@ module Unicorn line end + # :call-seq: + # ios.each { |line| block } => ios + # + # Executes the block for every ``line'' in *ios*, where lines are + # separated by the global record separator ($/, typically "\n"). def each(&block) while line = gets yield line @@ -117,6 +140,12 @@ module Unicorn self # Rack does not specify what the return value is here end + # :call-seq: + # ios.rewind => 0 + # + # Positions the *ios* pointer to the beginning of input, returns + # the offset (zero) of the +ios+ pointer. Subsequent reads will + # start from the beginning of the previously-buffered input. def rewind @tmp.rewind # Rack does not specify what the return value is here end diff --git a/local.mk.sample b/local.mk.sample index 2b331fc..5019576 100644 --- a/local.mk.sample +++ b/local.mk.sample @@ -11,12 +11,12 @@ gems := rack-1.1.0 # fork+exec heavy with Ruby. prefix = $(HOME) ifeq ($(r19),) - ruby := $(prefix)/bin/ruby + RUBY := $(prefix)/bin/ruby gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.8/gems/,$(gems)) else prefix := $(prefix)/ruby-1.9 export PATH := $(prefix)/bin:$(PATH) - ruby := $(prefix)/bin/ruby --disable-gems + RUBY := $(prefix)/bin/ruby --disable-gems gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.9.1/gems/,$(gems)) endif diff --git a/test/exec/test_exec.rb b/test/exec/test_exec.rb index fc0719b..24ba856 100644 --- a/test/exec/test_exec.rb +++ b/test/exec/test_exec.rb @@ -805,7 +805,7 @@ EOF exec($unicorn_bin, "-D", "-l#{@addr}:#{@port}", "-c#{ucfg.path}") end pid, status = Process.waitpid2(pid) - assert status.success?, "original process exited successfully" + assert ! status.success?, "original process exited successfully" sleep 1 # can't waitpid on a daemonized process :< assert err.stat.size > 0 end diff --git a/test/rails/app-2.3.3.1/.gitignore b/test/rails/app-2.3.5/.gitignore index f451f91..f451f91 100644 --- a/test/rails/app-2.3.3.1/.gitignore +++ b/test/rails/app-2.3.5/.gitignore diff --git a/test/rails/app-2.3.3.1/Rakefile b/test/rails/app-2.3.5/Rakefile index fbebfca..fbebfca 100644 --- a/test/rails/app-2.3.3.1/Rakefile +++ b/test/rails/app-2.3.5/Rakefile diff --git a/test/rails/app-2.3.3.1/app/controllers/application_controller.rb b/test/rails/app-2.3.5/app/controllers/application_controller.rb index 07c333e..07c333e 100644 --- a/test/rails/app-2.3.3.1/app/controllers/application_controller.rb +++ b/test/rails/app-2.3.5/app/controllers/application_controller.rb diff --git a/test/rails/app-2.3.3.1/app/controllers/foo_controller.rb b/test/rails/app-2.3.5/app/controllers/foo_controller.rb index 54ca1ed..54ca1ed 100644 --- a/test/rails/app-2.3.3.1/app/controllers/foo_controller.rb +++ b/test/rails/app-2.3.5/app/controllers/foo_controller.rb diff --git a/test/rails/app-2.3.3.1/app/helpers/application_helper.rb b/test/rails/app-2.3.5/app/helpers/application_helper.rb index d9889b3..d9889b3 100644 --- a/test/rails/app-2.3.3.1/app/helpers/application_helper.rb +++ b/test/rails/app-2.3.5/app/helpers/application_helper.rb diff --git a/test/rails/app-2.3.3.1/config/boot.rb b/test/rails/app-2.3.5/config/boot.rb index b6c80d5..b6c80d5 100644 --- a/test/rails/app-2.3.3.1/config/boot.rb +++ b/test/rails/app-2.3.5/config/boot.rb diff --git a/test/rails/app-2.3.3.1/config/database.yml b/test/rails/app-2.3.5/config/database.yml index 9f77843..9f77843 100644 --- a/test/rails/app-2.3.3.1/config/database.yml +++ b/test/rails/app-2.3.5/config/database.yml diff --git a/test/rails/app-2.3.3.1/config/environment.rb b/test/rails/app-2.3.5/config/environment.rb index 6eb092c..6eb092c 100644 --- a/test/rails/app-2.3.3.1/config/environment.rb +++ b/test/rails/app-2.3.5/config/environment.rb diff --git a/test/rails/app-2.3.3.1/config/environments/development.rb b/test/rails/app-2.3.5/config/environments/development.rb index 3d381d2..3d381d2 100644 --- a/test/rails/app-2.3.3.1/config/environments/development.rb +++ b/test/rails/app-2.3.5/config/environments/development.rb diff --git a/test/rails/app-2.3.3.1/config/environments/production.rb b/test/rails/app-2.3.5/config/environments/production.rb index 08710a4..08710a4 100644 --- a/test/rails/app-2.3.3.1/config/environments/production.rb +++ b/test/rails/app-2.3.5/config/environments/production.rb diff --git a/test/rails/app-2.3.3.1/config/routes.rb b/test/rails/app-2.3.5/config/routes.rb index ac7877c..ac7877c 100644 --- a/test/rails/app-2.3.3.1/config/routes.rb +++ b/test/rails/app-2.3.5/config/routes.rb diff --git a/test/rails/app-2.3.3.1/db/.gitignore b/test/rails/app-2.3.5/db/.gitignore index e69de29..e69de29 100644 --- a/test/rails/app-2.3.3.1/db/.gitignore +++ b/test/rails/app-2.3.5/db/.gitignore diff --git a/test/rails/app-2.3.3.1/log/.gitignore b/test/rails/app-2.3.5/log/.gitignore index 397b4a7..397b4a7 100644 --- a/test/rails/app-2.3.3.1/log/.gitignore +++ b/test/rails/app-2.3.5/log/.gitignore diff --git a/test/rails/app-2.3.3.1/public/404.html b/test/rails/app-2.3.5/public/404.html index 44d986c..44d986c 100644 --- a/test/rails/app-2.3.3.1/public/404.html +++ b/test/rails/app-2.3.5/public/404.html diff --git a/test/rails/app-2.3.3.1/public/500.html b/test/rails/app-2.3.5/public/500.html index e534a49..e534a49 100644 --- a/test/rails/app-2.3.3.1/public/500.html +++ b/test/rails/app-2.3.5/public/500.html diff --git a/test/rails/app-2.3.3.1/public/x.txt b/test/rails/app-2.3.5/public/x.txt index e427984..e427984 100644 --- a/test/rails/app-2.3.3.1/public/x.txt +++ b/test/rails/app-2.3.5/public/x.txt diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb index 1b3faaf..0443b46 100644 --- a/test/unit/test_http_parser.rb +++ b/test/unit/test_http_parser.rb @@ -298,6 +298,45 @@ class HttpParserTest < Test::Unit::TestCase assert ! parser.keepalive? end + # some dumb clients add users because they're stupid + def test_absolute_uri_w_user + parser = HttpParser.new + req = {} + http = "GET http://user%20space@example.com/foo?q=bar HTTP/1.0\r\n\r\n" + assert_equal req, parser.headers(req, http) + assert_equal 'http', req['rack.url_scheme'] + assert_equal '/foo?q=bar', req['REQUEST_URI'] + assert_equal '/foo', req['REQUEST_PATH'] + assert_equal 'q=bar', req['QUERY_STRING'] + + assert_equal 'example.com', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + assert_equal "", http + assert ! parser.keepalive? + end + + # since Mongrel supported anything URI.parse supported, we're stuck + # supporting everything URI.parse supports + def test_absolute_uri_uri_parse + "#{URI::REGEXP::PATTERN::UNRESERVED};:&=+$,".split(//).each do |char| + parser = HttpParser.new + req = {} + http = "GET http://#{char}@example.com/ HTTP/1.0\r\n\r\n" + assert_equal req, parser.headers(req, http) + assert_equal 'http', req['rack.url_scheme'] + assert_equal '/', req['REQUEST_URI'] + assert_equal '/', req['REQUEST_PATH'] + assert_equal '', req['QUERY_STRING'] + + assert_equal 'example.com', req['HTTP_HOST'] + assert_equal 'example.com', req['SERVER_NAME'] + assert_equal '80', req['SERVER_PORT'] + assert_equal "", http + assert ! parser.keepalive? + end + end + def test_absolute_uri parser = HttpParser.new req = {} |