unicorn 4.0.1 → 4.0.1.4.g406b

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,6 +20,7 @@
20
20
  pchar = (uchar | ":" | "@" | "&" | "=" | "+");
21
21
  tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
22
22
  lws = (" " | "\t");
23
+ content = ((any -- CTL) | lws);
23
24
 
24
25
  # elements
25
26
  token = (ascii -- (CTL | tspecials));
@@ -50,9 +51,9 @@
50
51
 
51
52
  field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
52
53
 
53
- field_value = any* >start_value %write_value;
54
+ field_value = content* >start_value %write_value;
54
55
 
55
- value_cont = lws+ any* >start_value %write_cont_value;
56
+ value_cont = lws+ content* >start_value %write_cont_value;
56
57
 
57
58
  message_header = ((field_name ":" lws* field_value)|value_cont) :> CRLF;
58
59
  chunk_ext_val = token*;
@@ -408,7 +408,13 @@ class Unicorn::HttpServer
408
408
  end
409
409
 
410
410
  self.reexec_pid = fork do
411
- listener_fds = LISTENERS.map { |sock| sock.fileno }
411
+ listener_fds = LISTENERS.map do |sock|
412
+ # IO#close_on_exec= will be available on any future version of
413
+ # Ruby that sets FD_CLOEXEC by default on new file descriptors
414
+ # ref: http://redmine.ruby-lang.org/issues/5041
415
+ sock.close_on_exec = false if sock.respond_to?(:close_on_exec=)
416
+ sock.fileno
417
+ end
412
418
  ENV['UNICORN_FD'] = listener_fds.join(',')
413
419
  Dir.chdir(START_CTX[:cwd])
414
420
  cmd = [ START_CTX[0] ].concat(START_CTX[:argv])
@@ -529,12 +535,17 @@ class Unicorn::HttpServer
529
535
  handle_error(client, e)
530
536
  end
531
537
 
538
+ EXIT_SIGS = [ :QUIT, :TERM, :INT ]
539
+ WORKER_QUEUE_SIGS = QUEUE_SIGS - EXIT_SIGS
540
+
532
541
  # gets rid of stuff the worker has no business keeping track of
533
542
  # to free some resources and drops all sig handlers.
534
543
  # traps for USR1, USR2, and HUP may be set in the after_fork Proc
535
544
  # by the user.
536
545
  def init_worker_process(worker)
537
- QUEUE_SIGS.each { |sig| trap(sig, nil) }
546
+ # we'll re-trap :QUIT later for graceful shutdown iff we accept clients
547
+ EXIT_SIGS.each { |sig| trap(sig) { exit!(0) } }
548
+ WORKER_QUEUE_SIGS.each { |sig| trap(sig, nil) }
538
549
  trap(:CHLD, 'DEFAULT')
539
550
  SIG_QUEUE.clear
540
551
  proc_name "worker[#{worker.nr}]"
@@ -572,7 +583,6 @@ class Unicorn::HttpServer
572
583
  # closing anything we IO.select on will raise EBADF
573
584
  trap(:USR1) { nr = -65536; SELF_PIPE[0].close rescue nil }
574
585
  trap(:QUIT) { worker = nil; LISTENERS.each { |s| s.close rescue nil }.clear }
575
- [:TERM, :INT].each { |sig| trap(sig) { exit!(0) } } # instant shutdown
576
586
  logger.info "worker=#{worker.nr} ready"
577
587
 
578
588
  begin
@@ -101,7 +101,7 @@ module Unicorn
101
101
  end
102
102
  sock.listen(opt[:backlog])
103
103
  rescue => e
104
- Unicorn.log_error(logger, message, e)
104
+ Unicorn.log_error(logger, "#{sock_name(sock)} #{opt.inspect}", e)
105
105
  end
106
106
 
107
107
  def log_buffer_sizes(sock, pfx = '')
@@ -813,6 +813,24 @@ class HttpParserTest < Test::Unit::TestCase
813
813
  assert_equal "hello\t world", parser.env["HTTP_X_SPACE"]
814
814
  end
815
815
 
816
+ def test_null_byte_header
817
+ parser = HttpParser.new
818
+ get = "GET / HTTP/1.1\r\nHost: \0\r\n\r\n"
819
+ assert_raises(HttpParserError) { parser.add_parse(get) }
820
+ end
821
+
822
+ def test_null_byte_in_middle
823
+ parser = HttpParser.new
824
+ get = "GET / HTTP/1.1\r\nHost: hello\0world\r\n\r\n"
825
+ assert_raises(HttpParserError) { parser.add_parse(get) }
826
+ end
827
+
828
+ def test_null_byte_at_end
829
+ parser = HttpParser.new
830
+ get = "GET / HTTP/1.1\r\nHost: hello\0\r\n\r\n"
831
+ assert_raises(HttpParserError) { parser.add_parse(get) }
832
+ end
833
+
816
834
  def test_empty_header
817
835
  parser = HttpParser.new
818
836
  get = "GET / HTTP/1.1\r\nHost: \r\n\r\n"
metadata CHANGED
@@ -1,13 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
5
- prerelease:
4
+ hash: 1551
5
+ prerelease: 8
6
6
  segments:
7
7
  - 4
8
8
  - 0
9
9
  - 1
10
- version: 4.0.1
10
+ - 4
11
+ - g
12
+ - 406
13
+ - b
14
+ version: 4.0.1.4.g406b
11
15
  platform: ruby
12
16
  authors:
13
17
  - Unicorn hackers
@@ -15,7 +19,7 @@ autorequire:
15
19
  bindir: bin
16
20
  cert_chain: []
17
21
 
18
- date: 2011-06-29 00:00:00 Z
22
+ date: 2011-08-03 00:00:00 Z
19
23
  dependencies:
20
24
  - !ruby/object:Gem::Dependency
21
25
  name: rack
@@ -414,12 +418,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
414
418
  required_rubygems_version: !ruby/object:Gem::Requirement
415
419
  none: false
416
420
  requirements:
417
- - - ">="
421
+ - - ">"
418
422
  - !ruby/object:Gem::Version
419
- hash: 3
423
+ hash: 25
420
424
  segments:
421
- - 0
422
- version: "0"
425
+ - 1
426
+ - 3
427
+ - 1
428
+ version: 1.3.1
423
429
  requirements: []
424
430
 
425
431
  rubyforge_project: mongrel