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@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.