On Fri, 09 Dec 2011 15:10:47 +0100
Jakob Bohm <jb-open...@wisemo.com> wrote:

> Hi, nice code, I spot a few questionable details, but only Warn#5
> might cause missing bytes.

> >          if (!field) return newSV(0);
> Warn#1: It is probably more efficient to return PL_sv_undef, avoiding
> an allocation in a potential memory full situation

Point taken. 

> Bug #2: must be allocated as [len+1] because of Bug#7 below.

WRT to #2 and #7, the caveat I've seen about this has to do with
handing a perl string into a C function that treats it like a C-string.
Eg, length() and SvPV(data, 0) use strlen.  However, if you set a
length manually, = and .= will use that.  Otherwise putting binary data
into a perl string would be near pointless.

Ie, it's not essential to null terminate here as long as you are aware
of the potential for runaway string opts.

However,  after exhausting the other possibilities, I tried this.  Kind
of a hassle because I then had to add chop() here and there.  But lo
and behold, it worked.  Considering each call of the sysread only got
16KB at most -- meaning it is called thousands of times for a 20 MB
upload -- I'm baffled as to why this would cause such a small and
irregular loss.  The POST is not accumulated using perl either, or C
string functions, just pointers.

I don't like baffled, I like to think I know why ;)  Good thing the
perlish are everywhere.  Thanks much -- I have a few more
comments/questions about your comments if you're interested.

> Warn#3: It is probably more efficient to do
>                     SvGrow(buf, len + 1);
>                     unsigned char *data = SvPV_nolen(buf);

Good idea; I then have to reset the length to the actual bytes read,
but this will save a copy.  Thanks.

> Warn#4: The calling perl code may need to distinguish between 
> SSL_ERROR_WANT_READ
>             and SSL_ERROR_WANT_WRITE, because the needed select()
> call will be different

I haven't actually seen SSL_ERROR_WANT_WRITE happen here; initially
I was testing for them separately.  In the SSL_read man page, it says:

"As at any time a re-negotiation is possible, a call to SSL_read() can
also cause write operations! The calling process then must repeat the
call after taking appropriate action to satisfy the needs of SSL_read
(). The action depends on the underlying BIO . When using a
non-blocking socket, *nothing is to be done*..."

So, if I were to handle them differently, how would I do it?

> Warn#5: Remember to ensure the perl code passes the exact same 
> parameters on retry!

Yep.  I actually made the "data" buffer global temporarily to make sure
the address stays the same, no change.  And the length remaining (based
on bytes read and content-length) is used for the len arg; than will
not change if the last call returned nothing.

> > // return buffer contents to perl
> >          sv_setpvn(buf, data, bytes);
> Bug#8: Note that if bytes==0 (a valid situation), then sv_setpvn()
> Bug#will
>      act like sv_setpvn(buf, data, strlen(data))
>      So in addition to Bug#7 above, bytes==0 could turn into
>      a variable number of random bytes getting put in buf.

Good catch, I should change that to prevent the wasted allocation.
However, it would not matter WRT to the collection of data, because
this function returns "bytes" (via SvIV).  Currently I'm
treating 0 the same way I would with a normal socket -- as an
indication that the client disconnected.  Does not seem to be a problem
thus far (ie, SSL_read never returns 0 during the transfer).  I left
the \0 out of the byte count so this does not get screwed up (but
allocated enough in SvCUR_set).

Anyway, seemingly the problem is solved!  Phew.  But if you think I'm
off base about anything here, I'm listening. :)

More thanks -- MK

-- 
"Enthusiasm is not the enemy of the intellect." (said of Irving Howe)
"The angel of history[...]is turned toward the past." (Walter Benjamin)

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to