Extract Headers From HTTP Request In Perl

I want to read headers in http or https request in my perl script :

#!/usr/bin/perl
use LWP::UserAgent;
my $ua = new LWP::UserAgent;
my $url = "http://example.com/";
my $req = $ua->get("$url");

I want To Extract The Headers Data Of The Upper Request Such As :

HTTP/1.1 200 OK
Access-Control-Allow-Headers: accept, origin, content-type, content-length
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin: *
Content-Encoding: gzip
Content-Type: application/javascript
Date: Thu, 28 Apr 2016 01:43:01 GMT
Etag: "779429019"
Cookie: username=usrname; pass=P@S$W0RD;
X-Powered-By: adzerk bifrost/
x-served-by: engine-i-536776c8

Upvotes: 4

Views: 9054

Answers (3)

Sebastian
Sebastian

Reputation: 2560

#!/usr/bin/perl -l
use strict;
use warnings;

use LWP::UserAgent;

my $ua = new LWP::UserAgent;
my $result = $ua->get("http://example.com/");
print $result;
print "HTTP code: ".$result->code;

$result will be no plain text response, but a HTTP::Response object. The output of the above script is:

HTTP::Response=HASH(0x23dbfc8)
HTTP code: 200

This object has methods (like ->code to get the HTTP status code). The documentation states (shortened):

$r->header( $field )

This is used to get header values and it is inherited from HTTP::Headers via HTTP::Message. See HTTP::Headers for details and other similar methods that can be used to access the headers.

HTTP::Headers itself has a method header_field_names:

$h->header_field_names

Returns the list of distinct names for the fields present in the header. The field names have case as suggested by HTTP spec, and the names are returned in the recommended "Good Practice" order.

In scalar context return the number of distinct field names.

Your script could easily get the requested information:

for my $header_name ($result->header_field_names) {
    print $header_name.": ".$result->header($header_name);
}

Which outputs:

Cache-Control: max-age=604800
Connection: close
Date: Thu, 28 Apr 2016 05:40:52 GMT
ETag: "359670651+ident"
Server: ECS (iad/182A)
Vary: Accept-Encoding
Content-Length: 1270
Content-Type: text/html
Expires: Thu, 05 May 2016 05:40:52 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Client-Date: Thu, 28 Apr 2016 05:40:52 GMT
Client-Peer: 2606:2800:220:1:248:1893:25c8:1946:80
Client-Response-Num: 1
Title: Example Domain
X-Cache: HIT
X-Ec-Custom-Error: 1
X-Meta-Charset: utf-8
X-Meta-Viewport: width=device-width, initial-scale=1

$result->header($header_name) is also useful to get one header value for a known header name. Let's say out want to have the ETag of the response:

print $result->header('ETag');

HTTP::Headers also has a ->as_string method, but it's overwritten by the ->as_string method from HTTP::Response. But HTTP::Message has two solutions:

$mess->headers

Returns the embedded HTTP::Headers object.

You could walk though the objects to get the HTTP headers as one string by doing

print $result->headers->as_string;

which outputs:

Cache-Control: max-age=604800
Connection: close
Date: Thu, 28 Apr 2016 05:47:54 GMT
ETag: "359670651+ident"
Server: ECS (iad/182A)
Vary: Accept-Encoding
Content-Length: 1270
Content-Type: text/html
Expires: Thu, 05 May 2016 05:47:54 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Client-Date: Thu, 28 Apr 2016 05:47:54 GMT
Client-Peer: 2606:2800:220:1:248:1893:25c8:1946:80
Client-Response-Num: 1
Title: Example Domain
X-Cache: HIT
X-Ec-Custom-Error: 1
X-Meta-Charset: utf-8
X-Meta-Viewport: width=device-width, initial-scale=1

Second solution:

$mess->headers_as_string $mess->headers_as_string( $eol )

Call the as_string() method for the headers in the message.

Try

print $result->headers_as_string;

and you'll get exactly the same output as before.

Upvotes: 1

Borodin
Borodin

Reputation: 126762

Note that your $req is actually a response object, not a request

To examine all of the header fields, you are looking for $resp->headers_as_string

To generate the output that you show, you would write this

#!/usr/bin/perl

use LWP::UserAgent;

my $ua = new LWP::UserAgent;
my $url = 'http://example.com/';

my $resp = $ua->get($url);

print $resp->protocol, ' ', $resp->status_line, "\n";
print $resp->headers_as_string, "\n";

Upvotes: 4

Marty
Marty

Reputation: 2808

Unless I'm missunderstanding something, I dont see your problem. You are already using LWP::UserAgent which states that ->get returns a HTTP::Respnse object on which you can call ->header to get at header fields as documented here.

use v5.12;
use warnings;

use LWP::UserAgent;
my $ua = new LWP::UserAgent;
my $url = "http://github.com/";
my $res = $ua->get("$url");

say "Headers returned: ", join(", ", $res->header_field_names);
say "With values:" ;
say "  $_: ", $res->header($_) for  $res->header_field_names ;

# Outputs

# Headers returned: Content-Type, Client-Date, Client-Warning
# With values:
#   Content-Type: text/plain
#   Client-Date: Thu, 28 Apr 2016 02:31:26 GMT
#   Client-Warning: Internal response

Upvotes: 2

Related Questions