[Dancer-users] dancer2's prototype is there, feedback needed
Assaf Gordon
gordon at cshl.edu
Wed Oct 12 19:48:57 CEST 2011
Hello Alexis,
I'm still getting this behavior (POST with parameters is stuck) with the latest dancer2.
But I have more details.
Alexis Sukrieh wrote, On 10/08/11 05:54:
> 2011/10/3 Assaf Gordon <gordon at cshl.edu>:
>> ## Access the app with "POST" (and parameters) - FAILS - the request hangs, BEFORE even reaching my 'post' handler code.
>> $ curl -X POST -d name=foobar http://localhost:3000/
>> [ XXXX - Stuck - XXXX ]
>
> I can't reproduce that. Here is what I did:
>
> $ curl -I -X POST http://0:3000/
> HTTP/1.0 200 OK
The missing part is adding POST parameters, with the following command:
$ curl -I -X POST -d "hello=world" http://0:3000/
Here's what happens in my setup, to the best of my ability to debug dancer2:
1. Request arrives (after some trials and tribulations) to "Dancer::Core::Dispatcher->dispatch()" which finds the appropriate route.
2. "Dispatch()" runs:
my $http_method = lc $context->request->method;
but $context->request DOES NOT exist, so the "moo" auto-builder thingy calls "Dancer::Core::Context::_build_request".
3. A new Dancer::Core::Request object is created, goes to "Dancer::Core::Request->BUILD".
Eventually calls "$self->_build_params()".
4. "Dancer::Core::Request->_build_params()" calls "_parse_post_params()"
5. "Dancer::Core::Request->_parse_post_params()" calls "_read_to_end()"
6. "Dancer::Core::Request->_read_to_end()" looks like this:
================
sub _read_to_end {
my ($self) = @_;
my $content_length = $self->content_length;
return unless $self->_has_something_to_read();
if ($content_length > 0) {
while (my $buffer = $self->_read()) {
$self->{body} .= $buffer;
$self->{_http_body}->add($buffer);
}
}
return $self->{body};
}
===============
I assume in your testing (without POST parameters), "content_length" was zero, and so nothing is read, and the function returns undef.
In my case, "content_length" is the length of the POST parameters (e.g. "hello=world" = 11 characters).
So it calls "$self->_read()".
7. "read_()" looks like this (without my sprinkled "warn" statements):
===================
sub _read {
my ($self,) = @_;
my $remaining = $self->content_length - $self->{_read_position};
warn "#### remaining = $remaining";
my $maxlength = $self->{_chunk_size};
warn "#### maxlength = $maxlength";
return if ($remaining <= 0);
my $readlen = ($remaining > $maxlength) ? $maxlength : $remaining;
warn "#### readlen = $readlen";
my $buffer;
my $rc;
warn "##### before read";
warn "###### input_handle = " . dump($self->input_handle) ;
$rc = $self->input_handle->read($buffer, $readlen);
warn "##### after read";
if (defined $rc) {
$self->{_read_position} += $rc;
return $buffer;
}
else {
croak "Unknown error reading input: $!";
}
}
===================
And Dancer2 is stuck in the:
$rc = $self->input_handle->read($buffer, $readlen);
Statement, unable to read the expected number of characters.
The printed output is:
========
#### remaining = 11 at /home/gordon/sources/dancer2/lib/Dancer/Core/Request.pm line 552, <DATA> line 16.
#### maxlength = 4096 at /home/gordon/sources/dancer2/lib/Dancer/Core/Request.pm line 554, <DATA> line 16.
#### readlen = 11 at /home/gordon/sources/dancer2/lib/Dancer/Core/Request.pm line 559, <DATA> line 16.
##### before read at /home/gordon/sources/dancer2/lib/Dancer/Core/Request.pm line 563, <DATA> line 16.
###### input_handle = do {
require Symbol;
bless(Symbol::gensym(), "FileHandle");
} at /home/gordon/sources/dancer2/lib/Dancer/Core/Request.pm line 564, <DATA> line 16.
========
Because the "read" function never returns.
Not sure if this is a problem in my setup or in dancer2, but it's reproducible every time.
regards,
-assaf.
More information about the Dancer-users
mailing list