Replace HTTP response header status from curl output

859 Views Asked by At

Is there a way to replace the HTTP/1.1 200 status with HTTP/1.1 500 status after getting the response from the curl command?

If the body of the response contains the string Error retrieving data then the status will ordinarily be HTTP/1.1 200. I need to change it to HTTP/1.1 500 (internal server error)

For example

#!/usr/bin/perl

my $curlvalue = `curl -vk http://myserver.com/test.html`;
$search_string = "Error retrieving data";

if ( $curlvalue =~ m/$search_string/isg ) {
  print $curlvalue;
  print "AFTER OUTPUT\n";
  $value =~ s/HTTP\/1.1 200/HTTP\/1.1 500/g;
}

print $curlvalue;

output

perl test.pl**

** About to connect() to myserver.com (#0)
*   Trying 111.111.111.11... connected
* Connected to myserver.comt (11.111.111.11) port 80 (#0)
> GET /iis/mybroker/test.html HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1     Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: myserver.com
> Accept: */*
> 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0   
< HTTP/1.1 200 OK
< Date: Mon, 16 Jan 2017 13:47:10 GMT
< Server: Apache
< X-Frame-Options: SAMEORIGIN
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=ISO-8859-1
< 
{ [data not shown]
105   315    0   315    0     0    155      0 --:--:--  0:00:02 --:--:--   155*      Connection #0 to host myserver.com left intact
* Closing connection #0
<HTML>
<HEAD>
<TITLE>Error retrieving data (1000)</TITLE>
</HEAD>
<BODY>
<H1>Error retrieving data (1000)</H1>
</BODY>
</HTML>*

AFTER OUTPUT MESSAGE not showing HTTP header details

<HTML>
<HEAD>
<TITLE>Error retrieving data (1000)</TITLE>
</HEAD>
<BODY>
<H1>Error retrieving data (1000)</H1>
</BODY>
</HTML>
2

There are 2 best solutions below

1
user3606329 On

You should not use cURL; there are Perl modules based on LWP.

In your example you try to match a string and then replace the status code from 200 to 500 if the string matched. HTML should not ever be matched with regular expressions. Instead you should use a DOM parser which can also handle nested tags easily.

According to the RFC, HTTP 200 is only for successful requests, so the API does not meet the standard.

You could do it with the following code:

template.html

<HTML>
<HEAD>
<TITLE>Error retrieving data (1000)</TITLE>
</HEAD>
<BODY>
<H1>Error retrieving data (1000)</H1>
</BODY>
</HTML>

Perl code

use strict;
use warnings;

use Mojo::UserAgent;

use feature 'say';

my $ua = Mojo::UserAgent->new;
my $response = $ua->get("http://myserver.com/iis/mybroker/test.html")->res->dom->at('h1')->text;
say $response eq "Error retrieving data (1000)" ? "Status code should be 500" : "Status code 200 is correct";
0
Borodin On

You've not answered the comments for four hours now, so here's a wild guess

This is your program

#!/usr/bin/perl

my $curlvalue = `curl -vk http://myserver.com/test.html`;

$search_string = "Error retrieving data";

if ( $curlvalue =~ m/$search_string/isg ) {
  print $curlvalue;
  print "AFTER OUTPUT\n";
  $value =~ s/HTTP\/1.1 200/HTTP\/1.1 500/g;
}

print $curlvalue;

It has neither use strict nor use warnings 'all' at the top, which are essential for any Perl program, and especially if you are asking for help with it.

My wild guess is that you're expecting the full output of curl, and you're trying to write a filter that will amend the reported status in specific cases. Is that right?

If so, then the problem is your substitution line

$value =~ s/HTTP\/1.1 200/HTTP\/1.1 500/g;

Because there is no $value variable, this line has no effect. You probably want $curlvalue, and I would use a different delimiter to avoid all of those escapes

There's also no need for the /g modifier, nor various other stuff, so I think your code should look like this

#!/usr/bin/perl

use strict;
use warnings 'all';

my $curlvalue = `curl -v http://myserver.com/test.html`;

my $search = "Error retrieving data";

if ( $curlvalue =~ /$search/i ) {

    print "BEFORE CHANGES\n";
    print $curlvalue;

    $curlvalue =~ s|HTTP/1.1 200|HTTP/1.1 500|;
}

print "AFTER CHANGES\n";
print $curlvalue;