talexb has asked for the wisdom of the Perl Monks concerning the following question:

I'm sending a GET to what I presume is a Windows Virtual Server, and it seems to want

GET /server/Api.asmx/FooReactivateAccount?UserId=blah HTTP/1.1 Host: staging-foo.bar.com
as the request. If I build the request manually,
use HTTP::Request; $r = HTTP::Request->new('GET','http://staging-foo.bar.com/server/Api.a +smx/FooReactivateAccount?UserId=blah'); print $r->as_string
I get the result
GET http://staging-foo.bar.com/server/Api.asmx/FooReactivateAccount?Us +erId=blah
without the all important HTTP/1.1 at the end.

I've dug through the CPAN pages and the code and haven't found any good ideas. Can anyone suggest what I'm doing wrong?

Alex / talexb / Toronto

"Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Replies are listed 'Best First'.
Re: Trying to get HTTP/1.1 at end of request
by Corion (Patriarch) on Apr 13, 2009 at 18:58 UTC

    From looking at the ->as_string source, you need the un(der)documented ->protocol method:

    perl -MHTTP::Request -e "$r=HTTP::Request->new(GET => 'http://perlmonk +s.org');$r->protocol('HTTP/1.1');print $r->as_string" GET http://perlmonks.org HTTP/1.1

      Thanks -- I did know about the protocol method, but couldn't understand how I could use it before the message went out. Your code does output the correct thing from the debugger, but now I'm getting an error from HTTP::Message that it's having trouble cloning the headers (line 27).

      The investigation continues. Thanks!

      Update: OK -- going through HTTP::Request means you have to reorganize the parameters from a hashref to a refarray to a flattened hash:

      $refhash = { UserId => 533, Something => 'foobart' } $refarray = [ map { $_, $refhash->{$_} } keys %$refhash ];
      so that the code in HTTP::Headers
      sub header { my $self = shift; Carp::croak('Usage: $h->header($field, ...)') unless @_; my(@old); my %seen; while (@_) { my $field = shift; my $op = @_ ? ($seen{lc($field)}++ ? 'PUSH' : 'SET') : 'GET'; @old = $self->_header($field, shift, $op); } return @old if wantarray; return $old[0] if @old <= 1; join(", ", @old); }
      accepts the data. Now I'm back to getting a 500 Internal Server error from the server I'm hitting .. I'll check back tomorrow when I can talk to the SysAdmin in Europe.

      Alex / talexb / Toronto

      "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      Here's the solution I finally ended up with. First, I build the command string using the parameters hashref:

      my $cmd = "$baseURL/$command?" . join( '&', map { "$_=" . uri_escape( $parameters->{$_} ) } keys %$parameters );
      Then I build the HTTP::Request object, adding the Host parameter (as a flattened hashref), and set the request's protocol:
      my $request = HTTP::Request->new( 'GET', $cmd, [ 'Host', $host ] ); $request->protocol('HTTP/1.1');
      Finally, I use LWP::UserAgent to send the request:
      my $agent = LWP::UserAgent->new(); my $response = $agent->request($request);
      So it looks like both the HTTP/1.1 at the end of the request and the Host parameter in the header were required.

      Alex / talexb / Toronto

      "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds