On Saturday December 13, 2003 06:27, A. Pagaltzis wrote:
> * David Robins <[EMAIL PROTECTED]> [2003-12-13 12:08]:
> > I'd like to contribute an HTTP::Parser module to CPAN.
...
> > "parse" which takes some text and either:
> > dies (on error) (I can return a string if people prefer it), or returns:
> > 0: want more data but don't know how much
> > -1: like 0 but a hint that we want a line
> > <n>: want n bytes more
> > HTTP::Request object: finished parsing the request.
>
> You're trying to make a single value do duble duty, and that
> doesn't work too well. The following code is the best I could
> come up with using your interface - note this is after I've
...
> my ($req, $ret);
> my $data = get_data(-1);
>
> until(ref($req = $ret = $httpp->parse($data))) {
> if(not $ret) {
> # 0, need more data, no idea how much
> $data = get_data(-1);
> }
> elsif(-1 == $ret) {
> $data = get_data(-1);
> # [ split off one line, feed it in ]
> }
> else {
> # $ret bytes (probably the request body, right?)
> $data = get_data($bytes);
> }
> }
Thanks for taking the time to suggest changes, and I probably will change the
return value to make it more "perlish" etc. A note about the above: a hint
that it wants X bytes or a complete line is just that, a hint, and it's
perfectly fine to not send a full line (you'll just get back the same
"want-line" hint) or to send more than a full line; similarly you don't have
to send exactly X bytes when "requested" to.
I've also thought of another condition that isn't detected, though: if you
send too much data (more than is required for a request), parse() won't tell
you how much you went over.
...
> Code using this interface would read something like this:
>
> my $data = get_data(-1);
>
> while(my $bytes = $httpp->parse($data)) {
I like the ability to do that which you wouldn't be able to with a list;
perhaps get_request can also return the number of extra bytes (if called in
list context).
> $data = $bytes > 0 ? get_data($bytes) : get_data(-1);
>
> if(-2 == $bytes) {
> # [ split off one line, feed it in ]
> }
> }
>
> my $req = $httpp->get_request;
>
> Note how this loop handles all the same cases the above convolute
> deals with, and differs only in that it's about a hundred times
> clearer to read.
Well, to be fair, the "above convolute" can be reduced to:
my ($data,$ret) = ('');
until(ref($ret = $httpp->parse($data))) {
$data = $ret > 0 ? get_data($ret) : get_data(-1);
# handle -1 condition and send only a single line if desired
}
I'll make the following changes:
parse() will return:
0 on completion of request (call request() to get the request, call data() to
get any extra data)
>0 meaning we want (at least - may want more later if we're using chunked
encoding) that many bytes
-1 meaning we want an indeterminate amount of bytes
-2 meaning we want (at least) a line of data
parse() will also accept undef as a parameter
data() will return:
the current unparsed data, this only really has relevance after a request is
completed (maybe also a data_size() method?)
request() will return:
the HTTP::Request object for the last completed request, or undef if none
--
Dave
Isa. 40:31