unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 1-4/4] various test fixes
  @ 2023-06-11 22:58  3% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2023-06-11 22:58 UTC (permalink / raw)
  To: unicorn-public

[-- Attachment #1: Type: text/plain, Size: 43 bytes --]

> Attached patches to reduce SMTP

Oops :x

[-- Attachment #2: 0001-t-lib.perl-ignore-errors-from-accept_filter-on-FreeB.patch --]
[-- Type: text/x-diff, Size: 899 bytes --]

From 8271bafb85f75b927f0ea15ec73fc0b1e714665e Mon Sep 17 00:00:00 2001
From: EW <bofh@yhbt.net>
Date: Tue, 6 Jun 2023 10:09:24 +0000
Subject: [PATCH 1/4] t/lib.perl: FreeBSD: ignore accf_* messages

Testers may not have accf_http loaded nor the permissions
to run `kldload accf_http', thus we must ignore these messages.
---
 t/lib.perl | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/t/lib.perl b/t/lib.perl
index 2685c3b4..fe3404ba 100644
--- a/t/lib.perl
+++ b/t/lib.perl
@@ -22,6 +22,8 @@ sub check_stderr () {
 	my @log = slurp("$tmpdir/err.log");
 	diag("@log") if $ENV{V};
 	my @err = grep(!/NameError.*Unicorn::Waiter/, grep(/error/i, @log));
+	@err = grep(!/failed to set accept_filter=/, @err);
+	@err = grep(!/perhaps accf_.*? needs to be loaded/, @err);
 	is_deeply(\@err, [], 'no unexpected errors in stderr');
 	is_deeply([grep(/SIGKILL/, @log)], [], 'no SIGKILL in stderr');
 }

[-- Attachment #3: 0002-t-active-unix-socket-sleep-for-init-8-to-reap-worker.patch --]
[-- Type: text/x-diff, Size: 1012 bytes --]

From a29364769d59e7bc0c67ad045af25f349ae913e8 Mon Sep 17 00:00:00 2001
From: EW <bofh@yhbt.net>
Date: Tue, 6 Jun 2023 10:09:25 +0000
Subject: [PATCH 2/4] t/active-unix-socket: sleep for init(8) to reap worker

Unfortunately, we need a sleep loop here since kill(2) succeeds
on zombies and init(8) doesn't reap the worker soon enough on
a FreeBSD VM.
---
 t/active-unix-socket.t | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/t/active-unix-socket.t b/t/active-unix-socket.t
index 4e11837a..4dcc8dc6 100644
--- a/t/active-unix-socket.t
+++ b/t/active-unix-socket.t
@@ -84,6 +84,10 @@ is($pidf, $to_kill{u1}, 'pid file contents unchanged after 2nd start failure');
 	ok(-S $u1, 'socket stayed after SIGKILL');
 	is(IO::Socket::UNIX->new(Peer => $u1, Type => SOCK_STREAM), undef,
 		'fail to connect to u1');
+	for (1..50) { # wait for init process to reap worker
+		kill(0, $worker_pid) or last;
+		select(undef, undef, undef, 0.011);
+	}
 	ok(!kill(0, $worker_pid), 'worker gone after parent dies');
 }
 

[-- Attachment #4: 0003-tests-handle-assignment-deprecation.patch --]
[-- Type: text/x-diff, Size: 4710 bytes --]

From b988e0779814a73876a4a06df0a90a3f85fb08c8 Mon Sep 17 00:00:00 2001
From: Eric Wong <bofh@yhbt.net>
Date: Tue, 6 Jun 2023 11:02:29 +0000
Subject: [PATCH 3/4] tests: handle $/ assignment deprecation

...by testing less.  `env["rack.input"].gets' users are out-of-luck
if they want anything other than "\n" or `nil', I suppose...

`$/' is non-thread-local and thus non-thread-safe, which doesn't
affect unicorn itself, but Ruby deprecates it for
single-threaded code, too, unfortunately.

Rack::Lint doesn't allow separator arguments for #gets, either,
so we can't support that, either...
---
 test/unit/test_stream_input.rb | 25 ++++++++++++++++---------
 test/unit/test_tee_input.rb    | 19 +++++++++----------
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/test/unit/test_stream_input.rb b/test/unit/test_stream_input.rb
index 1a07ec3a..2a14135b 100644
--- a/test/unit/test_stream_input.rb
+++ b/test/unit/test_stream_input.rb
@@ -6,7 +6,8 @@
 
 class TestStreamInput < Test::Unit::TestCase
   def setup
-    @rs = $/
+    @rs = "\n"
+    $/ == "\n" or abort %q{test broken if \$/ != "\\n"}
     @env = {}
     @rd, @wr = Kgio::UNIXSocket.pair
     @rd.sync = @wr.sync = true
@@ -15,7 +16,6 @@ def setup
 
   def teardown
     return if $$ != @start_pid
-    $/ = @rs
     @rd.close rescue nil
     @wr.close rescue nil
     Process.waitall
@@ -54,11 +54,18 @@ def test_gets_multiline
   end
 
   def test_gets_empty_rs
-    $/ = nil
     r = init_request("a\nb\n\n")
     si = Unicorn::StreamInput.new(@rd, r)
-    assert_equal "a\nb\n\n", si.gets
-    assert_nil si.gets
+    pid = fork do # to avoid $/ warning (hopefully)
+      $/ = nil
+      @rd.close
+      @wr.write(si.gets)
+      @wr.close
+    end
+    @wr.close
+    assert_equal "a\nb\n\n", @rd.read
+    pid, status = Process.waitpid2(pid)
+    assert_predicate status, :success?
   end
 
   def test_read_with_equal_len
@@ -90,21 +97,21 @@ def test_big_body_multi
   end
 
   def test_gets_long
-    r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
+    r = init_request("hello", 5 + (4096 * 4 * 3) + "#{@rs}foo#{@rs}".size)
     si = Unicorn::StreamInput.new(@rd, r)
     status = line = nil
     pid = fork {
       @rd.close
       3.times { @wr.write("ffff" * 4096) }
-      @wr.write "#$/foo#$/"
+      @wr.write "#{@rs}foo#{@rs}"
       @wr.close
     }
     @wr.close
     line = si.gets
     assert_equal(4096 * 4 * 3 + 5 + $/.size, line.size)
-    assert_equal("hello" << ("ffff" * 4096 * 3) << "#$/", line)
+    assert_equal("hello" << ("ffff" * 4096 * 3) << "#{@rs}", line)
     line = si.gets
-    assert_equal "foo#$/", line
+    assert_equal "foo#{@rs}", line
     assert_nil si.gets
     pid, status = Process.waitpid2(pid)
     assert status.success?
diff --git a/test/unit/test_tee_input.rb b/test/unit/test_tee_input.rb
index 4647e661..6f5bc8a7 100644
--- a/test/unit/test_tee_input.rb
+++ b/test/unit/test_tee_input.rb
@@ -9,17 +9,16 @@ class TeeInput < Unicorn::TeeInput
 end
 
 class TestTeeInput < Test::Unit::TestCase
-
   def setup
-    @rs = $/
     @rd, @wr = Kgio::UNIXSocket.pair
     @rd.sync = @wr.sync = true
     @start_pid = $$
+    @rs = "\n"
+    $/ == "\n" or abort %q{test broken if \$/ != "\\n"}
   end
 
   def teardown
     return if $$ != @start_pid
-    $/ = @rs
     @rd.close rescue nil
     @wr.close rescue nil
     begin
@@ -37,38 +36,38 @@ def check_tempfiles
   end
 
   def test_gets_long
-    r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
+    r = init_request("hello", 5 + (4096 * 4 * 3) + "#{@rs}foo#{@rs}".size)
     ti = TeeInput.new(@rd, r)
     status = line = nil
     pid = fork {
       @rd.close
       3.times { @wr.write("ffff" * 4096) }
-      @wr.write "#$/foo#$/"
+      @wr.write "#{@rs}foo#{@rs}"
       @wr.close
     }
     @wr.close
     line = ti.gets
     assert_equal(4096 * 4 * 3 + 5 + $/.size, line.size)
-    assert_equal("hello" << ("ffff" * 4096 * 3) << "#$/", line)
+    assert_equal("hello" << ("ffff" * 4096 * 3) << "#{@rs}", line)
     line = ti.gets
-    assert_equal "foo#$/", line
+    assert_equal "foo#{@rs}", line
     assert_nil ti.gets
     pid, status = Process.waitpid2(pid)
     assert status.success?
   end
 
   def test_gets_short
-    r = init_request("hello", 5 + "#$/foo".size)
+    r = init_request("hello", 5 + "#{@rs}foo".size)
     ti = TeeInput.new(@rd, r)
     status = line = nil
     pid = fork {
       @rd.close
-      @wr.write "#$/foo"
+      @wr.write "#{@rs}foo"
       @wr.close
     }
     @wr.close
     line = ti.gets
-    assert_equal("hello#$/", line)
+    assert_equal("hello#{@rs}", line)
     line = ti.gets
     assert_equal "foo", line
     assert_nil ti.gets

[-- Attachment #5: 0004-tests-ensure-t-random_blob-exists-before-Perl-tests.patch --]
[-- Type: text/x-diff, Size: 887 bytes --]

From 42028bf5b0327f7e8816ef294d215ae6bb085fc6 Mon Sep 17 00:00:00 2001
From: Eric Wong <bofh@yhbt.net>
Date: Tue, 6 Jun 2023 11:44:29 +0000
Subject: [PATCH 4/4] tests: ensure t/random_blob exists before Perl tests

Allow overriding `PROVE=' while we're at it, too; since
development installations of Perl5 may name it `prove5.$MINOR'
or similar.
---
 GNUmakefile | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index eab90829..70e7e108 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -11,6 +11,7 @@ RSYNC = rsync
 OLDDOC = olddoc
 RDOC = rdoc
 INSTALL = install
+PROVE = prove
 
 GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
 	@./GIT-VERSION-GEN
@@ -141,8 +142,8 @@ t/random_blob:
 
 test-integration: $(T_sh)
 
-test-prove:
-	prove -vw
+test-prove: t/random_blob
+	$(PROVE) -vw
 
 check: test-require test test-integration
 test-all: check

^ permalink raw reply related	[relevance 3%]

* Re: Potential Unicorn vulnerability
  2021-03-12 11:14  0%       ` Dirkjan Bussink
@ 2021-03-12 12:00  0%         ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2021-03-12 12:00 UTC (permalink / raw)
  To: Dirkjan Bussink; +Cc: John Crepezzi, Kevin Sawicki, unicorn-public

Dirkjan Bussink <dbussink@github.com> wrote:
> Hi Eric,
> 
> > On 12 Mar 2021, at 10:41, Eric Wong <normalperson@yhbt.net> wrote:
> > 
> > I'm not in favor of new options since they add support costs
> > and increase the learning/maintenance curve.
> > 
> > What I've been thinking about is bumping the major version to 6.0
> > 
> > Although our internals are technically not supported stable API,
> > there may be odd stuff out there similar to OobGC that uses
> > instance_variable_get or similar things to reach into internals.
> > Added with the fact our internals haven't changed in many years;
> > I'm inclined to believe there are other OobGC-like things out
> > there that can break.
> > 
> > Also, with 6.0; users who completely avoid Threads can keep
> > using 5.x, while others can use 6.x
> 
> That sounds like a good plan then. Once there’s a new version we can
> bump that on our side to remove the manual patch then.

OK.  I think it's safe to wait a few days for more comments
before releasing in case there's more last-minute revelations
(see below :x)

> > Btw, did you consider replacing the @request HttpRequest object
> > entirely instead of the env and buf elements?
> > I suppose that's more allocations, still; but could've
> > been a smaller change.
> 
> Ah, that’s a very good point. I think that would also have been a valid
> approach but it does indeed add more allocations. If that approach would
> be preferred, I think it can also be changed to that?
> 
> I don’t really have a strong preference on which approach to take here,
> do you?

I was going to say I didn't have a preference and the
current approach was fine...

However, I just now realized now that clobbering+replacing all
of @request is required.

That's because env['rack.input'] is (Stream|Tee)Input,
and that is lazily consumed and those objects keep state in
@request (as the historically-named @parser)

If we're to make env safe to be shipped off to another thread,
then @request still needs to stick around to maintain state
of env['rack.input'] until it's all consumed.

It probably doesn't affect most apps out there that just decode
forms via HTTP POST; but the streamed rack.input is something
that's critical for projects that feed unicorn with PUTs via
"curl -T"

> > Oops, was that the integration tests in t/* ?
> 
> Nope, looks like some platform behavior changes (tried on MacOS first).
> I was able to get the tests running and working on Debian Buster this
> morning before I sent a new version of the patch and they are all passing
> there for me locally.

Ah, no idea about MacOS or any proprietary OS; I've never
considered them supported.  But yeah, it should work on any
GNU/Linux and Free-as-in-speech *BSDs

^ permalink raw reply	[relevance 0%]

* Re: Potential Unicorn vulnerability
  2021-03-12  9:41  2%     ` Potential Unicorn vulnerability Eric Wong
@ 2021-03-12 11:14  0%       ` Dirkjan Bussink
  2021-03-12 12:00  0%         ` Eric Wong
  0 siblings, 1 reply; 30+ results
From: Dirkjan Bussink @ 2021-03-12 11:14 UTC (permalink / raw)
  To: Eric Wong; +Cc: John Crepezzi, Kevin Sawicki, unicorn-public

Hi Eric,

> On 12 Mar 2021, at 10:41, Eric Wong <normalperson@yhbt.net> wrote:
> 
> I'm not in favor of new options since they add support costs
> and increase the learning/maintenance curve.
> 
> What I've been thinking about is bumping the major version to 6.0
> 
> Although our internals are technically not supported stable API,
> there may be odd stuff out there similar to OobGC that uses
> instance_variable_get or similar things to reach into internals.
> Added with the fact our internals haven't changed in many years;
> I'm inclined to believe there are other OobGC-like things out
> there that can break.
> 
> Also, with 6.0; users who completely avoid Threads can keep
> using 5.x, while others can use 6.x

That sounds like a good plan then. Once there’s a new version we can
bump that on our side to remove the manual patch then.

> Btw, did you consider replacing the @request HttpRequest object
> entirely instead of the env and buf elements?
> I suppose that's more allocations, still; but could've
> been a smaller change.

Ah, that’s a very good point. I think that would also have been a valid
approach but it does indeed add more allocations. If that approach would
be preferred, I think it can also be changed to that?

I don’t really have a strong preference on which approach to take here,
do you? 

> Oops, was that the integration tests in t/* ?

Nope, looks like some platform behavior changes (tried on MacOS first).
I was able to get the tests running and working on Debian Buster this
morning before I sent a new version of the patch and they are all passing
there for me locally.

Cheers,

Dirkjan

^ permalink raw reply	[relevance 0%]

* Re: Potential Unicorn vulnerability
       [not found]       ` <7F6FD017-7802-4871-88A3-1E03D26D967C@github.com>
@ 2021-03-12  9:41  2%     ` Eric Wong
  2021-03-12 11:14  0%       ` Dirkjan Bussink
  0 siblings, 1 reply; 30+ results
From: Eric Wong @ 2021-03-12  9:41 UTC (permalink / raw)
  To: Dirkjan Bussink; +Cc: John Crepezzi, Kevin Sawicki, unicorn-public

[-- Attachment #1: Type: text/plain, Size: 6397 bytes --]

Dirkjan Bussink <dbussink@github.com> wrote:
> Hello Eric,
> 
> > On 11 Mar 2021, at 04:02, Eric Wong <normalperson@yhbt.net> wrote:
> > 
> > Thanks for reaching out.  Fwiw, I prefer if everything were made
> > public right away, but I'll leave it up to you if you're not
> > comfortable with it.
> > 
> > I don't know much about security, anwyays; and don't like
> > classifying bugs (or classifying anything)...
> 
> We reached out privately first out of care and to follow best practices
> around coordinated disclosure, in case you considered this a security
> vulnerability. We have no objections to moving this to the public mailing
> list. We are viewing this patch as a proactive hardening against race
> conditions more so than a vulnerability. 

OK, I'm adding unicorn-public@yhbt.net to the Cc: of this mail.

Personally, I prefer everything be reported publicly ASAP.
There's a constant threat of power/network failures from
disasters and such that could cause messages to be delayed
too long or indefinitely.

> We are also reaching out to a private Rails Security coordination channel
> that we’re a part of to raise awareness of this behavior so other Unicorn
> users in this group can look for similar issues in their code. 

OK.

> To move this discussion to the public list, would you prefer that you move
> this thread publicly, or that we resend the message or forward it to the
> public mailing list? 

Attached are the initial two (previously private) emails in this
thread, so no need to resend.  They have the correct
message/rfc822 MIME type set so they should be readable from
most MUAs and mail archives.

> > Ouch, so the hijack check we had in HttpParser_clear didn't fire...
> 
> Yes, to our understanding it only would fire if explicitly set and that
> doesn’t happen here.
> 
> >> While we understand and appreciate that Unicorn is not a multi-threaded web
> >> server, it feels like using the same `Hash` object between requests
> >> introduces the chance that a dependency like an external gem may use threads
> >> and thus potentially leak information between requests.
> > 
> > Yes, there's likely problems in trying to use threads with a
> > codebase that was only intended to be single-threaded.  And
> > using Thread.current[...] here wouldn't have made a. difference.
> 
> For us it was also the difference between “requests are handled single threaded”
> vs “you can’t use threads for anything else either.” We were totally aware of the
> first, but the latter seems more accidental and has a much broader impact. 

Agreed.

> > I worry some endpoints out there will suffer performance
> > degradation.  Expensive endpoints probably won't notice,
> > but maybe the fastest ones will...
> 
> That is a good point, but I think in practice most users do enough in most
> requests that the trade off is totally worth it. At least for us it definitely
> is. Maybe it would be an option to make the sharing somehow opt-in instead of
> default behavior? So that by default the safe behavior is used, but for those
> that want to, they can opt into the sharing if they know their app is safe
> enough to work with that. 

I'm not in favor of new options since they add support costs
and increase the learning/maintenance curve.

What I've been thinking about is bumping the major version to 6.0

Although our internals are technically not supported stable API,
there may be odd stuff out there similar to OobGC that uses
instance_variable_get or similar things to reach into internals.
Added with the fact our internals haven't changed in many years;
I'm inclined to believe there are other OobGC-like things out
there that can break.

Also, with 6.0; users who completely avoid Threads can keep
using 5.x, while others can use 6.x

> >> For the sake of transparency to our users, we plan on publishing a public
> >> post next week on how this was part of the larger series of bugs that had a
> >> security impact at GitHub. We've also attached a suggested patch that removes
> >> the environment sharing, which is what we're running right now to reduce the
> >> risk of this ever happening again.
> > 
> > Did you measure performance degradations in any endpoints you have?
> 
> We did measure and there were zero noticeable performance degradations. That’s
> also because all our requests do a bunch of work and are not direct Rack apps,
> and use stuff like Rails or Sinatra. Those all usually wrap the `env` hash
> anyway with their own per request object and there’s a lot of other allocations
> happening anyway.
> 
> In microbenchmarks we could see a difference, but even there, at least for us,
> we’d gladly pay the performance price for the safety if we’d have any endpoints
> where it would be measurable. 

OK.  Fwiw, there's still some stones left unturned that could
recover the lost speed if somebody _really_ cares for it(*)

(*) String#clear on response header buffer, swapping Ragel
    for a faster HTTP parser, ...

> All in all, I think here that a safe default would be helpful for users, as
> mentioned earlier, and that maybe for those cases where the latest performance
> bit matters, the existing behavior could be opted into. Whether this option is
> worth it from a maintenance standpoint is something you’re better able to answer
> than we are though.

It's probably OK and I'm inclined to accept your patch for 6.0.

At this point, I'm more worried about potential breakage of some
3rd-party OobGC-like thing that reaches deep into our internals.

Btw, did you consider replacing the @request HttpRequest object
entirely instead of the env and buf elements?
I suppose that's more allocations, still; but could've
been a smaller change.

> > I'll see about finding a less-noisy/overloaded system to run
> > benchmarks against...
> > 
> > I noticed some of the OobGC tests in t/ were failing (patch below),
> > but few users use the that version of OobGC.
> 
> I wasn’t easily able to run the entire suite, but only parts of it which is why
> I didn’t have a complete fix there. I can add this to the patch then.

Oops, was that the integration tests in t/* ?
They can run separately via "make test-integration"
(I never trusted some Ruby behaviors to remain stable,
 so I started writing tests in Bourne shell).

<snip> I have nothing to add to the rest of the mail

unicorn-public readers: see attachments

[-- Attachment #2: 0001-potential-unicorn-vulnerability.eml --]
[-- Type: message/rfc822, Size: 12105 bytes --]

[-- Attachment #2.1.1: Type: text/plain, Size: 2813 bytes --]

Hello Eric,

We're reaching out privately first on what we think could be classified as a
security issue in Unicorn. Since there may be other similarly impacted users,
this is out of an abundance of caution before sending it to the public
Unicorn mailing list.

The issue at hand is that the environment sharing and reuse between requests
in Unicorn, combined with other non thread safe code, resulted in a security
vulnerability where a very small number of user sessions tracked through
cookies got misrouted. For this reason, we logged everyone out of GitHub, see
also https://github.blog/2021-03-08-github-security-update-a-bug-related-to-handling-of-authenticated-sessions/. 

The unsafe background thread code we had ended up triggering an exception at
rare times and the exception tracking logic was using a deferred block
executed through a Ruby Proc to gather information, including things from the
request at the time the logic started.

That thread captured something from the cookie jar among other things, and
the following code in Rack memoized that into the (shared) environment.

From https://github.com/rack/rack/blob/2.1.4/lib/rack/request.rb#L219-L229

def cookies
  hash = fetch_header(RACK_REQUEST_COOKIE_HASH) do |k|
    set_header(k, {})
  end
  string = get_header HTTP_COOKIE

  return hash if string == get_header(RACK_REQUEST_COOKIE_STRING)
  hash.replace Utils.parse_cookies_header string
  set_header(RACK_REQUEST_COOKIE_STRING, string)
  hash
end

Because of the environment sharing, the memoization ended up overriding what
would be memoized (with the RACK_REQUEST_COOKIE_STRING key) for the new
request and because a specific session cookie was bumped then with a new
timeout on each request, the wrong session cookie was serialized.

While we understand and appreciate that Unicorn is not a multi-threaded web
server, it feels like using the same `Hash` object between requests
introduces the chance that a dependency like an external gem may use threads
and thus potentially leak information between requests.

For the sake of transparency to our users, we plan on publishing a public
post next week on how this was part of the larger series of bugs that had a
security impact at GitHub. We've also attached a suggested patch that removes
the environment sharing, which is what we're running right now to reduce the
risk of this ever happening again.

We hope you're open to collaborating on a fix prior to any public detailed
disclosure of how this request environment sharing could lead to security
issues, if you feel that is desired. 

I’ve added John & Kevin here on the CC since they’ve also worked on this and
that way we have some better timezone spread on our side if needed. 

Cheers,

Dirkjan Bussink


[-- Attachment #2.1.2: 0001-Drop-reuse-of-Ruby-level-objects.patch --]
[-- Type: application/octet-stream, Size: 4067 bytes --]

From 44aa6b056e1b24d42ab3efba738b38f4cd54a068 Mon Sep 17 00:00:00 2001
From: Dirkjan Bussink <d.bussink@gmail.com>
Date: Mon, 8 Mar 2021 09:51:09 +0100
Subject: [PATCH] Drop reuse of Ruby level objects

Remove the reuse of environment and the buffer as Ruby level objects.
Reusing these is very risky in the context of running any other threads
within the unicorn process, also for threads that run background tasks.

This lead to a significant security incident where the problems would
not have happened if there was no reuse of the `env` object. From a
safety perspective, this also removes reuse of the buffer object as it's
also a Ruby object and could be grabbed and retained outside of the http
parsing logic.

The downside here is that we allocate two extra objects on each request,
but that is worth the trade off here and the security risk we otherwise
would carry to leaking wrong and incorrect data.
---
 ext/unicorn_http/extconf.rb      |  1 -
 ext/unicorn_http/unicorn_http.rl | 30 +++---------------------------
 test/unit/test_http_parser.rb    |  3 +++
 3 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/ext/unicorn_http/extconf.rb b/ext/unicorn_http/extconf.rb
index 95514bc..7e4775c 100644
--- a/ext/unicorn_http/extconf.rb
+++ b/ext/unicorn_http/extconf.rb
@@ -10,7 +10,6 @@
 have_macro("SIZEOF_SIZE_T", "ruby.h") or check_sizeof("size_t", "sys/types.h")
 have_macro("SIZEOF_LONG", "ruby.h") or check_sizeof("long", "sys/types.h")
 have_func("rb_str_set_len", "ruby.h") or abort 'Ruby 1.9.3+ required'
-have_func("rb_hash_clear", "ruby.h") # Ruby 2.0+
 have_func("gmtime_r", "time.h")
 
 message('checking if String#-@ (str_uminus) dedupes... ')
diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
index 21e09d6..9904d85 100644
--- a/ext/unicorn_http/unicorn_http.rl
+++ b/ext/unicorn_http/unicorn_http.rl
@@ -65,18 +65,6 @@ struct http_parser {
 static ID id_set_backtrace, id_is_chunked_p;
 static VALUE cHttpParser;
 
-#ifdef HAVE_RB_HASH_CLEAR /* Ruby >= 2.0 */
-#  define my_hash_clear(h) (void)rb_hash_clear(h)
-#else /* !HAVE_RB_HASH_CLEAR - Ruby <= 1.9.3 */
-
-static ID id_clear;
-
-static void my_hash_clear(VALUE h)
-{
-  rb_funcall(h, id_clear, 0);
-}
-#endif /* HAVE_RB_HASH_CLEAR */
-
 static void finalize_header(struct http_parser *hp);
 
 static void parser_raise(VALUE klass, const char *msg)
@@ -445,6 +433,8 @@ static void http_parser_init(struct http_parser *hp)
   hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
   %% write init;
   hp->cs = cs;
+  hp->buf = rb_str_new(NULL, 0);
+  hp->env = rb_hash_new();
 }
 
 /** exec **/
@@ -628,8 +618,6 @@ static VALUE HttpParser_init(VALUE self)
   struct http_parser *hp = data_get(self);
 
   http_parser_init(hp);
-  hp->buf = rb_str_new(NULL, 0);
-  hp->env = rb_hash_new();
 
   return self;
 }
@@ -643,16 +631,7 @@ static VALUE HttpParser_init(VALUE self)
  */
 static VALUE HttpParser_clear(VALUE self)
 {
-  struct http_parser *hp = data_get(self);
-
-  /* we can't safely reuse .buf and .env if hijacked */
-  if (HP_FL_TEST(hp, HIJACK))
-    return HttpParser_init(self);
-
-  http_parser_init(hp);
-  my_hash_clear(hp->env);
-
-  return self;
+  return HttpParser_init(self);
 }
 
 static void advance_str(VALUE str, off_t nr)
@@ -1025,9 +1004,6 @@ void Init_unicorn_http(void)
   id_set_backtrace = rb_intern("set_backtrace");
   init_unicorn_httpdate();
 
-#ifndef HAVE_RB_HASH_CLEAR
-  id_clear = rb_intern("clear");
-#endif
   id_is_chunked_p = rb_intern("is_chunked?");
 }
 #undef SET_GLOBAL
diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb
index 697af44..d3f9ae7 100644
--- a/test/unit/test_http_parser.rb
+++ b/test/unit/test_http_parser.rb
@@ -33,6 +33,9 @@ def test_parse_simple
     parser.clear
     req.clear
 
+    req = parser.env
+    http = parser.buf
+
     http << "G"
     assert_nil parser.parse
     assert_equal "G", http
-- 
2.30.1


[-- Attachment #3: 0002-re-potential-unicorn-vulnerability.eml --]
[-- Type: message/rfc822, Size: 5635 bytes --]

From: Eric Wong <normalperson@yhbt.net>
To: Dirkjan Bussink <dbussink@github.com>
Cc: John Crepezzi <seejohnrun@github.com>, Kevin Sawicki <kevinsawicki@github.com>
Subject: Re: Potential Unicorn vulnerability
Date: Thu, 11 Mar 2021 03:02:50 +0000
Message-ID: <20210311030250.GA1266@dcvr>

Dirkjan Bussink <dbussink@github.com> wrote:
> Hello Eric,
> 
> We're reaching out privately first on what we think could be classified as a
> security issue in Unicorn. Since there may be other similarly impacted users,
> this is out of an abundance of caution before sending it to the public
> Unicorn mailing list.

Thanks for reaching out.  Fwiw, I prefer if everything were made
public right away, but I'll leave it up to you if you're not
comfortable with it.

I don't know much about security, anwyays; and don't like
classifying bugs (or classifying anything)...

<snip>

> That thread captured something from the cookie jar among other things, and
> the following code in Rack memoized that into the (shared) environment.

Ouch, so the hijack check we had in HttpParser_clear didn't fire...

<snip>

> While we understand and appreciate that Unicorn is not a multi-threaded web
> server, it feels like using the same `Hash` object between requests
> introduces the chance that a dependency like an external gem may use threads
> and thus potentially leak information between requests.

Yes, there's likely problems in trying to use threads with a
codebase that was only intended to be single-threaded.  And
using Thread.current[...] here wouldn't have made a. difference.

I worry some endpoints out there will suffer performance
degradation.  Expensive endpoints probably won't notice,
but maybe the fastest ones will...

`buf' is particularly worrying to me since it's a 16384-byte
allocation for a socket read on headers that could amount
to lots of GC pressure and hurt locality all around.

env['rack.input'] may also hold onto `buf', too, since
input is lazily-consumed (though it may be possible to
workaround that...).

Losing `env' is probably less worrying since keys are all
fstrings in modern Rubies.  Though losing the backing store (and
not having rb_hash_new_with_size in the C API) would mean more
rehashing with many headers.

The simple Rack apps I worked on back in-the-day which
benefitted from these object-reuse optimizations are unlikely to
be upgraded to newer versions of unicorn.  Of course, there
may be other similar Rack apps out there that depend on these...

> For the sake of transparency to our users, we plan on publishing a public
> post next week on how this was part of the larger series of bugs that had a
> security impact at GitHub. We've also attached a suggested patch that removes
> the environment sharing, which is what we're running right now to reduce the
> risk of this ever happening again.

Did you measure performance degradations in any endpoints you have?

I'll see about finding a less-noisy/overloaded system to run
benchmarks against...

I noticed some of the OobGC tests in t/ were failing (patch below),
but few users use the that version of OobGC.

Also, t/t0200-rack-hijack.sh would go away.

> We hope you're open to collaborating on a fix prior to any public detailed
> disclosure of how this request environment sharing could lead to security
> issues, if you feel that is desired. 

Sure, as long as everything is done via plain-text email so
I won't need working graphics drivers or modern hardware :>

Along the same lines, would you be OK with this entire mail thread
(including all mail headers) being eventually published in the
public mailbox at http://ou63pmih66umazou.onion/unicorn-public/
and https://yhbt.net/unicorn-public/ ?

> I’ve added John & Kevin here on the CC since they’ve also worked on this and
> that way we have some better timezone spread on our side if needed. 

OK, I'm around/awake at pretty random times.

Aforementioned OomGC change:
-------8<-------
diff --git a/lib/unicorn/oob_gc.rb b/lib/unicorn/oob_gc.rb
index 3b2f488..91a8e51 100644
--- a/lib/unicorn/oob_gc.rb
+++ b/lib/unicorn/oob_gc.rb
@@ -60,7 +60,6 @@ def self.new(app, interval = 5, path = %r{\A/})
     self.const_set :OOBGC_INTERVAL, interval
     ObjectSpace.each_object(Unicorn::HttpServer) do |s|
       s.extend(self)
-      self.const_set :OOBGC_ENV, s.instance_variable_get(:@request).env
     end
     app # pretend to be Rack middleware since it was in the past
   end
@@ -68,9 +67,10 @@ def self.new(app, interval = 5, path = %r{\A/})
   #:stopdoc:
   def process_client(client)
     super(client) # Unicorn::HttpServer#process_client
-    if OOBGC_PATH =~ OOBGC_ENV['PATH_INFO'] && ((@@nr -= 1) <= 0)
+    env = instance_variable_get(:@request).env
+    if OOBGC_PATH =~ env['PATH_INFO'] && ((@@nr -= 1) <= 0)
       @@nr = OOBGC_INTERVAL
-      OOBGC_ENV.clear
+      env.clear
       disabled = GC.enable
       GC.start
       GC.disable if disabled

^ permalink raw reply related	[relevance 2%]

* Re: Sustained queuing on one listener can block requests from other listeners
  @ 2020-04-16  6:59  6%     ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2020-04-16  6:59 UTC (permalink / raw)
  To: Stan Hu; +Cc: unicorn-public

Stan Hu <stanhu@gmail.com> wrote:
> Thanks, Eric. That patch didn't work; it spun the CPU. I think this worked?

Oops, sorry.  I was too eager to drop `nr += 1' :x

Btw, please don't top post.  Fwiw, I wouldn't mind if we stopped
quoting at all on publically-archived lists (saves space and
bandwidth).

> +++ b/lib/unicorn/http_server.rb
> @@ -708,7 +708,7 @@ def worker_loop(worker)
>        # we're probably reasonably busy, so avoid calling select()
>        # and do a speculative non-blocking accept() on ready listeners
>        # before we sleep again in select().
> -      unless nr == 0
> +      if nr == readers.size
>          tmp = ready.dup
>          redo
>        end

Your patch looks close.  However the `readers' array gets
dropped on SIGQUIT with `nuke_listeners!', so `readers.size'
is unstable.

How about this?

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index a52931a..45a2e97 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -686,6 +686,7 @@ def worker_loop(worker)
     trap(:USR1) { nr = -65536 }
 
     ready = readers.dup
+    nr_listeners = readers.size
     @after_worker_ready.call(self, worker)
 
     begin
@@ -708,7 +709,7 @@ def worker_loop(worker)
       # we're probably reasonably busy, so avoid calling select()
       # and do a speculative non-blocking accept() on ready listeners
       # before we sleep again in select().
-      unless nr == 0
+      if nr == nr_listeners
         tmp = ready.dup
         redo
       end

Thanks

^ permalink raw reply related	[relevance 6%]

* Re: [ANN] unicorn 5.3.0 - Rack HTTP server for fast clients and Unix
  @ 2017-04-02  2:14  7% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2017-04-02  2:14 UTC (permalink / raw)
  To: ruby-talk, unicorn-public
  Cc: Jeremy Evans, Simon Eskildsen, Dylan Thacker-Smith

Eric Wong <e@80x24.org> wrote:
> Anyways, this is a largish release with several new features,
> and no backwards incompatibilities.

Oops :x  Just released Rainbows! 5.1.1 to fix one incompatibility
introduced with unicorn 5.3.0 :x

  https://bogomips.org/rainbows-public/20170402021109.GA29200@dcvr/

Anyways, I no longer promote Rainbows! and there's almost no
users, so I hope the impact is small.

^ permalink raw reply	[relevance 7%]

* [PATCH] doc: note after_worker_exit is also 5.3.0+
@ 2017-03-24  0:33  7% Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2017-03-24  0:33 UTC (permalink / raw)
  To: unicorn-public; +Cc: Jeremy Evans

Followup-to: 650e01ab0b118803486b56f3ee59521d59042dae
  ("doc: add version annotations for new features")
---
 Oops, missed the 5.3.0.pre1 release; I managed to squash in
 the worker_exec change for that, though.

 lib/unicorn/configurator.rb | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 5203537b..7fb9030f 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -172,6 +172,8 @@ def after_fork(*args, &block)
   #      server.logger.error("worker process failure: #{status.inspect}")
   #    end
   #  end
+  #
+  # after_worker_exit is only available in unicorn 5.3.0+
   def after_worker_exit(*args, &block)
     set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
   end
-- 
EW

^ permalink raw reply related	[relevance 7%]

* response_start_sent (check_client_connection) is staying
@ 2017-02-15 18:45  7% Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2017-02-15 18:45 UTC (permalink / raw)
  To: unicorn-public

There's no way I would remove this feature or any other
feature other people rely on.  Just pushed this out:

commit c4b58719e8aa7f2b4979d139ca166a8c6a11eb7e
Author: Eric Wong <e@80x24.org>
Date:   Wed Feb 15 18:37:10 2017 +0000

    Revert "remove response_start_sent"
    
    Oops, this was a half-baked change I was considering
    but forgot about.
    
    This reverts commit 69fd4f9bbff3708166fbf70163fa6e192dde1497.

commit 69fd4f9bbff3708166fbf70163fa6e192dde1497 was the start of
a reorganization that I ultimately abandoned, at least for now.

https://bogomips.org/unicorn.git/patch?id=c4b58719e8aa7f2b
https://bogomips.org/unicorn.git/patch?id=69fd4f9bbff37081

(and I'm still working on a better git viewer for lynx/w3m users)

^ permalink raw reply	[relevance 7%]

* Re: trying to update unicorn to 5.1, build failure: VERSION= must be specified
       [not found]     ` <CAAB-Kcnwzc8Tcszv3FCPkyJRKRCsHRH6k_qBhKfBpSODxqKy5g@mail.gmail.com>
@ 2016-10-28  0:23  6%   ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2016-10-28  0:23 UTC (permalink / raw)
  To: Hleb Valoshka; +Cc: debian-ruby, Pirate Praveen, unicorn-public

Hleb Valoshka <375gnu@gmail.com> wrote:
> On 9/19/16, Pirate Praveen <praveen@onenetbeyond.org> wrote:
> > Its pushed to alioth. Can someone check?
> >
> > Error below:
> >
> > $ clean
> > dh clean --buildsystem=ruby --with ruby,systemd
> >    dh_testdir -O--buildsystem=ruby
> >    dh_auto_clean -O--buildsystem=ruby
> > 	dh_ruby --clean
> >    dh_ruby --clean
> > VERSION= must be specified
> > dh_auto_clean: dh_ruby --clean returned exit code 1
> > debian/rules:6: recipe for target 'clean' failed
> > make: *** [clean] Error 1
> 
> This is not the only problem, then you should have olddoc gem, I
> remember that I tried to fix these error, but I don't see my changes,
> maybe I did this on my home pc, I'll look there.

(oops, missed this earlier)

I understand olddoc may not be worth the effort to package in
Debian.  (I already tried to reduce dependencies in olddoc
compared to wrongdoc, but a package is a package...)

Anyways, I suggest you guys grab the generated gemspec from the
Rubygem or tar.gz.  You already seem to be doing that with NEWS
and the manpages to avoid a build-dep on pandoc(*).

Maybe the gemspec in git could have olddoc become optional, too,
while still remaining DRY.  The email address for the public
mailing list is already specified in multiple places, so maybe
over-DRY-ing isn't worth it...

Anyways, feel free to email me + Cc: unicorn-public@bogomips.org
w.r.t. any packaging/integration issues for any Free Software
systems (not just Debian)


(*) - I'll be switching over to perlpod at some point and
      pod2man is standard in Debian.  I hate having to spend
      ~30MB of bandwidth fees to get ghc + pandoc to build
      manpages.

^ permalink raw reply	[relevance 6%]

* [PATCH] explain 11 byte magic number for self-pipe
@ 2015-02-18  9:36  6% Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2015-02-18  9:36 UTC (permalink / raw)
  To: unicorn-public; +Cc: Steven Stewart-Gallus, Jesse Storimer

Oops, this should've been explained long ago but apparently not.

In response to a comment on
http://www.sitepoint.com/the-self-pipe-trick-explained/

> Does anybody know why both unicorn and foreman read 11 bytes from
> self-pipe?

Unfortunately I couldn't find a way to comment on the site on a
JavaScript-free browser nor does it seem possible without
registering.

Again, anybody can send plain-text mail to:
unicorn-public@bogomips.org

No registration, no real name policy, no terms-of-service, just
plain-text.  Feel free to use Tor, mixmaster or any anonymity
service, too.
---
 lib/unicorn/http_server.rb | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 015bd94..683eb82 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -370,6 +370,10 @@ class Unicorn::HttpServer
   # wait for a signal hander to wake us up and then consume the pipe
   def master_sleep(sec)
     IO.select([ @self_pipe[0] ], nil, nil, sec) or return
+    # 11 bytes is the maximum string length which can be embedded within
+    # the Ruby itself and not require a separate malloc (on 32-bit MRI 1.9+).
+    # Most reads are only one byte here and uncommon, so it's not worth a
+    # persistent buffer, either:
     @self_pipe[0].kgio_tryread(11)
   end
 
-- 
EW

^ permalink raw reply related	[relevance 6%]

* Re: No, passenger 5.0 is not faster than unicorn :)
  @ 2014-12-03  9:57  7%   ` Sam Saffron
  0 siblings, 0 replies; 30+ results
From: Sam Saffron @ 2014-12-03  9:57 UTC (permalink / raw)
  To: Bráulio Bhavamitra; +Cc: unicorn-public, Hitendra Hugo Melo

oops sent wrong link meant to send this

https://meta.discourse.org/t/raptor-web-server/21304/6

On Wed, Dec 3, 2014 at 8:56 PM, Sam Saffron <sam.saffron@gmail.com> wrote:
> I covered this here:
> http://discuss.topazlabs.com/t/amidst-blizzards-they-rest/1147
>
> it seems like an odd marketing move to me ... optimising a bit that
> needs very little help. heck ripping out hashie and the 50 frames
> omniauth injects would have a significantly bigger impact on rails
> apps out there than optimising the 0.5% that needs little optimising.
>
> On Wed, Dec 3, 2014 at 8:50 PM, Bráulio Bhavamitra <braulio@eita.org.br> wrote:
>> Hello all,
>>
>> I've just tested a one instance each (one worker with unicorn and
>> --max-pool-size 1 passenger 5) on the rails app I work.
>>
>> And the results are just as I expected, no miracle at all: Unicorn is
>> still the fatest!
>> (the difference is only a few milliseconds less per request)
>>
>> The blocking design of unicorn is proving itself very efficient.
>>
>> cheers!
>> bráulio
>>

^ permalink raw reply	[relevance 7%]

* Re: permissions on ChangeLog and NEWS
  @ 2013-11-25  6:52  7% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2013-11-25  6:52 UTC (permalink / raw)
  To: unicorn list; +Cc: Ken Dreyer

Ken Dreyer <ktdreyer@ktdreyer.com> wrote:
> Would you mind using the newer version of wrongdoc when you release
> the next version of Unicorn?

Oops, will do.  Just upgraded the build/release machine :x
Thanks for the catch.
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: Unicorn 4.7.0 tests fail on OSX 10.7.5 and debian squeeze
  @ 2013-11-04 18:37  5% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2013-11-04 18:37 UTC (permalink / raw)
  To: unicorn list; +Cc: Andrew Hobson

Andrew Hobson <ahobson@gmail.com> wrote:
> On both my machines, it is commit 7c125886b5862bf20711bae22e6697ad46141434 that breaks the tests.

> : Finished tests in 0.041678s, 263.9282 tests/s, 1943.4714 assertions/s.
> :
> : 1) Failure:
> : test_reuseport(TestSocketHelper) [test/unit/test_socket_helper.rb:193]:
> : <1> expected but was
> : <512>.
> :
> : 11 tests, 81 assertions, 1 failures, 0 errors, 0 skips
> 
> I don't see how the current test can be platform independent.  The following diff fixes OSX for me:
> 
> diff --git a/test/unit/test_socket_helper.rb b/test/unit/test_socket_helper.rb
> index abc177b..2244442 100644
> --- a/test/unit/test_socket_helper.rb
> +++ b/test/unit/test_socket_helper.rb
> @@ -189,7 +189,6 @@ class TestSocketHelper < Test::Unit::TestCase
> port = unused_port @test_addr
> name = "#@test_addr:#{port}"
> sock = bind_listen(name, :reuseport => true)
> - cur = sock.getsockopt(Socket::SOL_SOCKET, SO_REUSEPORT).unpack('i')[0]
> - assert_equal 1, cur
> + assert sock.getsockopt(Socket::SOL_SOCKET, SO_REUSEPORT).bool
> end if defined?(SO_REUSEPORT)

I can't use .bool for Ruby 1.8, unfortunately.
I've just use assert_operator in my proposed patch below.

> The error I get when I test 4.7.0 on debian squeeze (in a VM):
> 
> : 1) Error:
> : test_reuseport(TestSocketHelper):
> : Errno::ENOPROTOOPT: Protocol not available

Oops, I forgot Linux < 3.9 is still widely in use(!)

> I don't know how unicorn should deal with that.  I suppose ignoring
> ENOPROTOOPT if RUBY_PLATFORM =~ /linux/ is an option, but it is
> certainly not an appealing one.

I'll just ignore it in the test.  If a user requests it, then they'll
see the error (but we leave SO_REUSEPORT off by default)

Will push the following:

From: Eric Wong <normalperson@yhbt.net>
Subject: [PATCH] tests: fix SO_REUSEPORT tests for old Linux and non-Linux

On BSD-derived platforms the getsockopt true value may be any
(>= 0) value, not just one as it is on Linux.

Additionally, SO_REUSEPORT is only supported since Linux 3.9, so
folks on older kernels may not have it available.  We still define it
for Linux since kernel upgrades are usually more common than glibc
upgrades.

Note: we will still raise an exception at runtime if a user
explicitly requests :reuseport in their config and runs an
older Linux kernel.

Reported-by: Andrew Hobson <ahobson@gmail.com>
---
 test/unit/test_socket_helper.rb | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/unit/test_socket_helper.rb b/test/unit/test_socket_helper.rb
index abc177b..8992757 100644
--- a/test/unit/test_socket_helper.rb
+++ b/test/unit/test_socket_helper.rb
@@ -190,6 +190,8 @@ class TestSocketHelper < Test::Unit::TestCase
     name = "#@test_addr:#{port}"
     sock = bind_listen(name, :reuseport => true)
     cur = sock.getsockopt(Socket::SOL_SOCKET, SO_REUSEPORT).unpack('i')[0]
-    assert_equal 1, cur
-  end if defined?(SO_REUSEPORT)
+    assert_operator cur, :>, 0
+  rescue Errno::ENOPROTOOPT
+    # kernel does not support SO_REUSEPORT (older Linux)
+  end
 end
-- 
1.8.4.483.g7fe67e6.dirty
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 5%]

* [PATCH] http: avoid frozen string bug in filter_body
  @ 2013-02-26  2:56  6% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2013-02-26  2:56 UTC (permalink / raw)
  To: mongrel-unicorn

Eric Wong <normalperson@yhbt.net> wrote:
> I'm stumped that rb_str_modify() doesn't seem to help with
> rb_str_set_len() raising in the chunked parser.  More info here:
> 
> https://bugs.ruby-lang.org/issues/7957
> 
> Any help would be appreciated... It's way past my bed time.

Oops, my fault from 2010 and 2009.  v4.6.2 coming

>From f7ee06592d7709e96f64efb5e7a9485b54415c9d Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 26 Feb 2013 02:52:37 +0000
Subject: [PATCH] http: avoid frozen string bug in filter_body

Our rb_str_modify() became no-ops due to incomplete reverts
of workarounds for old Rubinius, causing rb_str_set_len to
fail with: can't set length of shared string (RuntimeError)

This bug was introduced due to improper workarounds for old
versions of Rubinius in 2009 and 2010:

commit 5e8979ad38efdc4de3a69cc53aea33710d478406
("http: cleanups for latest Rubinius")
commit f37c23704cb73d57e9e478295d1641df1d9104c7
("http: no-op rb_str_modify() for Rubies without it")
---
 ext/unicorn_http/ext_help.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/ext/unicorn_http/ext_help.h b/ext/unicorn_http/ext_help.h
index 0968080..c87c272 100644
--- a/ext/unicorn_http/ext_help.h
+++ b/ext/unicorn_http/ext_help.h
@@ -52,10 +52,6 @@ static void rb_18_str_set_len(VALUE str, long len)
 #  endif
 #endif /* ! defined(NUM2SIZET) */
 
-#ifndef HAVE_RB_STR_MODIFY
-#  define rb_str_modify(x) do {} while (0)
-#endif /* ! defined(HAVE_RB_STR_MODIFY) */
-
 static inline int str_cstr_eq(VALUE val, const char *ptr, long len)
 {
   return (RSTRING_LEN(val) == len && !memcmp(ptr, RSTRING_PTR(val), len));
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 6%]

* [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION
  @ 2013-02-08 18:55  4% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2013-02-08 18:55 UTC (permalink / raw)
  To: unicorn list; +Cc: Maurizio De Santis

Maurizio De Santis <m.desantis@morganspa.com> wrote:
> Hello,
> 
> I want to report that unicorn-4.6.0/lib/unicorn/const.rb declares
> UNICORN_VERSION = "4.5.0", which I think should be "4.6.0".

Oops, I've been meaning to move that constant over to an auto-generated file
using GIT-VERSION-GEN.  This should work:

--------------------------------- 8< ------------------------------
>From cb0623f25db7f06660e563e8e746bfe0ae5ba9c5 Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Fri, 8 Feb 2013 18:50:07 +0000
Subject: [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION

This DRYs out our code and prevents snafus like the 4.6.0
release where UNICORN_VERSION stayed at 4.5.0

Reported-by: Maurizio De Santis <m.desantis@morganspa.com>
---
 .gitignore           |  1 +
 GIT-VERSION-GEN      | 69 ++++++++++++++++++++++++++--------------------------
 GNUmakefile          |  2 +-
 lib/unicorn/const.rb |  4 +--
 4 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/.gitignore b/.gitignore
index 50c2736..19a82d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ pkg/
 /man
 /tmp
 /LATEST
+/lib/unicorn/version.rb
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 56aef5f..e5d414a 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,40 +1,39 @@
-#!/bin/sh
-
-GVF=GIT-VERSION-FILE
-DEF_VER=v4.6.0
-
-LF='
-'
+#!/usr/bin/env ruby
+DEF_VER = "v4.6.0"
+CONSTANT = "Unicorn::Const::UNICORN_VERSION"
+RVF = "lib/unicorn/version.rb"
+GVF = "GIT-VERSION-FILE"
+vn = DEF_VER
 
 # First see if there is a version file (included in release tarballs),
 # then try git-describe, then default.
-if test -f version
-then
-	VN=$(cat version) || VN="$DEF_VER"
-elif test -d .git -o -f .git &&
-	VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
-	case "$VN" in
-	*$LF*) (exit 1) ;;
-	v[0-9]*)
-		git update-index -q --refresh
-		test -z "$(git diff-index --name-only HEAD --)" ||
-		VN="$VN-dirty" ;;
-	esac
-then
-	VN=$(echo "$VN" | sed -e 's/-/./g');
-else
-	VN="$DEF_VER"
-fi
+if File.exist?(".git")
+  describe = `git describe --abbrev=4 HEAD 2>/dev/null`.strip
+  case describe
+  when /\Av[0-9]*/
+    vn = describe
+    system(*%w(git update-index -q --refresh))
+    unless `git diff-index --name-only HEAD --`.chomp.empty?
+      vn << "-dirty"
+    end
+    vn.tr!('-', '.')
+  end
+end
+
+vn = vn.sub!(/\Av/, "")
+
+# generate the Ruby constant
+new_ruby_version = "#{CONSTANT} = '#{vn}'\n"
+cur_ruby_version = File.read(RVF) rescue nil
+if new_ruby_version != cur_ruby_version
+  File.open(RVF, "w") { |fp| fp.write(new_ruby_version) }
+end
 
-VN=$(expr "$VN" : v*'\(.*\)')
+# generate the makefile snippet
+new_make_version = "GIT_VERSION = #{vn}\n"
+cur_make_version = File.read(GVF) rescue nil
+if new_make_version != cur_make_version
+  File.open(GVF, "w") { |fp| fp.write(new_make_version) }
+end
 
-if test -r $GVF
-then
-	VC=$(sed -e 's/^GIT_VERSION = //' <$GVF)
-else
-	VC=unset
-fi
-test "$VN" = "$VC" || {
-	echo >&2 "GIT_VERSION = $VN"
-	echo "GIT_VERSION = $VN" >$GVF
-}
+puts vn if $0 == __FILE__
diff --git a/GNUmakefile b/GNUmakefile
index ea13486..34a2d95 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -155,7 +155,7 @@ clean:
 man html:
 	$(MAKE) -C Documentation install-$@
 
-pkg_extra := GIT-VERSION-FILE ChangeLog LATEST NEWS \
+pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb ChangeLog LATEST NEWS \
              $(ext)/unicorn_http.c $(man1_paths)
 
 ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
diff --git a/lib/unicorn/const.rb b/lib/unicorn/const.rb
index fcc30c0..51d7394 100644
--- a/lib/unicorn/const.rb
+++ b/lib/unicorn/const.rb
@@ -7,9 +7,6 @@
 # improvement over using the strings directly.  Symbols did not really
 # improve things much compared to constants.
 module Unicorn::Const
-
-  UNICORN_VERSION = "4.5.0"
-
   # default TCP listen host address (0.0.0.0, all interfaces)
   DEFAULT_HOST = "0.0.0.0"
 
@@ -44,3 +41,4 @@ module Unicorn::Const
 
   # :startdoc:
 end
+require 'unicorn/version'
-- 
1.8.1.2.526.gf51a757
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 4%]

* Re: Combating nginx 499 HTTP responses during flash traffic scenario
  @ 2012-11-06 21:23  6%                   ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2012-11-06 21:23 UTC (permalink / raw)
  To: unicorn list

Tom Burns <tom.burns@jadedpixel.com> wrote:
> On Mon, Nov 5, 2012 at 6:48 AM, Eric Wong <normalperson@yhbt.net> wrote:
> > We can wait until you can report on how this change improves your
> > situation before fleshing this out.  Real-world results are always
> > good to have :>
> 
> Agreed.
> 
> We're going to be testing this this week so I should have some results
> to share by the weekend.  We only experience the problem during major
> sales so it may or may not manifest without our traffic generation
> tool.

Holidays are coming up, should be lots of traffic :)

> I'd like to be testing a patch close to the finished product so I've
> addressed all of your comments from the previous email (including the
> modification to the C extension) in the patch below.

Thanks for the updated patch.  A few comments below, apologies for the
nitpicks :)

> > Random thought:  HttpResponse generation gains even more coupling
> > with the current Http{Request,Parser} state.  Organizing code is hard :x
> Agreed.  Without a class wrapping the raw socket to hold state I
> didn't see a better way to accomplish this, but I've only been looking
> at this code for the past week or so.

I'm leaning towards just having one HttpState class which encompasses
the entire client state (request/response).  I did that earlier this
year for a single-purpose (non-Ruby) HTTP daemon and that design makes
the most sense to me.

Maybe we'll modify unicorn around that sooner or later...

> diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl
> index 96dcf83..52f7f3c 100644
> --- a/ext/unicorn_http/unicorn_http.rl
> +++ b/ext/unicorn_http/unicorn_http.rl
> @@ -115,7 +115,7 @@ struct http_parser {
>    } len;
>  };
> 
> -static ID id_clear, id_set_backtrace;
> +static ID id_clear, id_set_backtrace, id_response_start_sent;
> 
>  static void finalize_header(struct http_parser *hp);
> 
> @@ -626,6 +626,7 @@ static VALUE HttpParser_clear(VALUE self)
> 
>    http_parser_init(hp);
>    rb_funcall(hp->env, id_clear, 0);
> +  rb_funcall(self, id_response_start_sent, 1, Qfalse);

Nitpick:  Since HttpParser is already an alias of the HttpRequest class,
rb_ivar_set() should be a hair faster as it won't have to go through
normal method lookup.

>    return self;
>  }
> @@ -1031,6 +1032,7 @@ void Init_unicorn_http(void)
>    SET_GLOBAL(g_http_connection, "CONNECTION");
>    id_clear = rb_intern("clear");
>    id_set_backtrace = rb_intern("set_backtrace");
> +  id_response_start_sent = rb_intern("response_start_sent=");
>    init_unicorn_httpdate();
>  }
>  #undef SET_GLOBAL
> diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
> index 89cbf5c..5f329af 100644
> --- a/lib/unicorn/configurator.rb
> +++ b/lib/unicorn/configurator.rb
> @@ -45,6 +45,7 @@ class Unicorn::Configurator
>        },
>      :pid => nil,
>      :preload_app => false,
> +    :check_client_connection => false,
>      :rewindable_input => true, # for Rack 2.x: (Rack::VERSION[0] <= 1),
>      :client_body_buffer_size => Unicorn::Const::MAX_BODY,
>      :trust_x_forwarded => true,
> @@ -96,6 +97,13 @@ class Unicorn::Configurator
>      if ready_pipe = RACKUP.delete(:ready_pipe)
>        server.ready_pipe = ready_pipe
>      end
> +    if set[:check_client_connection]
> +      set[:listeners].each do |address|
> +        if set[:listener_opts][address][:tcp_nopush] == true ||
> set[:listener_opts][address][:tcp_nodelay] == true

Oops, I missed long lines the first time.  It looks like your MUA did
mangle the long line.  Wrap everything at <80 columns should help avoid
the issue (regardless of MUA, my brain cannot process >80 columns well)

> +          raise ArgumentError, "With check_client_connection set to
> true both :tcp_nopush and :tcp_nodelay listener options must be set to
> false."

Likewise, error messages should be more concise and easier to read
in smaller terminals.

Probably:

check_client_connection is incompatible with (tcp_nopush|tcp_nodelay):true

> @@ -454,6 +462,12 @@ class Unicorn::Configurator
>      set_int(:client_body_buffer_size, bytes, 0)
>    end
> 
> +  # When enabled, unicorn will check the client connection by writing
> +  # the beginning of the HTTP headers before calling the application.

Good to document the :tcp_* listener option incompatibilities here, too.

> +  def check_client_connection(bool)
> +    set_bool(:check_client_connection, bool)
> +  end
> +
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 6%]

* Re: FreeBSD jail and unicorn
  @ 2012-02-02 22:41  7%       ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2012-02-02 22:41 UTC (permalink / raw)
  To: unicorn list; +Cc: Philipp Bruell, Charles Hornberger

Eric Wong <normalperson@yhbt.net> wrote:
> A total stab in the dark, but I posted this patch to ruby-core anyways
> to find more testers/reviewers:
> 
>   http://mid.gmane.org/20120202221946.GA32004@dcvr.yhbt.net

Oops, and I just posted a follow-up since the original was a no-op
due to ordering issues :x
http://mid.gmane.org/20120202223945.GA9233@dcvr.yhbt.net
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  2011-06-07 15:11  0%   ` Hongli Lai
@ 2011-06-07 17:06  0%     ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2011-06-07 17:06 UTC (permalink / raw)
  To: unicorn list

Hongli Lai <hongli@phusion.nl> wrote:
> On Mon, Jun 6, 2011 at 7:51 PM, Eric Wong <normalperson@yhbt.net> wrote:
> > Oops, this was a regression introduced when I switched to wrongdoc
> > in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964
> >
> > Perhaps this is better?  It'll also affect the tgz target and not
> > just the gem target.
> 
> I'm fine with it if it works. :)

Pushed out with the following commit message:

From 0dc56fd03ea478ae054e3d0398703f43e017723b Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 7 Jun 2011 09:56:30 -0700
Subject: [PATCH] build: ensure gem and tgz targets build manpages

Original patch by Hongli Lai <hongli@phusion.nl>:

> >From bfefc2cf0efb0913a42862886363b3140dcdbb2a Mon Sep 17 00:00:00 2001
> From: Hongli Lai (Phusion) <hongli@phusion.nl>
> Date: Mon, 6 Jun 2011 13:39:00 +0200
> Subject: [PATCH] Ensure that 'make gem' builds the documentation too.
>
> If autogenerated documentation files, like man pages, don't exist then
> 'make gem' will fail, complaining that some files are not found. By
> depending the 'gem' target on the 'doc' target we ensure that 'make gem'
> always works.
>
> Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>

ref: http://mid.gmane.org/4DED0EE2.7040400@phusion.nl
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  2011-06-06 17:51  6% ` Eric Wong
@ 2011-06-07 15:11  0%   ` Hongli Lai
  2011-06-07 17:06  0%     ` Eric Wong
  0 siblings, 1 reply; 30+ results
From: Hongli Lai @ 2011-06-07 15:11 UTC (permalink / raw)
  To: unicorn list

On Mon, Jun 6, 2011 at 7:51 PM, Eric Wong <normalperson@yhbt.net> wrote:
> Oops, this was a regression introduced when I switched to wrongdoc
> in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964
>
> Perhaps this is better?  It'll also affect the tgz target and not
> just the gem target.

I'm fine with it if it works. :)

-- 
Phusion | Ruby & Rails deployment, scaling and tuning solutions

Web: http://www.phusion.nl/
E-mail: info@phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply	[relevance 0%]

* Re: [PATCH] Ensure that 'make gem' builds the documentation too.
  @ 2011-06-06 17:51  6% ` Eric Wong
  2011-06-07 15:11  0%   ` Hongli Lai
  0 siblings, 1 reply; 30+ results
From: Eric Wong @ 2011-06-06 17:51 UTC (permalink / raw)
  To: unicorn list

Hongli Lai <hongli@phusion.nl> wrote:
> >From bfefc2cf0efb0913a42862886363b3140dcdbb2a Mon Sep 17 00:00:00 2001
> From: Hongli Lai (Phusion) <hongli@phusion.nl>
> Date: Mon, 6 Jun 2011 13:39:00 +0200
> Subject: [PATCH] Ensure that 'make gem' builds the documentation too.
> 
> If autogenerated documentation files, like man pages, don't exist then
> 'make gem' will fail, complaining that some files are not found. By
> depending the 'gem' target on the 'doc' target we ensure that 'make gem'
> always works.
> 
> Signed-off-by: Hongli Lai (Phusion) <hongli@phusion.nl>

Oops, this was a regression introduced when I switched to wrongdoc
in f62ef19a4aa3d3e4ce1aa37a499907ff776a8964

Perhaps this is better?  It'll also affect the tgz target and not
just the gem target.

diff --git a/GNUmakefile b/GNUmakefile
index da55052..61fb739 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -164,7 +164,7 @@ pkg_extra := GIT-VERSION-FILE ChangeLog LATEST NEWS \
 ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
 	wrongdoc prepare
 
-.manifest: ChangeLog $(ext)/unicorn_http.c
+.manifest: ChangeLog $(ext)/unicorn_http.c man
 	(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
 	  LC_ALL=C sort > $@+
 	cmp $@+ $@ || mv $@+ $@
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 6%]

* Re: [ANN] unicorn 3.6.0 - small fixes, PRNG workarounds
  @ 2011-04-26 23:01  6%   ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2011-04-26 23:01 UTC (permalink / raw)
  To: unicorn list

ghazel@gmail.com wrote:
> On Wednesday, April 20, 2011, Eric Wong <normalperson@yhbt.net> wrote:
> > Changes:
> >
> > Mainly small fixes, improvements, and workarounds for fork() issues
> > with pseudo-random number generators shipped with Ruby (Kernel#rand,
> > OpenSSL::Random (used by SecureRandom and also by Rails).
> >
> > The PRNG issues are documented in depth here (and links to Ruby Redmine):
> >
> >   http://bogomips.org/unicorn.git/commit?id=1107ede7
> >   http://bogomips.org/unicorn.git/commit?id=b3241621
(top-posting corrected)
> Is it possible there is a problem with this change? Since I upgraded
> to 3.6.0 I have encountered two collisions on
> ActiveSupport::SecureRandom.hex(64), which seems very unlikely, since
> it has never happened in the history of my app otherwise.

Oops, the return value of srand shouldn't be relied on, I need to call
Kernel#rand instead.  My attempt to fix things actually made the problem
worse (which is why I pushed upstream Ruby to fix the problem, first :).
The following should fix it (3.6.1 release coming):

diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index d70de45..3077b95 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -492,11 +492,11 @@ class Unicorn::HttpServer
   def after_fork_internal
     @ready_pipe.close if @ready_pipe
     self.ready_pipe = nil # XXX Rainbows! compat, change for Unicorn 4.x
-    tmp = srand # http://redmine.ruby-lang.org/issues/4338
+    srand # http://redmine.ruby-lang.org/issues/4338
 
     # The OpenSSL PRNG is seeded with only the pid, and apps with frequently
     # dying workers can recycle pids
-    OpenSSL::Random.seed(tmp.to_s) if defined?(OpenSSL::Random)
+    OpenSSL::Random.seed(rand.to_s) if defined?(OpenSSL::Random)
   end
 
   def spawn_missing_workers
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying

^ permalink raw reply related	[relevance 6%]

* Re: Struggling with logrotate and unicorn
  @ 2011-04-12 23:01  6%           ` Emmanuel Gomez
  0 siblings, 0 replies; 30+ results
From: Emmanuel Gomez @ 2011-04-12 23:01 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

On Apr 12, 2011, at 3:51 PM, Eric Wong wrote:
> Yes, I think most people still deploy and start as non-root
> (Capistrano/Vlad).  But I also distribute init scripts and those
> are usually run as root :x

And it's because of init scripts that I'm running unicorn as root.

> Actually the (usually) user-visible one should be
> Unicorn::Configurator#user which should be in the top-level.
> Worker#user is just the internal call.

Oh, great, I'm glad you pointed that out. Since the worker instance is yielded into the after_fork block, I started looking there. I'll update my config to use the public interface. Also, I'll go correct my github blog post comment, oops.

>> Hey, I can help here. Here's a patch:
> 
> Perhaps this is better? I added a blurb discouraging people from
> running as root in the first place.  

Looks great. 

> You'll still get credit :)

It's a nothing, I don't need any credit :)
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 6%]

* Re: "Read error: #<IOError: closed stream>" and uploads
       [not found]             ` <C83FE4C4-F4FB-48BC-8FC6-4E1B1B26F2D8@gmail.com>
@ 2011-01-25  3:17  0%           ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2011-01-25  3:17 UTC (permalink / raw)
  To: mongrel-unicorn; +Cc: Alexey Bondar

Alexey Bondar <alexey.bondar@gmail.com> wrote:
> On Jan 25, 2011, at 03:51 , Eric Wong wrote:
> > Wait, nginx buffered the body to disk when client_body_buffer_size is
> > 128mb and you have trouble with a 150kb request?
> 
> Oops, my fault: not body_buffer_size, but client_max_body_size.  client_body_buffer_size is 128k.
> 
> As I understand, in this case nginx should buffer whole request body, before sending to backend? 

Yes, nginx always buffers the whole request body

> >> Same issue with 1.1.x
> > 
> > OK.  Which timeout exactly are you hitting in nginx?  
> 
> Logs: 
> 2011/01/23 21:09:05 [warn] 79095#0: *261 a client request body is buffered to a temporary file /var/spool/nginx-client-body/3/00/0000000003

<snip>

> 2011/01/23 21:09:35 [error] 79095#0: *261 upstream timed out (60: Operation timed out) while sending request to upstream

<snip>

Very strange.  Do you process env["rack.input"] directly from your app
or do you let Rails/Rack handle everything?

This probably won't help, but can you try increasing the
proxy_send_timeout in nginx?  What's your Unicorn timeout?

_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 0%]

* Re: Working directory and config.ru
  2010-06-09 18:04  7% ` Eric Wong
@ 2010-06-10  9:58  0%   ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2010-06-10  9:58 UTC (permalink / raw)
  To: unicorn list

Eric Wong <normalperson@yhbt.net> wrote:
> Pierre Baillet <oct@fotonauts.com> wrote:
> > Hi,
> > 
> > I naively expected unicorn to honor the working_directory
> > configuration directive before attempting to locate the config.ru but
> > this does not seem to be the case. Is this behavior wanted ? From the
> > code, I can guess that the configuration file parsing is done much
> > later  than the current config.ru location attempt.
> 
> Hi Pierre,
> 
> Oops, definitely not wanted behavior.  Unicorn should honor
> working_directory with regard to config.ru.  I'll start working
> on a fix shortly, thanks for the report!

I just pushed the following out with a few other cleanups.

Maintaining Rainbows!/Zbatery compatibility was a bit costly in terms of
prettiness.

Overall, my initial hesitation to support "working_directory" last year
was validated by the complexity of maintaining relative path
compatibility across the board.

I'm very glad for the integration test suite (stolen from Rainbows!)
which allows me to write tests in my "native" language :>

There'll be more tests coming when I'm more awake (and I'm actually
developing a real Rack application which will be public Real Soon
Now(TM), but more targeted at Rainbows!/Zbatery :)

>From 4accf4449390c649bce0b1c9d84314d65fd41f8e Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Thu, 10 Jun 2010 08:47:10 +0000
Subject: [PATCH] respect "working_directory" wrt config.ru

Since we added support for the "working_directory" parameter, it
often became unclear where/when certain paths would be bound.

There are some extremely nasty dependencies and ordering issues
when doing this.  It's all pretty fragile, but works for now
and we even have a full integration test to keep it working.

I plan on cleaning this up 2.x.x to be less offensive to look
at (Rainbows! and Zbatery are a bit tied to this at the moment).

Thanks to Pierre Baillet for reporting this.

ref: http://mid.gmane.org/AANLkTimKb7JARr_69nfVrJLvMZH3Gvs1o_KwZFLKfuxy@mail.gmail.com
---
 bin/unicorn                  |    5 +---
 bin/unicorn_rails            |   17 +++++++++---
 lib/unicorn.rb               |    7 ++---
 lib/unicorn/configurator.rb  |   56 ++++++++++++++++++++++++++++++++++++++++++
 lib/unicorn/launcher.rb      |    5 ++-
 t/t0003-working_directory.sh |   53 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 129 insertions(+), 14 deletions(-)
 create mode 100755 t/t0003-working_directory.sh

diff --git a/bin/unicorn b/bin/unicorn
index beece97..2cc10b1 100755
--- a/bin/unicorn
+++ b/bin/unicorn
@@ -107,10 +107,7 @@ opts = OptionParser.new("", 24, '  ') do |opts|
   opts.parse! ARGV
 end
 
-ru = ARGV[0] || "config.ru"
-abort "configuration file #{ru} not found" unless File.exist?(ru)
-
-app = Unicorn.builder(ru, opts)
+app = Unicorn.builder(ARGV[0] || 'config.ru', opts)
 options[:listeners] << "#{host}:#{port}" if set_listener
 
 if $DEBUG
diff --git a/bin/unicorn_rails b/bin/unicorn_rails
index 2f88bc1..e9cac00 100755
--- a/bin/unicorn_rails
+++ b/bin/unicorn_rails
@@ -107,8 +107,6 @@ opts = OptionParser.new("", 24, '  ') do |opts|
   opts.parse! ARGV
 end
 
-ru = ARGV[0] || (File.exist?('config.ru') ? 'config.ru' : nil)
-
 def rails_dispatcher
   if ::Rails::VERSION::MAJOR >= 3 && ::File.exist?('config/application.rb')
     if ::File.read('config/application.rb') =~ /^module\s+([\w:]+)\s*$/
@@ -127,9 +125,20 @@ def rails_dispatcher
   result || abort("Unable to locate the application dispatcher class")
 end
 
-def rails_builder(daemonize)
+def rails_builder(ru, opts, daemonize)
+  return Unicorn.builder(ru, opts) if ru
+
+  # allow Configurator to parse cli switches embedded in the ru file
+  Unicorn::Configurator::RACKUP.update(:file => :rails, :optparse => opts)
+
   # this lambda won't run until after forking if preload_app is false
+  # this runs after config file reloading
   lambda do ||
+    # Rails 3 includes a config.ru, use it if we find it after
+    # working_directory is bound.
+    ::File.exist?('config.ru') and
+      return Unicorn.builder('config.ru', opts).call
+
     # Load Rails and (possibly) the private version of Rack it bundles.
     begin
       require ::File.expand_path('config/boot')
@@ -179,7 +188,7 @@ def rails_builder(daemonize)
   end
 end
 
-app = ru ? Unicorn.builder(ru, opts) : rails_builder(daemonize)
+app = rails_builder(ARGV[0], opts, daemonize)
 options[:listeners] << "#{host}:#{port}" if set_listener
 
 if $DEBUG
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index c026236..a7b0646 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -33,11 +33,10 @@ module Unicorn
     # Unicorn config).  The returned lambda will be called when it is
     # time to build the app.
     def builder(ru, opts)
-      if ru =~ /\.ru\z/
-        # parse embedded command-line options in config.ru comments
-        /^#\\(.*)/ =~ File.read(ru) and opts.parse!($1.split(/\s+/))
-      end
+      # allow Configurator to parse cli switches embedded in the ru file
+      Unicorn::Configurator::RACKUP.update(:file => ru, :optparse => opts)
 
+      # always called after config file parsing, may be called after forking
       lambda do ||
         inner_app = case ru
         when /\.ru$/
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index e4305c2..0716e64 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -13,6 +13,12 @@ module Unicorn
   # nginx is also available at
   # http://unicorn.bogomips.org/examples/nginx.conf
   class Configurator < Struct.new(:set, :config_file, :after_reload)
+    # :stopdoc:
+    # used to stash stuff for deferred processing of cli options in
+    # config.ru after "working_directory" is bound.  Do not rely on
+    # this being around later on...
+    RACKUP = {}
+    # :startdoc:
 
     # Default settings for Unicorn
     DEFAULTS = {
@@ -51,6 +57,8 @@ module Unicorn
     def reload #:nodoc:
       instance_eval(File.read(config_file), config_file) if config_file
 
+      parse_rackup_file
+
       # working_directory binds immediately (easier error checking that way),
       # now ensure any paths we changed are correctly set.
       [ :pid, :stderr_path, :stdout_path ].each do |var|
@@ -66,6 +74,9 @@ module Unicorn
 
     def commit!(server, options = {}) #:nodoc:
       skip = options[:skip] || []
+      if ready_pipe = RACKUP.delete(:ready_pipe)
+        server.ready_pipe = ready_pipe
+      end
       set.each do |key, value|
         value == :unset and next
         skip.include?(key) and next
@@ -411,5 +422,50 @@ module Unicorn
       set[var] = my_proc
     end
 
+    # this is called _after_ working_directory is bound.  This only
+    # parses the embedded switches in .ru files
+    # (for "rackup" compatibility)
+    def parse_rackup_file # :nodoc:
+      ru = RACKUP[:file] or return # we only return here in unit tests
+
+      # :rails means use (old) Rails autodetect
+      if ru == :rails
+        File.readable?('config.ru') or return
+        ru = 'config.ru'
+      end
+
+      File.readable?(ru) or
+        raise ArgumentError, "rackup file (#{ru}) not readable"
+
+      # it could be a .rb file, too, we don't parse those manually
+      ru =~ /\.ru\z/ or return
+
+      /^#\\(.*)/ =~ File.read(ru) or return
+      warn "ru cli opts: #{$1}"
+      RACKUP[:optparse].parse!($1.split(/\s+/))
+
+      # XXX ugly as hell, WILL FIX in 2.x (along with Rainbows!/Zbatery)
+      host, port, set_listener, options, daemonize =
+                      eval("[ host, port, set_listener, options, daemonize ]",
+                           TOPLEVEL_BINDING)
+
+      warn [ :host, :port, :set_listener, :options, :daemonize ].inspect
+      warn [ ru, host, port, set_listener, options, daemonize ].inspect
+      # XXX duplicate code from bin/unicorn{,_rails}
+      set[:listeners] << "#{host}:#{port}" if set_listener
+
+      if daemonize
+        # unicorn_rails wants a default pid path, (not plain 'unicorn')
+        if ru == :rails
+          spid = set[:pid]
+          pid('tmp/pids/unicorn.pid') if spid.nil? || spid == :unset
+        end
+        unless RACKUP[:daemonized]
+          Unicorn::Launcher.daemonize!(options)
+          RACKUP[:ready_pipe] = options.delete(:ready_pipe)
+        end
+      end
+    end
+
   end
 end
diff --git a/lib/unicorn/launcher.rb b/lib/unicorn/launcher.rb
index 5ab04c7..7f3ffa6 100644
--- a/lib/unicorn/launcher.rb
+++ b/lib/unicorn/launcher.rb
@@ -56,8 +56,9 @@ class Unicorn::Launcher
       end
     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"
+    Unicorn::Configurator::DEFAULTS[:stderr_path] ||= "/dev/null"
+    Unicorn::Configurator::DEFAULTS[:stdout_path] ||= "/dev/null"
+    Unicorn::Configurator::RACKUP[:daemonized] = true
   end
 
 end
diff --git a/t/t0003-working_directory.sh b/t/t0003-working_directory.sh
new file mode 100755
index 0000000..3faa6c0
--- /dev/null
+++ b/t/t0003-working_directory.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+. ./test-lib.sh
+t_plan 4 "config.ru inside alt working_directory"
+
+t_begin "setup and start" && {
+	unicorn_setup
+	rtmpfiles unicorn_config_tmp
+	rm -rf $t_pfx.app
+	mkdir $t_pfx.app
+
+	port=$(expr $listen : '[^:]*:\([0-9]\+\)')
+	host=$(expr $listen : '\([^:]*\):[0-9]\+')
+
+	cat > $t_pfx.app/config.ru <<EOF
+#\--daemonize --host $host --port $port
+use Rack::ContentLength
+use Rack::ContentType, "text/plain"
+run lambda { |env| [ 200, {}, [ "#{\$master_ppid}\\n" ] ] }
+EOF
+	# we have --host/--port in config.ru instead
+	grep -v ^listen $unicorn_config > $unicorn_config_tmp
+
+	# the whole point of this exercise
+	echo "working_directory '$t_pfx.app'" >> $unicorn_config_tmp
+
+	# allows ppid to be 1 in before_fork
+	echo "preload_app true" >> $unicorn_config_tmp
+	cat >> $unicorn_config_tmp <<\EOF
+before_fork do |server,worker|
+  $master_ppid = Process.ppid # should be zero to detect daemonization
+end
+EOF
+
+	mv $unicorn_config_tmp $unicorn_config
+
+	# rely on --daemonize switch, no & or -D
+	unicorn -c $unicorn_config
+	unicorn_wait_start
+}
+
+t_begin "hit with curl" && {
+	body=$(curl -sSf http://$listen/)
+}
+
+t_begin "killing succeeds" && {
+	kill $unicorn_pid
+}
+
+t_begin "response body ppid == 1 (daemonized)" && {
+	test "$body" -eq 1
+}
+
+t_done
-- 

Eric Wong (7):
      launcher: get rid of backwards compatibility code
      isolate: don't run isolate in parallel
      Rakefile: only try rake-compiler if VERSION is defined
      Rakefile: isolate to rbx directory
      tests: set NO_PROXY when running tests
      unicorn_rails: use Kernel#warn instead of $stderr.puts
      respect "working_directory" wrt config.ru

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 0%]

* Re: Working directory and config.ru
  @ 2010-06-09 18:04  7% ` Eric Wong
  2010-06-10  9:58  0%   ` Eric Wong
  0 siblings, 1 reply; 30+ results
From: Eric Wong @ 2010-06-09 18:04 UTC (permalink / raw)
  To: unicorn list

Pierre Baillet <oct@fotonauts.com> wrote:
> Hi,
> 
> I naively expected unicorn to honor the working_directory
> configuration directive before attempting to locate the config.ru but
> this does not seem to be the case. Is this behavior wanted ? From the
> code, I can guess that the configuration file parsing is done much
> later  than the current config.ru location attempt.

Hi Pierre,

Oops, definitely not wanted behavior.  Unicorn should honor
working_directory with regard to config.ru.  I'll start working
on a fix shortly, thanks for the report!

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: workers created when request comes in?
       [not found]       ` <73096a160912152148l4eea211eq972fcea3ebdf9112@mail.gmail.com>
@ 2009-12-16  6:05  7%     ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2009-12-16  6:05 UTC (permalink / raw)
  To: Joseph McDonald; +Cc: mongrel-unicorn

Joseph McDonald <superjoe@gmail.com> wrote:
> On Tue, Dec 15, 2009 at 6:37 PM, Eric Wong <normalperson@yhbt.net> wrote:
> 
> > Yes, just send SIGQUIT to yourself anywhere inside the application
> > dispatch and it'll defer the exit until your application is done
> > processing.
> >
> > You should be able to just make it middleware like this:
> >
> >  # name inspired by the "shotgun" gem
> >  class Unicorn::Shotgun < Struct.new(:app)
> >    def call(env)
> >      Process.kill(:QUIT, 0)
                             ^-- Oops, that should be a $$, not 0
> >      app.call(env)
> >    end
> >  end
> 
> Thanks Eric,
> I added that middleware, but now unicorn exits after servicing one
> request.  I'd like unicorn to keep running and fork off a new child if
> a new request comes in.  Is that possible?

Yeah, just change the 0 to a $$ there, brain fart :x

With that middleware, it should prefork a worker, but then kill it
after every request (and a new one will be preforked).

-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply	[relevance 7%]

* Re: About Unicorn Rack handler
  2009-11-05  4:47  7%     ` Lin Jen-Shin (aka godfat 真常)
@ 2009-11-05  7:29  0%       ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2009-11-05  7:29 UTC (permalink / raw)
  To: Lin Jen-Shin (aka godfat 真常); +Cc: unicorn list

"Lin Jen-Shin (aka godfat 真常)" <godfat@godfat.org> wrote:
> 2009/11/5 Lin Jen-Shin (aka godfat 真常) <godfat@godfat.org>:
> > On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
> >> On the other hand, does Innate make it possible to do transparent
> >> upgrades (since rackup does not)?  I'll look into it a bit more later...
> >
> > I am not sure what do you mean transparent here,
> 
> Oops, accidentally sent incomplete mail, sorry.
> 
> I am not sure what do you mean transparent here,
> but I would guess Innate work better than rackup. :p

Transparent, zero-downtime upgrades (USR2 + QUIT) that Unicorn
can do like nginx[1].

The issue here with rackup is that it changes ARGV with the option
parser before Unicorn can get to it.  So when Unicorn receives the USR2
signal and respawns itself, it won't be able to spawn a child with the
same command-line options as its parent.  Using the "unicorn" script
will allow it to always save its ARGV before OptionParser has a chance
to mangle it.

[1] - http://unicorn.bogomips.org/SIGNALS.html
-- 
Eric Wong
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[relevance 0%]

* Re: About Unicorn Rack handler
  @ 2009-11-05  4:47  7%     ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05  7:29  0%       ` Eric Wong
  0 siblings, 1 reply; 30+ results
From: Lin Jen-Shin (aka godfat 真常) @ 2009-11-05  4:47 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

2009/11/5 Lin Jen-Shin (aka godfat 真常) <godfat@godfat.org>:
> On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
>> On the other hand, does Innate make it possible to do transparent
>> upgrades (since rackup does not)?  I'll look into it a bit more later...
>
> I am not sure what do you mean transparent here,

Oops, accidentally sent incomplete mail, sorry.

I am not sure what do you mean transparent here,
but I would guess Innate work better than rackup. :p

cheers,
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[relevance 7%]

* Unicorn/Rainbows! mailing list migration
@ 2009-10-29 22:44  4% Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2009-10-29 22:44 UTC (permalink / raw)
  To: mongrel-unicorn, rainbows-talk; +Cc: meta

As I'm sure you've all heard by now, RubyForge will be moving to a
read-only state and we'll have to migrate our mailing lists somewhere.

== librelist

I'm leaning strongly towards librelist.com.  I've had good, but limited
experiences with it.  I like that librelist has no logins or accounts to
deal with; just email the list you want to join and reply to the
automated message to subscribe.  It also has downloadable archives
via rsync.

librelist is run by Zed Shaw, the same guy who started Mongrel (which
eventually led us to Unicorn).  While I don't believe in giving any
single entity too much power and influence, Zed's done a lot of good for
Mongrel and handed it off gracefully when he didn't want to work on it
anymore.  For these reason, I think librelist will be in good hands for
years to come.

I probably would've picked librelist if it had been around when I
started this RubyForge list in May 2009.  I started Rainbows! more
recently, but continued using RubyForge because I wanted everything
Rainbows!-related on RubyForge.org (oops!).


== Other options

Google Groups is out.  Spam has been a big problem in the few groups
I've joined and I'd rather trust Zed than Google for mailing lists.
Also I don't know of a way to get archives from Google without scraping.

SourceForge - I've had spam problems in the past, mailman...

Savannah - no idea about the quality, but uses mailman...

I've also considered hosting the list ourselves, but that might be
too much work and spreading ourselves too thin at the moment.


Any other list hosting options out there we should consider?  It must be
a mailing list that does not mangle plain-text patches.

Or any votes in favor of migrating to librelist sooner rather than
later?  I'll work on getting the gmane NNTP mirrors moved over as
well.


== Other stuff related to RubyForge going read-only...

Gem hosting will (obviously) be taken care of by our new
Gemcut^WRubygems.org overlords.

The tarballs for non-RubyGems users will probably just be moved to a
files/ section of the websites; it'll be even be easier to find and
download tarballs in automated scripts that way, too.

Since we're using git, our repositories are mirrored everywhere already
and was never centrally-hosted on RubyForge in the first place.

http://rainbows.rubyforge.org/ will probably be redirected to
http://rainbows.bogomips.org/ (same box as the Unicorn website).

Should you ever want to access either of the sites offline, just make
sure you have RDoc 2.4.x ("gem install rdoc" if you're on 1.8) and run
`make doc' or `gmake doc' in the latest source tree.

-- 
Eric Wong

^ permalink raw reply	[relevance 4%]

* Re: 0.93.0 gem bug report: permissions snafu
  @ 2009-10-03  1:23  7% ` Eric Wong
  0 siblings, 0 replies; 30+ results
From: Eric Wong @ 2009-10-03  1:23 UTC (permalink / raw)
  To: Jay Reitz; +Cc: mongrel-unicorn

Jay Reitz <jreitz@gmail.com> wrote:
> I found some permissions issues with the 0.93.0 gem release.  In
> short, the installed permissions are excessively strict and incorrect.
>  The following files have the mode 700 rather than the correct 755
> mode:

> This prevents unicorn from being started by a non-super user, as many
> people are wont to do.  There are also a smattering of document files
> and the gemspec with incorrect permissions but this it less of an
> issue.

Oops, I just uploaded v0.93.1 which should fix this.  Huge thanks for
reporting this (and using Unicorn :)   I never would've noticed
as all my Ruby and Gem installations are done as regular users

-- 
Eric Wong

^ permalink raw reply	[relevance 7%]

Results 1-30 of 30 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2009-10-02 23:54     0.93.0 gem bug report: permissions snafu Jay Reitz
2009-10-03  1:23  7% ` Eric Wong
2009-10-29 22:44  4% Unicorn/Rainbows! mailing list migration Eric Wong
2009-11-04 12:37     About Unicorn Rack handler Lin Jen-Shin (aka godfat 真常)
2009-11-04 17:07     ` Eric Wong
2009-11-05  4:43       ` Lin Jen-Shin (aka godfat 真常)
2009-11-05  4:47  7%     ` Lin Jen-Shin (aka godfat 真常)
2009-11-05  7:29  0%       ` Eric Wong
2009-12-16  1:37     workers created when request comes in? Joseph McDonald
2009-12-16  2:37     ` Eric Wong
     [not found]       ` <73096a160912152148l4eea211eq972fcea3ebdf9112@mail.gmail.com>
2009-12-16  6:05  7%     ` Eric Wong
2010-06-09 12:58     Working directory and config.ru Pierre Baillet
2010-06-09 18:04  7% ` Eric Wong
2010-06-10  9:58  0%   ` Eric Wong
2011-01-23 21:28     "Read error: #<IOError: closed stream>" and uploads Alexey Bondar
2011-01-24  0:59     ` Eric Wong
     [not found]       ` <20110124181919.GA24783@dcvr.yhbt.net>
     [not found]         ` <BE4CE2A9-B804-4EFE-9F68-8E8253B4B82D@gmail.com>
2011-01-25  0:51           ` Eric Wong
     [not found]             ` <C83FE4C4-F4FB-48BC-8FC6-4E1B1B26F2D8@gmail.com>
2011-01-25  3:17  0%           ` Eric Wong
2011-04-12 16:13     Struggling with logrotate and unicorn Emmanuel Gomez
2011-04-12 17:58     ` Eric Wong
2011-04-12 18:36       ` Emmanuel Gomez
2011-04-12 18:59         ` Eric Wong
2011-04-12 22:38           ` Emmanuel Gomez
2011-04-12 22:51             ` Eric Wong
2011-04-12 23:01  6%           ` Emmanuel Gomez
2011-04-21  6:56     [ANN] unicorn 3.6.0 - small fixes, PRNG workarounds Eric Wong
2011-04-26 22:38     ` ghazel
2011-04-26 23:01  6%   ` Eric Wong
2011-06-06 17:31     [PATCH] Ensure that 'make gem' builds the documentation too Hongli Lai
2011-06-06 17:51  6% ` Eric Wong
2011-06-07 15:11  0%   ` Hongli Lai
2011-06-07 17:06  0%     ` Eric Wong
2012-02-01 18:14     FreeBSD jail and unicorn Eric Wong
     [not found]     ` <CB5014D7.892%philipp.bruell@skrill.com>
2012-02-02 19:31       ` Eric Wong
2012-02-02 22:27         ` Eric Wong
2012-02-02 22:41  7%       ` Eric Wong
2012-10-29 17:44     Combating nginx 499 HTTP responses during flash traffic scenario Tom Burns
2012-10-29 18:45     ` Eric Wong
2012-10-29 21:53       ` Eric Wong
2012-10-30 20:40         ` Tom Burns
2012-10-30 21:37           ` Eric Wong
2012-11-02 17:59             ` Tom Burns
2012-11-02 19:38               ` Eric Wong
2012-11-03 22:45                 ` Tom Burns
2012-11-05 11:48                   ` Eric Wong
2012-11-06  3:16                     ` Tom Burns
2012-11-06 21:23  6%                   ` Eric Wong
2013-02-08 13:54     Unicorn 4.6.0 version is 4.5.0 Maurizio De Santis
2013-02-08 18:55  4% ` [PATCH] auto-generate Unicorn::Const::UNICORN_VERSION Eric Wong
2013-02-25 12:57     weird C extension bug from Ruby 2.0.0-p0 Eric Wong
2013-02-26  2:56  6% ` [PATCH] http: avoid frozen string bug in filter_body Eric Wong
2013-11-04 18:04     Unicorn 4.7.0 tests fail on OSX 10.7.5 and debian squeeze Andrew Hobson
2013-11-04 18:37  5% ` Eric Wong
2013-11-25  6:01     permissions on ChangeLog and NEWS Ken Dreyer
2013-11-25  6:52  7% ` Eric Wong
2014-12-03  9:50     No, passenger 5.0 is not faster than unicorn :) Bráulio Bhavamitra
2014-12-03  9:56     ` Sam Saffron
2014-12-03  9:57  7%   ` Sam Saffron
2015-02-18  9:36  6% [PATCH] explain 11 byte magic number for self-pipe Eric Wong
     [not found]     <f1d5eacb-b6a2-be96-34aa-fe061a194a62@onenetbeyond.org>
     [not found]     ` <CAAB-Kcnwzc8Tcszv3FCPkyJRKRCsHRH6k_qBhKfBpSODxqKy5g@mail.gmail.com>
2016-10-28  0:23  6%   ` trying to update unicorn to 5.1, build failure: VERSION= must be specified Eric Wong
2017-02-15 18:45  7% response_start_sent (check_client_connection) is staying Eric Wong
2017-03-24  0:33  7% [PATCH] doc: note after_worker_exit is also 5.3.0+ Eric Wong
2017-04-01  8:08     [ANN] unicorn 5.3.0 - Rack HTTP server for fast clients and Unix Eric Wong
2017-04-02  2:14  7% ` Eric Wong
2020-04-15  5:06     Sustained queuing on one listener can block requests from other listeners Stan Hu
2020-04-15  5:26     ` Eric Wong
2020-04-16  5:46       ` Stan Hu
2020-04-16  6:59  6%     ` Eric Wong
     [not found]     <F6712BF3-A4DD-41EE-8252-B9799B35E618@github.com>
     [not found]     ` <20210311030250.GA1266@dcvr>
     [not found]       ` <7F6FD017-7802-4871-88A3-1E03D26D967C@github.com>
2021-03-12  9:41  2%     ` Potential Unicorn vulnerability Eric Wong
2021-03-12 11:14  0%       ` Dirkjan Bussink
2021-03-12 12:00  0%         ` Eric Wong
2023-06-11 22:56     [PATCH 0/4] various test fixes Eric Wong
2023-06-11 22:58  3% ` [PATCH 1-4/4] " Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/unicorn.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).