For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > July 2006 > libwww-POST Issue









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author libwww-POST Issue
AZSTYX

2006-07-28, 6:59 pm

Hello Folks!

Environment:
libwww-perl: 5.805
OS: Solaris 8
Perl: 5.8.4

Issue Summary:
Issue with posting form variables in POST operation using
HTTP::REQUEST.

I have a script that sends a form via POST with one form element
'DownloadFormat=ascii'.
I first wrote the script using pure UserAgent POST and all works fine.
However, I tried (just for a learning experience) to utilize
HTTPS::Request method
and I have an unexplained issue.
According to the lwpcook.pod, they give an example:
HTTP::REQUEST example format:
code:
my $req = HTTP::Request->new(POST => 'http://www.perl.com/cgi-bin/BugGlimpse'); $req->content_type('application/x-www-form-urlencoded'); $req->content('match=www&errors=0'); my $res = $ua->request($req);

UserAgent POST example format:
code:
my $req = POST 'http://www.perl.com/cgi-bin/BugGlimpse', [ search => 'www', errors => 0 ]; print $ua->request($req)->as_string;


In reviewing this info, I see that the author is passing the form
variables and
values in the ::REQUEST via the $req->content(). I am not understanding
this call
of why the form varaibles would be passed in the content section?
Especially in
the next example when they use the variable 'search" and in the first
example
they use the variable 'match' (I guess thats another question?)

The only way I was able to get the script to work properly was to code
the
single form variable and value ('DownloadFormat=ascii') in the URL as:
https://10.10.10.10:1954/dynamic/Fi...oadFormat=ascii
AND I also HAD TO specify something (didn't seem to matter what) in the
content() method.
To make it work I used some garbage text: $httpReq->
content('Comment=justacomment') ;

Q: Why did I have to pass my form variable and value like I would if I
was doing a GET,
when I am doing a form POST operation?
(I prefixed my URL with '?DownloadFormat=ascii').
Q: What is the proper method using HTTP::REQUEST to pass form
variables and values when
doing a POST operation?
Q: Why did I have to specify something in content(), even though it
was just garbage code?
($httpReq-> content('Comment=justacomment') ;)(It would not work
otherwise!)

My script:

code:
#!/export/ieapps/common/perl5/perl-5.8.4/bin/perl # getwsd3.pl - LWP demo - downloads a radware WSD config ascii file. # utilizes HTTPS and login credentials, https request object # interfacing with https request object is depreciated form # usage: lwpdemo.pl <devname> <devipaddr> <port> <uid> <passw> # output: /export/ieapps/local/test/<devName.asc> use strict; use warnings; use LWP; ######################################## ##### my $urlConfigFile = '/dynamic/File/Configuration/ReceivefromDevice' ; my $urlDeviceinfo = '/dynamic/Device/DeviceInformation'; my ($ua, $httpReq, $httpResp, $url, $baseUrl, $credUrl, $strReq); my ($devName, $devIP, $port, $UID, $upassw); my ($statusLine, $statusCode, $statusMsg, $contentResponse); my $asciiFile = "/export/ieapps/local/test/"; ######################################## ######### if (@ARGV == 5) { # if there are 5 arguments $devName = $ARGV[0]; $devIP = $ARGV[1]; $port = $ARGV[2]; $UID = $ARGV[3]; $upassw = $ARGV[4]; } else { die "Error 01: Usage: $0 <devname> <devipaddr> <port> <uid> <passw>\n"; } print "Processing devName [$devName] ip addr [$devIP].\n"; print "Using libwww-perl-$LWP::VERSION\n"; $asciiFile .= "$devName.asc"; print "Output file is [$asciiFile].\n"; $baseUrl = "https://$devIP:$port"; # create base URL $credUrl = "$devIP:$port"; # create URL for credentials print "Base URL [$baseUrl]\n"; ######################################## ############################### # start LWP Processing ######################################## ################################# $ua = LWP::UserAgent->new; # create new user agent object $ua->timeout(15); # set user agent timeout to 15 seconds $url = "$baseUrl$urlConfigFile?DownloadFormat=ascii"; # create URL for getting config ascii file # set up HTTP REQUEST object $httpReq = HTTP::Request->new(POST=>$url) ; # init Request object $httpReq-> content_type('multipart/form-data') ; # content type/mode $httpReq-> content('Comment=justacomment') ; # content garbage to make it work $httpReq-> authorization_basic($UID, $upassw) ; # credentials $strReq = $httpReq->as_string( ); print "\nThe Request:\n$strReq\n"; print "\n\nNow get the WSD config ascii file.\n"; print "Submitting browser request using url [$url].\n"; $httpResp = $ua->request($httpReq) ; $statusLine = $httpResp->status_line(); $statusCode = $httpResp->code(); $statusMsg = $httpResp->message(); print "HTTP Response: StatusLine[$statusLine] Code[$statusCode] Message[$statusMsg]\n"; if ($httpResp->is_success) { print "Request OK.\n"; } else { die "Request failed.\n"; } # ok, save content to file open(FILEO, ">$asciiFile") || die "Error $! Could not open file $asciiFile.\n"; print FILEO $httpResp->content; close(FILEO);



The run results:

code:
dsym03z>./getwsd3.pl device-y 10.10.10.10 1900 admin admin Processing devName [device-y] ip addr [10.10.10.10]. Using libwww-perl-5.805 Output file is [/export/ieapps/local/test/device-y.asc]. Base URL [https://10.10.10.10:1900] The Request: POST https://10.10.10.10:1900/dynamic/Fi...oadFormat=ascii Authorization: Basic aWVhZG1pbjptMWdodHkhTTB1czM= Content-Type: multipart/form-data Comment=justacomment Now get the WSD config ascii file. Submitting browser request using url [https://10.10.10.10:1900/dynamic/Fi...oadFormat=ascii]. HTTP Response: StatusLine[200 OK] Code[200] Message[OK] Request OK. dsym03z>


Appreciate any feedback anyone may have to offer!!!
:)
styx

AZSTYX

2006-07-28, 6:59 pm


AZSTYX wrote:
> Hello Folks!
>
> Environment:
> libwww-perl: 5.805
> OS: Solaris 8
> Perl: 5.8.4
>
> Issue Summary:
> Issue with posting form variables in POST operation using
> HTTP::REQUEST.
>
> I have a script that sends a form via POST with one form element
> 'DownloadFormat=ascii'.
> I first wrote the script using pure UserAgent POST and all works fine.
> However, I tried (just for a learning experience) to utilize
> HTTPS::Request method
> and I have an unexplained issue.
> According to the lwpcook.pod, they give an example:
> HTTP::REQUEST example format:
>
code:
> my $req = HTTP::Request->new(POST => > 'http://www.perl.com/cgi-bin/BugGlimpse'); > $req->content_type('application/x-www-form-urlencoded'); > $req->content('match=www&errors=0'); > my $res = $ua->request($req); >

> UserAgent POST example format:
>
code:
> my $req = POST 'http://www.perl.com/cgi-bin/BugGlimpse', > [ search => 'www', errors => 0 ]; > > print $ua->request($req)->as_string; >

>
> In reviewing this info, I see that the author is passing the form
> variables and
> values in the ::REQUEST via the $req->content(). I am not understanding
> this call
> of why the form varaibles would be passed in the content section?
> Especially in
> the next example when they use the variable 'search" and in the first
> example
> they use the variable 'match' (I guess thats another question?)
>
> The only way I was able to get the script to work properly was to code
> the
> single form variable and value ('DownloadFormat=ascii') in the URL as:
> https://10.10.10.10:1954/dynamic/Fi...oadFormat=ascii
> AND I also HAD TO specify something (didn't seem to matter what) in the
> content() method.
> To make it work I used some garbage text: $httpReq->
> content('Comment=justacomment') ;
>
> Q: Why did I have to pass my form variable and value like I would if I
> was doing a GET,
> when I am doing a form POST operation?
> (I prefixed my URL with '?DownloadFormat=ascii').
> Q: What is the proper method using HTTP::REQUEST to pass form
> variables and values when
> doing a POST operation?
> Q: Why did I have to specify something in content(), even though it
> was just garbage code?
> ($httpReq-> content('Comment=justacomment') ;)(It would not work
> otherwise!)
>
> My script:
>
>
code:
> #!/export/ieapps/common/perl5/perl-5.8.4/bin/perl > # getwsd3.pl - LWP demo - downloads a radware WSD config ascii file. > # utilizes HTTPS and login credentials, https request object > # interfacing with https request object is depreciated form > # usage: lwpdemo.pl <devname> <devipaddr> <port> <uid> <passw> > # output: /export/ieapps/local/test/<devName.asc> > use strict; > use warnings; > use LWP; > ######################################## ##### > my $urlConfigFile = '/dynamic/File/Configuration/ReceivefromDevice' ; > my $urlDeviceinfo = '/dynamic/Device/DeviceInformation'; > my ($ua, $httpReq, $httpResp, $url, $baseUrl, $credUrl, $strReq); > my ($devName, $devIP, $port, $UID, $upassw); > my ($statusLine, $statusCode, $statusMsg, $contentResponse); > my $asciiFile = "/export/ieapps/local/test/"; > > > ######################################## ######### > > if (@ARGV == 5) { # if there are 5 arguments > $devName = $ARGV[0]; > $devIP = $ARGV[1]; > $port = $ARGV[2]; > $UID = $ARGV[3]; > $upassw = $ARGV[4]; > } > else { > die "Error 01: Usage: $0 <devname> <devipaddr> <port> <uid> > <passw>\n"; > } > print "Processing devName [$devName] ip addr [$devIP].\n"; > print "Using libwww-perl-$LWP::VERSION\n"; > $asciiFile .= "$devName.asc"; > print "Output file is [$asciiFile].\n"; > $baseUrl = "https://$devIP:$port"; # create base URL > $credUrl = "$devIP:$port"; # create URL for credentials > print "Base URL [$baseUrl]\n"; > ######################################## ############################### > # start LWP Processing > ######################################## ################################# > $ua = LWP::UserAgent->new; # create new user agent object > $ua->timeout(15); # set user agent timeout to 15 seconds > $url = "$baseUrl$urlConfigFile?DownloadFormat=ascii"; # create URL for > getting config ascii file > > # set up HTTP REQUEST object > $httpReq = HTTP::Request->new(POST=>$url) ; # init Request object > $httpReq-> content_type('multipart/form-data') ; # content type/mode > $httpReq-> content('Comment=justacomment') ; # content garbage to make > it work > $httpReq-> authorization_basic($UID, $upassw) ; # credentials > $strReq = $httpReq->as_string( ); > print "\nThe Request:\n$strReq\n"; > print "\n\nNow get the WSD config ascii file.\n"; > print "Submitting browser request using url [$url].\n"; > $httpResp = $ua->request($httpReq) ; > > $statusLine = $httpResp->status_line(); > $statusCode = $httpResp->code(); > $statusMsg = $httpResp->message(); > print "HTTP Response: StatusLine[$statusLine] Code[$statusCode] > Message[$statusMsg]\n"; > if ($httpResp->is_success) { > print "Request OK.\n"; > } > else { > die "Request failed.\n"; > } > # ok, save content to file > open(FILEO, ">$asciiFile") || die "Error $! Could not open file > $asciiFile.\n"; > print FILEO $httpResp->content; > close(FILEO); > > >

>
>
> The run results:
>
>
code:
> dsym03z>./getwsd3.pl device-y 10.10.10.10 1900 admin admin > Processing devName [device-y] ip addr [10.10.10.10]. > Using libwww-perl-5.805 > Output file is [/export/ieapps/local/test/device-y.asc]. > Base URL [https://10.10.10.10:1900] > > The Request: > POST > https://10.10.10.10:1900/dynamic/Fi...oadFormat=ascii > Authorization: Basic aWVhZG1pbjptMWdodHkhTTB1czM= > Content-Type: multipart/form-data > > Comment=justacomment > > > > Now get the WSD config ascii file. > Submitting browser request using url > [https://10.10.10.10:1900/dynamic/Fi...oadFormat=ascii]. > HTTP Response: StatusLine[200 OK] Code[200] Message[OK] > Request OK. > dsym03z> > >

>
> Appreciate any feedback anyone may have to offer!!!
> :)
> styx



RESOLVED!!
When using this method, code form varaibles in ->content().
Do not use $httpReq-> content_type('multipart/form-data') ; that is
only for uploading files.
For post do not inlcue variables in URL.
New code that works:
code:
$url=dynamic/File/Configuration/ReceivefromDevice $httpReq = HTTP::Request->new(POST=>$url) ; # init Request object $httpReq->content('DownloadFormat=ascii'); # pass form variables $httpReq-> authorization_basic($UID, $upassw) ; # credentials $httpResp = $ua->request($httpReq) ;


Ben Morrow

2006-07-28, 6:59 pm


Quoth "AZSTYX" <azstyx@yahoo.com>:
>
> AZSTYX wrote:

<snip>
[color=darkred]

<snip>
[color=darkred]
> RESOLVED!!
> When using this method, code form varaibles in ->content().
> Do not use $httpReq-> content_type('multipart/form-data') ; that is
> only for uploading files.


No, when using multipart/form-data, make sure the POSTs body is actually
formatted as multipart/form-data. You can't just randomly change the
content-type and expect things to work.

> For post do not inlcue variables in URL.


There are situations where POSTing to a URL including a query-string is
sensible, however they are rare, and do not arise from ordinary form
submission.

Ben

--
Giles: It's very common for Indian spirits to change to animal form.
Buffy: [...] and, 'Native American'. G: Sorry? B: We don't say 'Indian'.
G: Oh, right, yes; always behind on the terms... yes, still trying not to refer
to you lot as 'bloody colonials'. [Buffy, 'Pangs'] benmorrow@tiscali.co.uk
Charles DeRykus

2006-07-29, 3:58 am

AZSTYX wrote:
> AZSTYX wrote:
> ...


> RESOLVED!!
> When using this method, code form varaibles in ->content().
> Do not use $httpReq-> content_type('multipart/form-data') ; that is
> only for uploading files.
> For post do not inlcue variables in URL.
> New code that works:
> [code]
> $url=dynamic/File/Configuration/ReceivefromDevice
> $httpReq = HTTP::Request->new(POST=>$url) ; # init Request object
> $httpReq->content('DownloadFormat=ascii'); # pass form variables
> $httpReq-> authorization_basic($UID, $upassw) ; # credentials
> $httpResp = $ua->request($httpReq) ;
>
>

Another simpler alternative which'll output the correct header; take
care of form encoding; and also output a content-length header (needed
for https POST requests IIRC):

use LWP;
use HTTP::Request::Common qw/POST/;

....
my $r = POST $url, [Comment => 'justacomment'];
$r->authorization_basic($UID, $upassw);
print $r->as_string;


sample output:

POST https://130.130.130.130:23?DownloadFormat=ascii
Authorization: Basic Y2VkOnJ1bndheS0x
Content-Length: 20
Content-Type: application/x-www-form-urlencoded

Comment=justacomment


--
Charles DeRykus
AZSTYX

2006-07-31, 7:11 pm


Ben Morrow wrote:
> Quoth "AZSTYX" <azstyx@yahoo.com>:
>
> <snip>
>
>
> <snip>
>
>
> No, when using multipart/form-data, make sure the POSTs body is actually
> formatted as multipart/form-data. You can't just randomly change the
> content-type and expect things to work.
>
>
> There are situations where POSTing to a URL including a query-string is
> sensible, however they are rare, and do not arise from ordinary form
> submission.
>
> Ben
>
> --
> Giles: It's very common for Indian spirits to change to animal form.
> Buffy: [...] and, 'Native American'. G: Sorry? B: We don't say 'Indian'.
> G: Oh, right, yes; always behind on the terms... yes, still trying not to refer
> to you lot as 'bloody colonials'. [Buffy, 'Pangs'] benmorrow@tiscali.co.uk


Ben, thx for info!

I did get it to work using this code:
code:
$url = "$baseUrl$urlConfigFile"; # create URL for getting config ascii file # set up HTTP REQUEST object $httpReq = HTTP::Request->new(POST=>$url) ; # init Request object $httpReq->content('DownloadFormat=ascii'); # pass form variables $httpReq-> authorization_basic($UID, $upassw) ; # credentials $httpResp = $ua->request($httpReq) ;

So... what is wrong with this approach and how should I have set it up?
I'm ...
Thanks,
Styx

AZSTYX

2006-07-31, 7:11 pm


Charles DeRykus wrote:
> AZSTYX wrote:
>
> Another simpler alternative which'll output the correct header; take
> care of form encoding; and also output a content-length header (needed
> for https POST requests IIRC):
>
> use LWP;
> use HTTP::Request::Common qw/POST/;
>
> ...
> my $r = POST $url, [Comment => 'justacomment'];
> $r->authorization_basic($UID, $upassw);
> print $r->as_string;
>
>
> sample output:
>
> POST https://130.130.130.130:23?DownloadFormat=ascii
> Authorization: Basic Y2VkOnJ1bndheS0x
> Content-Length: 20
> Content-Type: application/x-www-form-urlencoded
>
> Comment=justacomment
>
>
> --
> Charles DeRykus


Hi Charles,
Yes, I actually got this to work just using LWP UserAget POST which
calls the class you mention. I just wanted to understand and see if I
could also get it to work using the http::request methos as well.
thx,
Styx

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com