Skip to content

feof hangs indefinitely #10495

Closed
Closed
@bytestream

Description

@bytestream

Description

I am using horde/imap-client to connect to an IMAPS server. If I disconnect the local network interface after a couple of iterations of https://github.com/bytestream/Imap_Client/blob/ac98de92168777fb8bf0bacf3129fc178523defe/lib/Horde/Imap/Client/Socket/Connection/Socket.php#L186 when it's downloading a 30MB email body then feof hangs indefintely. stream_set_timeout(30); and default_socket_timeout of 60 seem to have no effect...

The following is an example to illustrate the problem, and should not be used as a test case:

<?php

$_stream = @stream_socket_client(
  "ssl://server.com:993",
  $error_number,
  $error_string,
  30,
  STREAM_CLIENT_CONNECT,
  stream_context_create([
    'ssl' => [
      'verify_peer' => false,
      'verify_peer_name' => false,
      'cafile' => '/etc/ssl/certs/ca-certificates.crt',
      'allow_self_signed' => true,
    ],
  ])
);

stream_set_timeout($_stream, 30);
stream_set_read_buffer($_stream, 0);
stream_set_write_buffer($_stream, 0);

while (!feof($_stream)) {
  $in = fread($_stream, 8192);
}

If I dump stream metadata, the result never changes:

array(8) {
  ["crypto"]=>
  array(4) {
    ["protocol"]=>
    string(7) "TLSv1.2"
    ["cipher_name"]=>
    string(27) "ECDHE-RSA-AES128-GCM-SHA256"
    ["cipher_bits"]=>
    int(128)
    ["cipher_version"]=>
    string(7) "TLSv1.2"
  }
  ["timed_out"]=>
  bool(false)
  ["blocked"]=>
  bool(true)
  ["eof"]=>
  bool(false)
  ["stream_type"]=>
  string(14) "tcp_socket/ssl"
  ["mode"]=>
  string(2) "r+"
  ["unread_bytes"]=>
  int(0)
  ["seekable"]=>
  bool(false)
}

When using slightly modified code of:

while ($literal_len > 0) {
  sleep(3);
  if (! is_resource($this->_stream) || feof($this->_stream)) {

strace at the point where the process hangs shows:

16:57:11.921521 clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=3, tv_nsec=0}, 0x7fffb50a22b0) = 0
16:57:14.930968 poll([{fd=11, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 1 ([{fd=11, revents=POLLIN}])
16:57:14.931033 read(11, "\27\3\3\20\30", 5) = 5
 | 00000  17 03 03 10 18                                    .....            |
16:57:14.931068 read(11, "\26c\306", 4120) = 3
 | 00000  16 63 c6                                          .c.              |
16:57:14.931094 read(11, 

File descriptor 11 is the socket to the IMAPS server.

PHP Version

PHP 8.1.11

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions