【问题标题】:Perl/ curl How to get Status Code and Response BodyPerl/ curl 如何获取状态码和响应体
【发布时间】:2015-04-29 09:36:50
【问题描述】:

我正在尝试编写一个简单的 perl 脚本来调用和 API,如果状态代码是 2xx,则对响应执行一些操作。而如果是 4xx 或 5xx 则执行其他操作。

我遇到的问题是我能够获取响应代码(使用自定义写出格式化程序并将输出传递到其他地方),或者我可以获得整个响应和标头。

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

只会给我状态码。

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

会给我整个标题加上响应。

我的问题是如何以一种简洁的格式从服务器获取响应正文和 http 状态代码,以便将它们分成两个单独的变量。

很遗憾,我不能使用 LWP 或任何其他单独的库。

提前致谢。 -斯宾塞

【问题讨论】:

  • “我不能使用 LWP 或任何其他单独的库” 有什么特别的原因吗?
  • 是的,有很多不值得在这里讨论的原因......本质上它是一个环境约束。 LWP 会让我的生活更轻松。
  • 我之所以这么问,是因为许多说“我不能使用模块”的人认为您需要管理员权限才能使用它们,但事实并非如此。如果您没有在问题中提供令人信服的理由,通常有人会问为什么,因为您不使用 CPAN 确实限制了自己。

标签: linux perl curl


【解决方案1】:

我想出了这个解决方案:

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

【讨论】:

    【解决方案2】:

    ...会给我整个标题和响应。

    ...以一种简洁的格式,我可以将它们分成两个单独的变量。

    由于标题和正文仅由空行分隔,因此您可以在此行上拆分内容:

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

    并从标题中获取状态码

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

    您也可以将其与正则表达式组合成一个表达式,尽管这可能更难理解:

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

    【讨论】:

      【解决方案3】:

      从根本上说非常漂亮 - 您正在捕获系统命令的输出。通过使用为它构建的库 - 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 并将您的内容捕获到临时文件中。

      【讨论】:

        【解决方案4】:

        还没有想出一个“纯粹的”Perl 解决方案,但我起草了这个 sn-p 以通过 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 的详细使用或多或少是文档本身。我的示例允许您将凭据传递给页面,但可以根据需要将其删除。

        【讨论】:

          猜你喜欢
          • 2015-05-28
          • 1970-01-01
          • 2019-04-11
          • 2011-07-17
          • 1970-01-01
          • 1970-01-01
          • 2020-01-10
          • 2015-05-21
          • 1970-01-01
          相关资源
          最近更新 更多