Edit report at http://bugs.php.net/bug.php?id=52374&edit=1

 ID:                 52374
 Comment by:         recycling dot sp dot am at gmail dot com
 Reported by:        bastard dot internets at gmail dot com
 Summary:            socket_read(): PHP_NORMAL_READ against user defined
                     string
 Status:             Open
 Type:               Feature/Change Request
 Package:            Sockets related
 Operating System:   any
 PHP Version:        5.3.2
 Block user comment: N

 New Comment:

In most text protocols, the end of line is written "\r\n" (See http,
POP3,...). Consequently, it requires two consecutive calls using
socket_read() to handle answers from these protocol. The latter call is
only done to bypass the '\n'.


Previous Comments:
------------------------------------------------------------------------
[2010-07-19 03:04:39] bastard dot internets at gmail dot com

Note: on the echo line, you may want to replace the end
'$current_line\n' with '".trim($current_line)."\n";'.  Because of all
the extra line breaks and carriage returns echoed directly from the read
text, the original example might output a bit oddly.

------------------------------------------------------------------------
[2010-07-19 02:20:03] bastard dot internets at gmail dot com

Description:
------------
With the assumption that the PHP_NORMAL_READ flag can be used to
basically read in line-by-line, can a 4th optional function argument be
added to allow users to define what exactly denotes an end of line for
their chosen protocol?  If this 4th parameter is not passed by the user,
socket_read() could default to it's current behavior.



With PHP_NORMAL_READ set, socket_read() now stops and returns on any of
the first "\r", "\n", and presumably "\0" characters found.  Because
protocols would more often use a different character or character chains
to denote end of line - such as HTTP's "\r\n" - allowing the user to
pass in "\r\n" to tell socket_read() where to stop and return would help
save extra code to correctly handle message parsing, or having to
confirm and discard any useless character socket_read() grabs next.



Also, the current behavior of socket_read() is to consume and return
that "end of line" character, which is good.  If the above is
implemented, the function should also consume and return everything up
to and and including that user defined string, to avoid infinite loops.

Test script:
---------------
// read in line-by-line, echoing the first ord and last ord of each line
just to show my point



$conn = socket_accept($s_socket);

socket_set_nonblock($conn) OR

        trigger_error("Failed to set non-blocking for accepted connection!",
E_USER_ERROR);

for($current_line = ''; 1;) {

        $current_line = socket_read($conn, 4096, PHP_NORMAL_READ);

        if ($current_line == '') {

                break;

                }

        echo "[Start ord at pos 0: ".ord($current_line[0])."; End ord at pos
".(strlen($current_line) - 1).":
".ord($current_line[strlen($current_line) - 1])."]: $current_line\n";

        }



Expected result:
----------------
With the optional 4th function parameter, the read behavior could be
controlled by the user.  For example if a client connected with an HTTP
request, socket_read($conn, 4096, PHP_NORMAL_READ, "\r\n") would return
the current header.  The next iteration of socket_read() would return
the next header.  And, if socket_read() returned only "\r\n", this would
denote end of headers section.

Actual result:
--------------
The test script above shows the undesirable behavior if using something
like HTTP to connect to this server.  Line 'echo "[Start ord at pos...'
produces an extra line each time.  This is because socket_read() stopped
and returned at the first encounter of "\r" in each header line, and on
the next read, stopped and returned at the first encounter of "\n",
which was the very next character in the header line.


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52374&edit=1

Reply via email to