download file after perl post - perl

This request returns a file of type ZIP how can I retrieve that file from that request?
# put timeouts, proxy etc into the useragent if needed
my $ua = LWP::UserAgent->new();
my $req = POST $in_u, Content_Type => 'form-data', Content => $in_r;
my $response = $ua->request($req);
if ($response->is_success())
{
print $response->content;
}

I think you can use the content method on your $req object to get the raw content returned as a result of the POST. If the content is huge, then content_ref method is more suitable and offers to directly manipulate the content.
my $zfile = $req->content;
and crack on $zfile with Archive::Zip as DVK suggested.

You can use Archive::Zip CPAN module

Related

Perl version of this python servicenow script posting a file

So I am going over the Attachment API for ServiceNow, documented here:
https://docs.servicenow.com/integrate/inbound_rest/reference/r_AttachmentAPI-POST.html
For an application I'm working on, I need to write up some Perl code to handle attachments. Unfortunately, the ServiceNow Perl API libraries do not handle attachments larger than 5mb, so I need to use the stock Attachment API that comes with the instance.
From the above link, I saw this example on how to post files with this python code.
#Need to install requests package for python
#easy_install requests
import requests
# Set the request parameters
url = 'https://instance.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=d71f7935c0a8016700802b64c67c11c6&file_name=Issue_screenshot.jpg'
# Specify the file To send. When specifying fles to send make sure you specify the path to the file, in
# this example the file was located in the same directory as the python script being executed.
data = open('Issue_screenshot.jpg', 'rb').read()
# Eg. User name="admin", Password="admin" for this code sample.
user = 'admin'
pwd = 'admin'
# Set proper headers
headers = {"Content-Type":"image/jpeg","Accept":"application/json"}
# Do the HTTP request
response = requests.post(url, auth=(user, pwd), headers=headers, data=data)
# Check for HTTP codes other than 201
if response.status_code != 201:
print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:',response.json())
exit()
# Decode the JSON response into a dictionary and use the data
data = response.json()
print(data)
I've used REST::Client a lot for posting, but unfortunately, I can't find a good example on how to handle the above ^^ but in Perl. How does one use REST::Client to post a file like above?
I've done a temp workaround with this by invoking curl in my scripts, but using REST::Client would be more elegant.
You can use LWP::UserAgent Perl module to achieve the same:
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Fcntl;
use JSON qw[decode_json];
use Data::Dumper;
my $ua = LWP::UserAgent->new;
my $url = 'https://instance.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=d71f7935c0a8016700802b64c67c11c6&file_name=Issue_screenshot.jpg';
my $user = 'admin';
my $pwd = 'admin';
$ua->credentials( 'instance.service-now.com', '<REALM>', $user, $pwd);
my $file = 'Issue_screenshot.jpg';
my $request = HTTP::Request->new( POST => $url );
$request->header( 'Content-Type' => 'image/jpeg');
$request->header( 'Accept' => 'application/json');
$request->header( 'Content-Length' => -s $file);
sysopen(my $fh,$file,O_RDONLY);
$request->content( sub {
sysread($fh,my $buf,1024);
return $buf;
});
my $res = $ua->request($request);
unless($res->code == 201) {
print 'Status: '.$res->code, 'Headers:',$res->headers_as_string,'Error Response:',$res->content;
exit;
}
my $data = decode_json($res->content);
print Dumper($data);

Filling out a form in perl using HTML::Form

I am trying to fill out a form on a separate page and return the data, but my hosting does not support the www::mechanize module. I saw that HTML::FORM would accomplish the same thing but I am getting the error
Can't call method "value" on an undefined value at G:\Programming\test.pl line 12.
Here is the code I have been testing with
use strict;
use LWP::Simple;
use LWP::UserAgent;
use HTML::Form;
use HTML::Strip;
my $base_uri = "UTF-8";
my $url = 'xxxxxxx';
my $form = HTML::Form->parse($url, $base_uri);
$form->value(Zip => '74014');
my $ua = LWP::UserAgent->new;
my $response = $ua->request($form->click);
The first argument for parse is HTML document itself but not the URL.
The required arguments is the HTML document to parse ($html_document)
and the URI used to retrieve the document ($base_uri). The base URI is
needed to resolve relative action URIs. The provided HTML document
should be a Unicode string (or US-ASCII).
So you need to first get this document (with LWP::UserAgent) and parse response:
my $response = $ua->get($url);
if ($response->is_success) {
my $form = HTML::Form->parse($response->decoded_content, $base_uri);
...
}
else {
die $response->status_line;
}

Get redirected url in perl

I want to get last of redirect URL.
like
url_1 : http://on.fb.me/4VGeu
url_2 : https://www.facebook.com/
I want to get url_2 by url_1 in perl.
Previous source is below.
sub get_redirect_location
{
my ($url) = #_;
my $ua = LWP::UserAgent->new;
$ua->proxy('http', 'SAMPLE_PROXY');
my $req = new HTTP::Request(GET => $url);
my $res = $ua->request($req);
return $res->headers_as_string;
}
Thanks in advance.
You can find the request that lead to a response using
$response->request()
You can get the previous response in the chain using
$response->previous()
All together:
while ($response) {
say $response->request()->uri();
$response = $response->previous();
}
You could look at WWW::Mechanize. I have used it before to do something like this.
http://search.cpan.org/~jesse/WWW-Mechanize-1.72/lib/WWW/Mechanize.pm#$mech->redirect_ok()
You may also find this post helpful:
Perl WWW::Mechanize (or LWP) get redirect url

How can I make a HTTP PUT request in perl that contains application/x-www-form-urlencoded data?

How can I make a HTTP PUT request in Perl that contains application/x-www-form-urlencoded data?
This is an equivalent POST request that works:
my $ua = new LWP::UserAgent;
my $response = $ua->post(
$url,
{
"parameter1" => $value1,
"parameter2" => $value2
}
);
How would this be done as a PUT request?
There is no put method in LWP and the PUT function in HTTP::Request::Common does not take form data.
For a discussion if a PUT request with form data is allowed, see Can HTTP PUT request have application/x-www-form-urlencoded as the Content-Type?
This is an example of a PUT request, but it does not contain code to enclose form data: How to make a HTTP PUT request using LWP?
Just make POST-request and change its method to PUT:
use HTTP::Request::Common;
my $req = POST('http://example.com/', Content => [param => 'value']);
$req->method('PUT');
say($req->as_string);

How to POST content with an HTTP Request (Perl)

use LWP::UserAgent;
use Data::Dumper;
my $ua = new LWP::UserAgent;
$ua->agent("AgentName/0.1 " . $ua->agent);
my $req = new HTTP::Request POST => 'http://example.com';
$req->content('port=8', 'target=64'); #problem
my $res = $ua->request($req);
print Dumper($res->content);
How can I send multiple pieces of content using $req->content? What kind of data does $req->content expect?
It only sends the last one.
Edit:
Found out if i format it like 'port=8&target=64' it works. Is there a better way?
my $ua = LWP::UserAgent->new();
my $request = POST( $url, [ 'port' => 8, 'target' => 64 ] );
my $content = $ua->request($request)->as_string();
The answer given didn't work for me. I still had the same problem as OP.
The documentation for LWP::UserAgent wants a hash or array reference.
This works:
my $url = 'https://www.google.com/recaptcha/api/siteverify';
my $ua = LWP::UserAgent->new();
my %form;
$form{'secret'}='xxxxxxxxxxxxxxxxxxxxxxx';
$form{'response'}=$captchaResponse;
my $response = $ua->post( $url, \%form );
my $content = $response->as_string();
Using together LWP::UserAgent and HTTP::Request as it is also quite common if not even more frequent practice , I was little puzzled that the standard POST and GET / request were almost not discussed at SO aside from json as them are in vast majority used.
POST
my $ua = LWP::UserAgent->new();
my $req = new HTTP::Request(
'POST' => "http://url/path",
['Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'],
'par1=par1value&par2=par2value'
);
$ua->request($req);
similarly for the GET
my $ua = LWP::UserAgent->new();
my $req = new HTTP::Request(
'GET' => "http://url/path",
['Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'],
'par1=par1value&par2=par2value' # or I presume attaching the query string directly to the url
);
$ua->request($req);
another format form , where the first two parameters (method and url) are not fused into a one, not like the previous, but separately
my $request = HTTP::Request->new( 'POST', $url, [ parameter1 => 'parameter1Value' ] );
request->header( 'Content-Type' => 'application/json' )
There is a similar question, but just regards LWP and Json, but it could be probably accomplished only by using both LWP and HTTP::Request together as suggested by that question chosen answer, and the POST and GET were missing there but it might not have been obvious
How can I make a JSON POST request with LWP?
Note:
I post this specially also, since the concrete/concise usage for POST/GET is not mentioned even in the documentation
https://metacpan.org/pod/HTTP::Request