简体   繁体   English

Perl/ curl 如何获取状态码和响应体

[英]Perl/ curl How to get Status Code and Response Body

I am trying to write a simple perl script that calls and API and if the status code is 2xx the do something with the response.我正在尝试编写一个简单的 perl 脚本来调用和 API,如果状态代码是 2xx,则对响应执行一些操作。 While if it is 4xx or 5xx then do something else.而如果是 4xx 或 5xx 则执行其他操作。

The issue I am encountering is I am able to either get the response code (using a custom write-out formatter and pass the output somewhere else) or I can get the whole response and the headers.我遇到的问题是我能够获取响应代码(使用自定义写出格式化程序并将输出传递到其他地方),或者我可以获得整个响应和标题。

my $curlResponseCode = `curl -s -o /dev/null -w "%{http_code}" ....`;

Will give me the status code only.只会给我状态码。

my $curlResponse = `curl -si ...`; 

Will give me the entire header plus the response.会给我整个标题加上响应。

My question is how can I obtain the response body from the server and the http status code in a neat format that allows me to separate them into two separate variables.我的问题是如何以一种简洁的格式从服务器获取响应正文和 http 状态代码,使我可以将它们分成两个单独的变量。

Unfortunately I cannot use LWP or any other separate libraries.不幸的是,我不能使用 LWP 或任何其他单独的库。

Thanks in advance.提前致谢。 -Spencer -斯宾塞

I came up with this solution: 我想出了这个解决方案:

URL="http://google.com"

# store the whole response with the status at the and
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" -X POST $URL)

# extract the body
HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')

# extract the status
HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')

# print the body
echo "$HTTP_BODY"

# example using the status
if [ ! $HTTP_STATUS -eq 200  ]; then
  echo "Error [HTTP status: $HTTP_STATUS]"
  exit 1
fi

...Will give me the entire header plus the response. ...会给我整个标题加上回复。

...in a neat format that allows me to separate them into two separate variables. ...以一种简洁的格式,允许我将它们分成两个独立的变量。

Since header and body are simply delimited by an empty line you can split the content on this line: 由于标题和正文仅由空行分隔,因此您可以拆分此行上的内容:

 my ($head,$body) = split( m{\r?\n\r?\n}, `curl -si http://example.com `,2 );

And to get the status code from the header 并从标题中获取状态代码

 my ($code) = $head =~m{\A\S+ (\d+)};

You might also combine this into a single expression with a regexp, although this might be harder to understand: 您也可以将它组合成一个带有正则表达式的表达式,尽管这可能更难理解:

my ($code,$body) = `curl -si http://example.com` 
      =~m{\A\S+ (\d+) .*?\r?\n\r?\n(.*)}s;

Pretty fundamentally - you're capturing output from a system command. 非常基本 - 您正在捕获系统命令的输出。 It is far and away better to do this by using the library built for it - LWP . 通过使用为其构建的库( LWP来做到这一点远比这更好。 Failing that though - curl -v will produce status code and content, and you'll have to parse it. 虽然失败了 - curl -v会产生状态代码和内容,你将不得不解析它。

You might also find this thread on SuperUser useful: 您可能还会发现SuperUser上的这个主题非常有用:

https://superuser.com/questions/272265/getting-curl-to-output-http-status-code https://superuser.com/questions/272265/getting-curl-to-output-http-status-code

Specifically 特别

#creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1 
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')

(That isn't perl, but you can probably use something similar. At very least, running the -w and capturing your content to a temp file. (这不是perl,但你可以使用类似的东西。至少,运行-w并将你的内容捕获到临时文件。

Haven't figured out a "pure" Perl solution, but I drafted this snippet to check the HTTP response code of a page via curl :还没有想出一个“纯”的Perl解决方案,但我起草了这个片段来通过curl检查页面的 HTTP 响应代码:

#!/usr/bin/perl

use v5.30;

use warnings;
use diagnostics;

our $url = "";

my $username = "";
my $password = "";

=begin url_check
Exit if HTTP response code not 200.
=cut

sub url_check {

  print "Checking URL status code...\n";

  my $status_code =
(`curl --max-time 2.5 --user ${username}:${password} --output /dev/null --silent --head --write-out '%{http_code}\n' $url`);

  if ($status_code != '200'){
    {
      print "URL not accessible. Exiting. \n";
      exit;
    }
  } else {
      print "URL accessible. Continuing... \n";
    }
}

url_check

The verbose use of curl more or less documents itself. curl的详细使用或多或少是文档本身。 My example allows you to pass credentials to a page, but that can be removed as needed.我的示例允许您将凭据传递给页面,但可以根据需要将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM