unicorn 0.95.2 → 0.95.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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