8

Here is the code that I am using:

if (!($fp = fsockopen('ssl://imap.gmail.com', '993', $errno, $errstr, 15)))
    echo "Could not connect to host";
$server_response = fread($fp, 256);
echo $server_response;

fwrite($fp, "C01 CAPABILITY"."\r\n");
while (!feof($fp)) {
    echo fgets($fp, 256);
}

I get the first response:

OK Gimap ready for requests from xx.xx.xx.xx v3if9968808ibd.15 

but then the page times out. I have searched through stream_set_blocking, stream_set_timeout, stream_select, fread, etc. but could not get it to work. I need to read all the data that the server sends and then proceed with other commands (I would be retrieving emails using imap).

Thanks

vyegorov
  • 21,787
  • 7
  • 59
  • 73
victor_golf
  • 195
  • 2
  • 2
  • 10
  • Are You sure the response is only 256 chars long? And are You sure that the socket is writeable? It is possible Your script hangs on `fwrite()` because of socket is not writeable... – shadyyx May 04 '12 at 13:20
  • Yes. I tested that by replacing the while loop by simple writing fgets($fp,256) two times. And this is the response that I get : * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH C01 OK – victor_golf May 04 '12 at 13:27

2 Answers2

8

Your script is hanging in the while loop at the end. This is because you have used !feof() as the condition for the loop, and the server is not closing the connection. This means the feof() will always return false and the loop will continue forever.

This will not be problem when your write a full implementation, as you will be looking for response codes and can break out of the loop accordingly, for example:

<?php

  // Open a socket
  if (!($fp = fsockopen('ssl://imap.gmail.com', 993, $errno, $errstr, 15))) {
      die("Could not connect to host");
  }

  // Set timout to 1 second
  if (!stream_set_timeout($fp, 1)) die("Could not set timeout");

  // Fetch first line of response and echo it
  echo fgets($fp);

  // Send data to server
  echo "Writing data...";
  fwrite($fp, "C01 CAPABILITY\r\n");
  echo " Done\r\n";

  // Keep fetching lines until response code is correct
  while ($line = fgets($fp)) {
    echo $line;
    $line = preg_split('/\s+/', $line, 0, PREG_SPLIT_NO_EMPTY);
    $code = $line[0];
    if (strtoupper($code) == 'C01') {
      break;
    }
  }

  echo "I've finished!";
DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • 1
    [RFCs are your friends](http://tools.ietf.org/html/rfc3501) ;-) (Don't forget to handle error responses as well, or you script will hang forever waiting for the `C01` response it will never get) – DaveRandom May 04 '12 at 13:51
  • Yes. I have been going through those commands for some time now. Thanks again. – victor_golf May 04 '12 at 13:54
1

Your script should be working. In fact, it is working.

See the results below on my pc when I ran your code:

* OK Gimap ready for requests from xx.xx.xx.xx l5if4585958ebb.20
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY  SASL-IR AUTH=XOAUTH
C01 OK Thats all she wrote! l5if4585958ebb.20

Since gmail doesn't disconnect you. No end of file occurs. And the page loading simply times out.

In other words: Your script will just keep waiting and waiting until gmail does disconnect, which unfortunately happens after your page load has already timed out.

Woutifier
  • 313
  • 2
  • 7
  • Did you get the result immediately, or it took some time (1-2min) to timeout?? – victor_golf May 04 '12 at 13:31
  • The problem is probably that you are trying to run it from a webpage am I right? The page times out before gmail disconnects (so feof() never returns true). It probably loses part of the buffer in the process of timing out. – Woutifier May 04 '12 at 13:32
  • Yes. I have a .php page which has this code. What's the problem? – victor_golf May 04 '12 at 13:33
  • I receive the following response but after 2min of loading the page: * OK Gimap ready for requests from xx.xx.xx.xx vb10if10168308icb.24 * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH C01 OK Thats all she wrote! vb10if10168308icb.24 How can I deal with the time out, since stream_set_timeout($fp,1) does not seem to work.. – victor_golf May 04 '12 at 13:36
  • Your code works. You should look for that C01 OK instead of waiting for end of file – Woutifier May 04 '12 at 13:37
  • The stream does not timeout. It just sits there waiting for input/output from either gmail or you. – Woutifier May 04 '12 at 13:38
  • OK. But thats a solution only if the server responds as expected. What if I receive an error, the page will still hang? And as I mentioned, I will be retrieving emails so just checking for "OK" may not be a good solution. Am I right?? – victor_golf May 04 '12 at 13:40
  • Yes you will actually have to check the protocol specifications for possible error codes and implement appropriate responses for them. After this step you can continue by sending your "question" to the gmail server. – Woutifier May 04 '12 at 13:44
  • Ok.Thanks. @DaveRandom has also suggested the same (code below). – victor_golf May 04 '12 at 13:47