http://qs321.pair.com?node_id=854210


in reply to Re^2: Does CGI::Application expose a HTTP::Request object?
in thread Does CGI::Application expose a HTTP::Request object?

The value of $header doesn't seem to work for HTTP::Request, it complains with "Bad header argument". Further, it doesn't seem to hold the headers of the request, but of the response CGI::Application is about to deliver, for example in my test it held a "Content-Type: text/html" header.

That should have been @{ $self->header_props } because HTTP::Request wants a reference to an array of key-value pairs but in any case it wouldn't work because as you pointed out, it gives outgoing headers not incoming.

You would have to get the special HTTP envvars out of the environment and make them into headers.

Your elaborate attempts to get the $content *of the request* do not seem to work. None of my tests showed the request content getting through. my @params = $q->param should return all parameters but is empty except for those keys passed in $ENV{QUERY_STRING}, no PUTDATA etc. there. Is a CGI::Fast + CGI::Application based script aware of request data which is not coming from POST requests - at all?

As I alluded to in my last reply, I think the problem is POSTDATA and PUTDATA don't get set in some cases. (They are not real params but specially set up by CGI.pm) I think this happens if the MIME type is application/x-www-form-urlencoded or multipart/form-data which is usual for an HTML form. So in this case or if we can't get the them for any other reason, we should read from standard input based on the Content-Length header (which doesn't seem to have CGI.pm method I don't know why.)

Try this. Again untested I'm afraid.

sub request_from_cgi { my ($self) = @_; my $q = $self->query; my $uri = $q->url; my $method = uc $q->request_method; # probably not an exhaustive list. my @http_envvars = qw/ DOCUMENT_ROOT HTTP_COOKIE HTTP_REFERER HTTP_USER_AGENT HTTPS PATH QUERY_STRING REMOTE_ADDR REMOTE_HOST REMOTE_PORT REMOTE_USER REQUEST_METHOD REQUEST_URI SCRIPT_FILENAME SCRIPT_NAME SERVER_ADMIN SERVER_NAME SERVER_PORT SERVER_SOFTWARE /; my $headers = {}; foreach my $var (@http_envvars) { if (exists $ENV{$var}) { $headers->{$var} = $ENV{$var}; } } my $content = undef; if ($method eq 'POST') { $content = $q->param('POSTDATA'); } elsif ($method eq 'PUT') { $content = $q->param('PUTDATA'); } if (!defined $content) { my $len = $ENV{CONTENT_LENGTH} || 0; read STDIN, $content, $len; } return HTTP::Request->new( $method, $uri, HTTP::Headers->new($headers), $content, ); }

--
જલધર