unicorn 0.95.2 → 0.95.3

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.
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.95.2.GIT
4
+ DEF_VER=v0.95.3.GIT
5
5
 
6
6
  LF='
7
7
  '
@@ -1,21 +1,28 @@
1
1
  # use GNU Make to run tests in parallel, and without depending on RubyGems
2
2
  all:: test
3
+
3
4
  ruby = ruby
4
5
  rake = rake
5
6
  ragel = ragel
7
+
6
8
  GIT_URL = git://git.bogomips.org/unicorn.git
7
9
  RLFLAGS = -G2
8
10
 
11
+ # lower-case vars are deprecated
12
+ RUBY = $(ruby)
13
+ RAKE = $(rake)
14
+ RAGEL = $(ragel)
15
+
9
16
  GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
10
17
  @./GIT-VERSION-GEN
11
18
  -include GIT-VERSION-FILE
12
19
  -include local.mk
13
- ruby_bin := $(shell which $(ruby))
20
+ ruby_bin := $(shell which $(RUBY))
14
21
  ifeq ($(DLEXT),) # "so" for Linux
15
- DLEXT := $(shell $(ruby) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
22
+ DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
16
23
  endif
17
24
  ifeq ($(RUBY_VERSION),)
18
- RUBY_VERSION := $(shell $(ruby) -e 'puts RUBY_VERSION')
25
+ RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
19
26
  endif
20
27
 
21
28
  # 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
45
52
 
46
53
  ragel: $(ext)/unicorn_http.c
47
54
  $(ext)/unicorn_http.c: $(rl_files)
48
- cd $(@D) && $(ragel) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
55
+ cd $(@D) && $(RAGEL) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
49
56
  $(ext)/Makefile: $(ext)/extconf.rb $(c_files)
50
- cd $(@D) && $(ruby) extconf.rb
57
+ cd $(@D) && $(RUBY) extconf.rb
51
58
  $(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile
52
59
  $(MAKE) -C $(@D)
53
60
  lib/unicorn_http.$(DLEXT): $(ext)/unicorn_http.$(DLEXT)
@@ -65,11 +72,11 @@ $(test_prefix)/.stamp: $(inst_deps)
65
72
 
66
73
  # this is only intended to be run within $(test_prefix)
67
74
  shebang: $(bins)
68
- $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
75
+ $(RUBY) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
69
76
 
70
77
  t_log := $(T_log) $(T_n_log)
71
78
  test: $(T) $(T_n)
72
- @cat $(t_log) | $(ruby) test/aggregate.rb
79
+ @cat $(t_log) | $(RUBY) test/aggregate.rb
73
80
  @$(RM) $(t_log)
74
81
 
75
82
  test-exec: $(wildcard test/exec/test_*.rb)
@@ -87,18 +94,18 @@ else
87
94
  # so we use a stamp file to indicate success and
88
95
  # have rm fail if the stamp didn't get created
89
96
  stamp = $@$(log_suffix).ok
90
- quiet_pre = @echo $(ruby) $(arg) $(TEST_OPTS); ! test -f $(stamp) && (
97
+ quiet_pre = @echo $(RUBY) $(arg) $(TEST_OPTS); ! test -f $(stamp) && (
91
98
  quiet_post = && > $(stamp) )2>&1 | tee $(t); \
92
99
  rm $(stamp) 2>/dev/null && $(check_test)
93
100
  endif
94
101
 
95
102
  # not all systems have setsid(8), we need it because we spam signals
96
103
  # stupidly in some tests...
97
- rb_setsid := $(ruby) -e 'Process.setsid' -e 'exec *ARGV'
104
+ rb_setsid := $(RUBY) -e 'Process.setsid' -e 'exec *ARGV'
98
105
 
99
106
  # TRACER='strace -f -o $(t).strace -s 100000'
100
107
  run_test = $(quiet_pre) \
101
- $(rb_setsid) $(TRACER) $(ruby) -w $(arg) $(TEST_OPTS) $(quiet_post) || \
108
+ $(rb_setsid) $(TRACER) $(RUBY) -w $(arg) $(TEST_OPTS) $(quiet_post) || \
102
109
  (sed "s,^,$(extra): ," >&2 < $(t); exit 1)
103
110
 
104
111
  %.n: arg = $(subst .n,,$(subst --, -n ,$@))
@@ -121,7 +128,7 @@ install: $(bins) $(ext)/unicorn_http.c
121
128
  $(RM) -r .install-tmp
122
129
  mkdir .install-tmp
123
130
  cp -p bin/* .install-tmp
124
- $(ruby) setup.rb all
131
+ $(RUBY) setup.rb all
125
132
  $(RM) $^
126
133
  mv .install-tmp/* bin/
127
134
  $(RM) -r .install-tmp
@@ -153,7 +160,7 @@ manifest: $(pkg_extra) man
153
160
  $(RM) $@+
154
161
 
155
162
  NEWS: GIT-VERSION-FILE
156
- $(rake) -s news_rdoc > $@+
163
+ $(RAKE) -s news_rdoc > $@+
157
164
  mv $@+ $@
158
165
 
159
166
  SINCE = 0.94.0
@@ -175,6 +182,7 @@ atom = <link rel="alternate" title="Atom feed" href="$(1)" \
175
182
  # using rdoc 2.4.1+
176
183
  doc: .document $(ext)/unicorn_http.c NEWS ChangeLog
177
184
  for i in $(man1_bins); do > $$i; done
185
+ find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';'
178
186
  rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)"
179
187
  install -m644 COPYING doc/COPYING
180
188
  install -m644 $(shell grep '^[A-Z]' .document) doc/
@@ -183,13 +191,13 @@ doc: .document $(ext)/unicorn_http.c NEWS ChangeLog
183
191
  cd doc && for i in $(base_bins); do \
184
192
  sed -e '/"documentation">/r man1/'$$i'.1.html' \
185
193
  < $${i}_1.html > tmp && mv tmp $${i}_1.html; done
186
- $(ruby) -i -p -e \
194
+ $(RUBY) -i -p -e \
187
195
  '$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \
188
196
  doc/ChangeLog.html
189
- $(ruby) -i -p -e \
197
+ $(RUBY) -i -p -e \
190
198
  '$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \
191
199
  doc/NEWS.html doc/README.html
192
- $(rake) -s news_atom > doc/NEWS.atom.xml
200
+ $(RAKE) -s news_atom > doc/NEWS.atom.xml
193
201
  cd doc && ln README.html tmp && mv tmp index.html
194
202
  $(RM) $(man1_bins)
195
203
 
@@ -223,10 +231,10 @@ release_changes := release_changes-$(VERSION)
223
231
  release-notes: $(release_notes)
224
232
  release-changes: $(release_changes)
225
233
  $(release_changes):
226
- $(rake) -s release_changes > $@+
234
+ $(RAKE) -s release_changes > $@+
227
235
  $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
228
236
  $(release_notes):
229
- GIT_URL=$(GIT_URL) $(rake) -s release_notes > $@+
237
+ GIT_URL=$(GIT_URL) $(RAKE) -s release_notes > $@+
230
238
  $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
231
239
 
232
240
  # ensures we're actually on the tagged $(VERSION), only used for release
data/Rakefile CHANGED
@@ -146,6 +146,35 @@ task :raa_update do
146
146
  puts res.body
147
147
  end
148
148
 
149
+ desc "post to FM"
150
+ task :fm_update do
151
+ require 'tempfile'
152
+ require 'net/http'
153
+ require 'net/netrc'
154
+ require 'json'
155
+ version = ENV['VERSION'] or abort "VERSION= needed"
156
+ uri = URI.parse('http://freshmeat.net/projects/unicorn/releases.json')
157
+ rc = Net::Netrc.locate('unicorn-fm') or abort "~/.netrc not found"
158
+ api_token = rc.password
159
+ changelog = tags.find { |t| t[:tag] == "v#{version}" }[:body]
160
+ tmp = Tempfile.new('fm-changelog')
161
+ tmp.syswrite(changelog)
162
+ system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?"
163
+ changelog = File.read(tmp.path).strip
164
+
165
+ req = {
166
+ "auth_code" => api_token,
167
+ "release" => {
168
+ "tag_list" => "Stable",
169
+ "version" => version,
170
+ "changelog" => changelog,
171
+ },
172
+ }.to_json
173
+ Net::HTTP.start(uri.host, uri.port) do |http|
174
+ p http.post(uri.path, req, {'Content-Type'=>'application/json'})
175
+ end
176
+ end
177
+
149
178
  # optional rake-compiler support in case somebody needs to cross compile
150
179
  begin
151
180
  require 'rubygems'
@@ -28,6 +28,7 @@
28
28
  scheme = ( "http"i ("s"i)? ) $downcase_char >mark %scheme;
29
29
  hostname = (alnum | "-" | "." | "_")+;
30
30
  host_with_port = (hostname (":" digit*)?) >mark %host;
31
+ userinfo = ((unreserved | escape | ";" | ":" | "&" | "=" | "+")+ "@")*;
31
32
 
32
33
  path = ( pchar+ ( "/" pchar* )* ) ;
33
34
  query = ( uchar | reserved )* %query_string ;
@@ -36,7 +37,7 @@
36
37
  rel_path = (path? (";" params)? %request_path) ("?" %start_query query)?;
37
38
  absolute_path = ( "/"+ rel_path );
38
39
  path_uri = absolute_path > mark %request_uri;
39
- Absolute_URI = (scheme "://" host_with_port path_uri);
40
+ Absolute_URI = (scheme "://" userinfo host_with_port path_uri);
40
41
 
41
42
  Request_URI = ((absolute_path | "*") >mark %request_uri) | Absolute_URI;
42
43
  Fragment = ( uchar | reserved )* >mark %fragment;
@@ -249,9 +249,6 @@ module Unicorn
249
249
  def stdout_path=(path); redirect_io($stdout, path); end
250
250
  def stderr_path=(path); redirect_io($stderr, path); end
251
251
 
252
- alias_method :set_pid, :pid=
253
- undef_method :pid=
254
-
255
252
  # sets the path for the PID file of the master process
256
253
  def pid=(path)
257
254
  if path
@@ -274,7 +271,7 @@ module Unicorn
274
271
  File.rename(fp.path, path)
275
272
  fp.close
276
273
  end
277
- self.set_pid(path)
274
+ super(path)
278
275
  end
279
276
 
280
277
  # add a given address to the +listeners+ set, idempotently
@@ -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.2"
10
+ UNICORN_VERSION="0.95.3"
11
11
 
12
12
  DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
13
13
  DEFAULT_PORT = 8080 # default TCP listen port
@@ -3,15 +3,20 @@
3
3
  module Unicorn
4
4
 
5
5
  # acts like tee(1) on an input input to provide a input-like stream
6
- # while providing rewindable semantics through a File/StringIO
7
- # backing store. On the first pass, the input is only read on demand
8
- # so your Rack application can use input notification (upload progress
9
- # and like). This should fully conform to the Rack::InputWrapper
6
+ # while providing rewindable semantics through a File/StringIO backing
7
+ # store. On the first pass, the input is only read on demand so your
8
+ # Rack application can use input notification (upload progress and
9
+ # like). This should fully conform to the Rack::Lint::InputWrapper
10
10
  # specification on the public API. This class is intended to be a
11
- # strict interpretation of Rack::InputWrapper functionality and will
12
- # not support any deviations from it.
11
+ # strict interpretation of Rack::Lint::InputWrapper functionality and
12
+ # will not support any deviations from it.
13
+ #
14
+ # When processing uploads, Unicorn exposes a TeeInput object under
15
+ # "rack.input" of the Rack environment.
13
16
  class TeeInput < Struct.new(:socket, :req, :parser, :buf)
14
17
 
18
+ # Initializes a new TeeInput object. You normally do not have to call
19
+ # this unless you are writing an HTTP server.
15
20
  def initialize(*args)
16
21
  super(*args)
17
22
  @size = parser.content_length
@@ -24,10 +29,16 @@ module Unicorn
24
29
  end
25
30
  end
26
31
 
27
- # returns the size of the input. This is what the Content-Length
28
- # header value should be, and how large our input is expected to be.
29
- # For TE:chunked, this requires consuming all of the input stream
30
- # before returning since there's no other way
32
+ # :call-seq:
33
+ # ios.size => Integer
34
+ #
35
+ # Returns the size of the input. For requests with a Content-Length
36
+ # header value, this will not read data off the socket and just return
37
+ # the value of the Content-Length header as an Integer.
38
+ #
39
+ # For Transfer-Encoding:chunked requests, this requires consuming
40
+ # all of the input stream before returning since there's no other
41
+ # way to determine the size of the request body beforehand.
31
42
  def size
32
43
  @size and return @size
33
44
 
@@ -41,8 +52,7 @@ module Unicorn
41
52
  @size = @tmp.size
42
53
  end
43
54
 
44
- # call-seq:
45
- # ios = env['rack.input']
55
+ # :call-seq:
46
56
  # ios.read([length [, buffer ]]) => string, buffer, or nil
47
57
  #
48
58
  # Reads at most length bytes from the I/O stream, or to the end of
@@ -82,7 +92,15 @@ module Unicorn
82
92
  end
83
93
  end
84
94
 
85
- # takes zero arguments for strict Rack::Lint compatibility, unlike IO#gets
95
+ # :call-seq:
96
+ # ios.gets => string or nil
97
+ #
98
+ # Reads the next ``line'' from the I/O stream; lines are separated
99
+ # by the global record separator ($/, typically "\n"). A global
100
+ # record separator of nil reads the entire unread contents of ios.
101
+ # Returns nil if called at the end of file.
102
+ # This takes zero arguments for strict Rack::Lint compatibility,
103
+ # unlike IO#gets.
86
104
  def gets
87
105
  socket or return @tmp.gets
88
106
  nil == $/ and return read
@@ -109,6 +127,11 @@ module Unicorn
109
127
  line
110
128
  end
111
129
 
130
+ # :call-seq:
131
+ # ios.each { |line| block } => ios
132
+ #
133
+ # Executes the block for every ``line'' in *ios*, where lines are
134
+ # separated by the global record separator ($/, typically "\n").
112
135
  def each(&block)
113
136
  while line = gets
114
137
  yield line
@@ -117,6 +140,12 @@ module Unicorn
117
140
  self # Rack does not specify what the return value is here
118
141
  end
119
142
 
143
+ # :call-seq:
144
+ # ios.rewind => 0
145
+ #
146
+ # Positions the *ios* pointer to the beginning of input, returns
147
+ # the offset (zero) of the +ios+ pointer. Subsequent reads will
148
+ # start from the beginning of the previously-buffered input.
120
149
  def rewind
121
150
  @tmp.rewind # Rack does not specify what the return value is here
122
151
  end
@@ -11,12 +11,12 @@ gems := rack-1.0.1
11
11
  # fork+exec heavy with Ruby.
12
12
  prefix = $(HOME)
13
13
  ifeq ($(r19),)
14
- ruby := $(prefix)/bin/ruby
14
+ RUBY := $(prefix)/bin/ruby
15
15
  gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.8/gems/,$(gems))
16
16
  else
17
17
  prefix := $(prefix)/ruby-1.9
18
18
  export PATH := $(prefix)/bin:$(PATH)
19
- ruby := $(prefix)/bin/ruby --disable-gems
19
+ RUBY := $(prefix)/bin/ruby --disable-gems
20
20
  gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.9.1/gems/,$(gems))
21
21
  endif
22
22
 
@@ -298,6 +298,45 @@ class HttpParserTest < Test::Unit::TestCase
298
298
  assert ! parser.keepalive?
299
299
  end
300
300
 
301
+ # some dumb clients add users because they're stupid
302
+ def test_absolute_uri_w_user
303
+ parser = HttpParser.new
304
+ req = {}
305
+ http = "GET http://user%20space@example.com/foo?q=bar HTTP/1.0\r\n\r\n"
306
+ assert_equal req, parser.headers(req, http)
307
+ assert_equal 'http', req['rack.url_scheme']
308
+ assert_equal '/foo?q=bar', req['REQUEST_URI']
309
+ assert_equal '/foo', req['REQUEST_PATH']
310
+ assert_equal 'q=bar', req['QUERY_STRING']
311
+
312
+ assert_equal 'example.com', req['HTTP_HOST']
313
+ assert_equal 'example.com', req['SERVER_NAME']
314
+ assert_equal '80', req['SERVER_PORT']
315
+ assert_equal "", http
316
+ assert ! parser.keepalive?
317
+ end
318
+
319
+ # since Mongrel supported anything URI.parse supported, we're stuck
320
+ # supporting everything URI.parse supports
321
+ def test_absolute_uri_uri_parse
322
+ "#{URI::REGEXP::PATTERN::UNRESERVED};:&=+$,".split(//).each do |char|
323
+ parser = HttpParser.new
324
+ req = {}
325
+ http = "GET http://#{char}@example.com/ HTTP/1.0\r\n\r\n"
326
+ assert_equal req, parser.headers(req, http)
327
+ assert_equal 'http', req['rack.url_scheme']
328
+ assert_equal '/', req['REQUEST_URI']
329
+ assert_equal '/', req['REQUEST_PATH']
330
+ assert_equal '', req['QUERY_STRING']
331
+
332
+ assert_equal 'example.com', req['HTTP_HOST']
333
+ assert_equal 'example.com', req['SERVER_NAME']
334
+ assert_equal '80', req['SERVER_PORT']
335
+ assert_equal "", http
336
+ assert ! parser.keepalive?
337
+ end
338
+ end
339
+
301
340
  def test_absolute_uri
302
341
  parser = HttpParser.new
303
342
  req = {}
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.2
4
+ version: 0.95.3
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-12-07 00:00:00 +00:00
12
+ date: 2009-12-21 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency