以下代码段读取HTTP响应。假设响应不包含Content-Length标头而Content-Type不是text / html,那么如何终止while循环呢?
(1。不要担心分块传输编码2.没有IO :: Socket)
while(defined($line = <SOCK>))
{
$data .= $line;
if($line =~ /Content-length:/isg)
{
($cl) = $line =~ /Content-Length: ([0-9]+)/i;
}
$line =~ s/\n//g;
$line =~ s/\r//g;
if($line eq '' && $cl)
{
read(SOCK, $data, $cl, length($data));
last;
}
if($line =~ /<\/html>/) { last; }
}
答案 0 :(得分:2)
如果没有Content-Length,并且服务器没有使用分块传输编码,则数据在服务器关闭套接字时结束(您将获得EOF)。有关详细信息,请参阅HTTP规范中的相关部分:http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
代码示例中的真正问题是:
X-Not-Really-Content-Length:
$cl
为零或未定义,则永远不要输入读取 (这可能就是您所看到的!)。既然你说没有Content-Length
标题就会中断,那么$cl
会保持未定义的状态,你永远不会输入你的读取块。由于这是perl,您可能需要查看LWP,它处理HTTP处理的许多棘手部分。
答案 1 :(得分:1)
如果您不想再从套接字读取,请不要从套接字读取。如果要关闭套接字,只需将其关闭即可。如果您希望服务器在完成为您的请求提供服务时关闭连接,请确保在您的请求中发送“Connection:close”标头。
如果您认为自己可能会损害服务器的感受,那么您可以阅读剩下的所有内容,而不是对其进行任何操作。但是,这使服务器有机会向您传输无穷无尽的数据,让您的插槽永远保持打开状态。
如果您确实需要在代码中自行处理它,则可能需要单独处理标题和消息正文。看到完整的标题后,您可以检查它是否包含您需要的字段。如果没有,你关闭袜子并返回:
sub read_sock {
HEADER: while( <SOCK> ) {
last if /^[\r\n]+$/; # blank line terminating header
... parse header lines into %headers...
}
unless( exists $headers{'content-length'} ) {
warn "No Content-Length! Stopping!\n";
close SOCK;
return;
}
MESSAGE_BODY: while( <SOCK> ) {
... read(), etc ...
}
return $message_body;
}
尽管如此,使用LWP :: UserAgent可能有更好的方法。您可以定义自己的内容处理程序,并在其中执行任何操作。
答案 2 :(得分:0)
如果没有内容长度标题,那么您有三个选项:
其中没有一个非常强大。