Perl/curl 如何获取状态代码和响应 Body
Perl/ curl How to get Status Code and Response Body
我正在尝试编写一个简单的 perl 脚本来调用 API,如果状态代码为 2xx,则对响应执行某些操作。如果是 4xx 或 5xx,则执行其他操作。
我遇到的问题是我能够获得响应代码(使用自定义 write-out 格式化程序并将输出传递到其他地方)或者我可以获得整个响应和 headers。
my $curlResponseCode = `curl -s -o /dev/null -w "%{http_code}" ....`;
只会给我状态码。
my $curlResponse = `curl -si ...`;
会给我完整的 header 加上回复。
我的问题是如何从服务器获取响应 body 以及格式简洁的 http 状态代码,以便将它们分成两个单独的变量。
不幸的是,我不能使用 LWP 或任何其他单独的库。
提前致谢。
-斯宾塞
...Will give me the entire header plus the response.
...in a neat format that allows me to separate them into two separate variables.
由于 header 和 body 只是由一个空行分隔,您可以拆分此行的内容:
my ($head,$body) = split( m{\r?\n\r?\n}, `curl -si http://example.com `,2 );
并从 header
获取状态码
my ($code) = $head =~m{\A\S+ (\d+)};
您也可以将其组合成一个带有正则表达式的表达式,尽管这可能更难理解:
my ($code,$body) = `curl -si http://example.com`
=~m{\A\S+ (\d+) .*?\r?\n\r?\n(.*)}s;
从根本上说,您正在捕获系统命令的输出。使用为其构建的库来做到这一点要好得多 - LWP
。
如果失败 - curl -v
将生成状态代码和内容,您将不得不解析它。
您可能还会发现 SuperUser 上的这个帖子很有用:
https://superuser.com/questions/272265/getting-curl-to-output-http-status-code
具体
#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')
(这不是 perl,但您可以使用类似的东西。至少,运行 -w
并将您的内容捕获到临时文件。
我想到了这个解决方案:
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
还没有想出一个“纯粹的”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
冗长的使用curl
或多或少说明了自己。我的示例允许您将凭据传递到页面,但可以根据需要将其删除。
我正在尝试编写一个简单的 perl 脚本来调用 API,如果状态代码为 2xx,则对响应执行某些操作。如果是 4xx 或 5xx,则执行其他操作。
我遇到的问题是我能够获得响应代码(使用自定义 write-out 格式化程序并将输出传递到其他地方)或者我可以获得整个响应和 headers。
my $curlResponseCode = `curl -s -o /dev/null -w "%{http_code}" ....`;
只会给我状态码。
my $curlResponse = `curl -si ...`;
会给我完整的 header 加上回复。
我的问题是如何从服务器获取响应 body 以及格式简洁的 http 状态代码,以便将它们分成两个单独的变量。
不幸的是,我不能使用 LWP 或任何其他单独的库。
提前致谢。 -斯宾塞
...Will give me the entire header plus the response.
...in a neat format that allows me to separate them into two separate variables.
由于 header 和 body 只是由一个空行分隔,您可以拆分此行的内容:
my ($head,$body) = split( m{\r?\n\r?\n}, `curl -si http://example.com `,2 );
并从 header
获取状态码 my ($code) = $head =~m{\A\S+ (\d+)};
您也可以将其组合成一个带有正则表达式的表达式,尽管这可能更难理解:
my ($code,$body) = `curl -si http://example.com`
=~m{\A\S+ (\d+) .*?\r?\n\r?\n(.*)}s;
从根本上说,您正在捕获系统命令的输出。使用为其构建的库来做到这一点要好得多 - LWP
。
如果失败 - curl -v
将生成状态代码和内容,您将不得不解析它。
您可能还会发现 SuperUser 上的这个帖子很有用:
https://superuser.com/questions/272265/getting-curl-to-output-http-status-code
具体
#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')
(这不是 perl,但您可以使用类似的东西。至少,运行 -w
并将您的内容捕获到临时文件。
我想到了这个解决方案:
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
还没有想出一个“纯粹的”Perl
解决方案,但我起草了这个片段来通过 curl
:
#!/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
冗长的使用curl
或多或少说明了自己。我的示例允许您将凭据传递到页面,但可以根据需要将其删除。