Truncated request bodies

Eric Wong normalperson at yhbt.net
Sat Oct 24 20:04:35 EDT 2009


Vadim Spivak <vadim at spivak.net> wrote:
> > Hi Vadim,
> >
> > What's the output of that standalone ruby example for you?  Is there a
> > bug filed with ruby-core I could look at?
> 
> "Should be 5: 0"
> 
> I haven't had a chance to file a bug yet and couldn't find
> 
> Also, if you don't set sync to true, then you get the expected output
> 5 instead of 0.

Interesting....

I bet it doesn't fail if you skip the f.read in there.

> > Also, does using f << or f.syswrite change things?
> > f.sync = true should really make it unnecessary...
> 
> I tried both and they didn't make a difference

sysread (instead of read) + syswrite() would've made a difference,
I very much hope, at least.

> >        f = File.open("bar", File::RDWR|File::CREAT, 0600)

                                ^-- btw, I would put File::TRUNC
				    there just in case because I
				    got 10 the 2nd time running it :x

> >        f.sync=true
> >        f.read  # why is this here?
> >        f << "Hello"  # or f.syswrite
> >
> >        # would an explicit f.flush here work? shouldn't be needed
> >        # with f.sync = true
> >        puts "Should be 5: #{f.pos}"
> >        f.close
> >
> > > I couldn't reproduce this on 1.9.1 on OS X or 1.8.7 on Linux.

This could be a stdio bug...  1.9.1 uses only the saner unistd.h
functions so it's immune to stdio bugs, but 1.8.7 uses stdio with
explicit fflush() when sync=true instead of calling
setvbuf(..._IONBF...) to disable buffering like a normal app would.

Looking at io.c in 1.8.7-p72, it even seems to call
setvbuf(..._IOFBF...) for full buffering on FreeBSD regardless
of sync mode (!)

> > I'll definitely need help with testing this then since I only have
> > Linux.

Does the following patch fix things for you?

diff --git a/lib/unicorn/util.rb b/lib/unicorn/util.rb
index 6b35426..0f517e9 100644
--- a/lib/unicorn/util.rb
+++ b/lib/unicorn/util.rb
@@ -54,7 +54,6 @@ module Unicorn
         end
         File.unlink(fp.path)
         fp.binmode
-        fp.sync = true
         fp
       end
---

On the flip side, I'm once again tempted to use sysread/sysseek/syswrite
because I have a very intense and long-standing distrust of luserspace
IO buffering libraries.

-- 
Eric Wong


More information about the mongrel-unicorn mailing list