Issues

ZF-4238: Infinite loop when connection is closed

Issue Type: Bug Created: 2008-09-10T09:27:13.000+0000 Last Updated: 2012-03-21T11:14:58.000+0000 Status: Resolved Fix version(s): - 1.7.1 (01/Dec/08)

Reporter: Alex Adriaanse (alexadriaanse) Assignee: Satoru Yoshida (satoruyoshida) Tags: - Zend_Http_Client

Related issues: - ZF-4561

Attachments: - zend_http_client_infinite_loop_on_timeout_fix.patch

Description

When I use Zend_Http_Client it occasionally seems to get stuck in an infinite loop. When I perform an strace on the offending process I see the following system calls being called in an infinite loop:

<pre class="literal">
poll([{fd=6, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN|POLLHUP}], 1, 300000) = 1
recvfrom(6, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
poll([{fd=6, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN|POLLHUP}], 1, 300000) = 1
recvfrom(6, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
poll([{fd=6, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN|POLLHUP}], 1, 300000) = 1
recvfrom(6, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
poll([{fd=6, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN|POLLHUP}], 1, 300000) = 1
recvfrom(6, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
...

I noticed that Zend_Http_Client_Adapter_Socket::read() does not check whether the socket has been closed while it reads a response. My hypothesis is that when a connection is closed while read() is in the process of reading the response, it gets stuck in an infinite loop as it is never able to finish reading $left_to_read bytes.

Comments

Posted by Alex Adriaanse (alexadriaanse) on 2008-09-10T09:36:41.000+0000

While I was reviewing Zend_Http_Client_Adapter_Socket::read(), I also noticed that it has lines like while ($line = @fgets($this->socket)) and while ($buff = @fread($this->socket, 8192)). Due to the loose comparisons performed by these statements, I'd imagine that when fgets() and fread() return a string such as "0" the read is aborted prematurely. In addition to adding feof() checks, these conditions should probably be rewritten as (... === false) and/or (... === '').

Posted by Shahar Evron (shahar) on 2008-10-11T04:41:47.000+0000

I added additional failure checks in changeset 11864 and an additional test to make sure lines with '0' or '' are not wrongly evaluated as FALSE. In order to fully confirm that this issue is fixed I need either a clear reproduction, or you can test with the latest revision and see if this still happens.

Posted by Alexander Veremyev (alexander) on 2008-10-11T13:17:56.000+0000

That seems ZF-4560 is caused by this problem.

Posted by Shahar Evron (shahar) on 2008-10-12T02:48:53.000+0000

I added some additional feof() checks to fix ZF-4560.

It seems that fread() / fgets() do not always return false when at EOF, and you need to manually check for EOF or it will just keep reading. This is the case when there is no content-length or "transfer-encoding: chunked" response, and you just need to read until the end of file, which is the case with some responses from the AudioScrobbler servers and maybe from other servers as well.

Posted by Alexander Veremyev (alexander) on 2008-10-12T04:03:53.000+0000

It seems it's resolved with r11886 commit.

Posted by Benjamin Eberlei (beberlei) on 2008-10-12T04:28:54.000+0000

The Unit Test file: /trunk/tests/Zend/Http/Client/_files/ZF4238-zerolineresponse.txt is missing, unit tests fail:

testZF4238FalseLinesInResponse() testHttpAuthBasic()

Posted by Wil Sinclair (wil) on 2008-11-13T14:09:58.000+0000

Changing issues in preparation for the 1.7.0 release.

Posted by Alex Adriaanse (alexadriaanse) on 2008-11-13T18:19:56.000+0000

If the connection times out while Zend_Http_Client_Adapter_Socket is reading from the socket, it will still go into an infinite loop. I am attaching a patch that appears to fix this.

Posted by old of Satoru Yoshida (yoshida@zend.co.jp) on 2008-12-04T04:09:02.000+0000

I try to solve this issue at SVN r13013.

I will happy if I receive any reviews.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts