Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

POST request problem

by bangor (Monk)
on Jun 03, 2016 at 13:27 UTC ( [id://1164862]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks, I am trying to send a POST request using LWP::UserAgent and HTTP::Request. The example I was given looks a bit weird to me but this is it:
POST /endpoint?user=yyy&pass=zzz HTTP/1.1 Host: api.xxx.com Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4 +YWxkTrZu0gW ----WebKitFormBoundary7MA4YWxkTrZu0gW
This is the code I have tried:
my $url = 'https://api.xxx.com/endpoint?user=yyy&pass=zzz'; my $request = HTTP::Request->new( 'POST', $url ); $request->content_type('multipart/form-data'); print $request->as_string; my $response = $ua->request($request); print $response->as_string;
The request
POST https://api.xxx.com/endpoint?user=yyy&pass=zzz Content-Type: multipart/form-data
The response:
HTTP Error 411. The request must be chunked or have a content length.
How can I get HTTP::Request to do this. I tried giving it a content of empty string but no different. TIA for any help

Replies are listed 'Best First'.
Re: POST request problem
by Corion (Patriarch) on Jun 03, 2016 at 13:31 UTC

    Have you considered giving a Content-Length header?

      I did try $request->content_length(0); but then got "Not Found". Thing is there is no content. From research I saw something about a header "Transfer-Encoding: chunked" but I can't seem to set that.

        Have you looked at what exactly you are sending now? I would suspect that whatever "not found" error you're getting now is the next step.

        Personally, I don't know how to make LWP::UserAgent send content in a "chunked" encoding. Maybe consider first simply printing directly all the headers and body yourself if you want to follow up that avenue.

Re: POST request problem
by Anonymous Monk on Jun 04, 2016 at 00:36 UTC
Re: POST request problem
by hippo (Bishop) on Jun 03, 2016 at 15:49 UTC

    Unless I'm missing something obvious, your POST request has no payload, unlike the sample you've been given, ie. you never call the content method of your request object to set the data. This may be all that is required.

      Hi hippo, you may have missed last line of my original question - I tried giving it a content of an empty string but it did not generate the boundary in the header and body which is what I think is necessary. The example I was given comes from the Postman app - if you put a URL in and then choose "multipart/form-data" that is the request it generates. I am trying to duplicate that.

        Yes, somehow missed reading that, thanks.

        However, I would recommend giving it some actual content (not an empty string). Do the folks running the server not suggest what the POSTed content should be? There is little point to a POST request with no content.

        Adding to what hippo said, from RFC 2616:

        The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

        So, many webservers require that POST requests have actual content. However, it's up to whomever designed/implemented the handler pointed to by the URI to describe what that content should be.

        but it did not generate the boundary in the header and body which is what I think is necessary.

        Its highly unlikely it would be necessary (highly unlikely), but anything is possible (stupid servers exist)

        Server should only care about "content", the chunked/boundary stuff is just ways to deliver "content", only some kind of http test server would "require" that type of request

Re: POST request problem
by papidave (Pilgrim) on Jun 06, 2016 at 13:40 UTC
    When I use LWP, I use the post() method instead of directly constructing the HTTP::Request object myself, and have never run into any issues. The Content for your request should be the user and pass arguments from your URL -- which, as a side effect, keeps the web server from logging user account info into its access log. I suspect that's the reason you wanted to POST in the first place.

    In any case, this would give you something like the following:

    #!/usr/bin/perl -w use strict; use LWP::UserAgent; my $auser = 'jebediah'; # kerman my $apwd = 'KSP#bada55'; # green my $page = 'http://api.xxx.com/endpoint'; my @args = ( user => $auser, pass => $apwd ); my $agent = new LWP::UserAgent(); die "couldn't create agent\n" unless $agent; my $response = $agent->post( $page, Content => \@args ); die "couldn't post web page\n" unless $response; # process $response->header() here if desired. print $response->content(), "\n";
    UPDATE: cleaned up the account info so i'm not hard-coding @args as much.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1164862]
Approved by beech
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2024-04-23 20:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found