@@ -26,6 +26,7 @@ namespace Adoy\FastCGI;
2626
2727class TimedOutException extends \Exception {}
2828class ForbiddenException extends \Exception {}
29+ class ReadLimitExceeded extends \Exception {}
2930
3031/**
3132 * Handles communication with a FastCGI application
@@ -404,16 +405,24 @@ class Client
404405 /**
405406 * Read a FastCGI Packet
406407 *
408+ * @param int $readLimit max content size
407409 * @return array
410+ * @throws ReadLimitExceeded
408411 */
409- private function readPacket ()
412+ private function readPacket ($ readLimit = - 1 )
410413 {
411414 if ($ packet = fread ($ this ->_sock , self ::HEADER_LEN )) {
412415 $ resp = $ this ->decodePacketHeader ($ packet );
413416 $ resp ['content ' ] = '' ;
414417 if ($ resp ['contentLength ' ]) {
415- $ len = $ resp ['contentLength ' ];
416- while ($ len && $ buf =fread ($ this ->_sock , $ len )) {
418+ $ len = $ resp ['contentLength ' ];
419+ if ($ readLimit >= 0 && $ len > $ readLimit ) {
420+ // close connection so it can be re-set reset and throw an error
421+ fclose ($ this ->_sock );
422+ $ this ->_sock = null ;
423+ throw new ReadLimitExceeded ("Content has $ len bytes but the limit is $ readLimit bytes " );
424+ }
425+ while ($ len && $ buf = fread ($ this ->_sock , $ len )) {
417426 $ len -= strlen ($ buf );
418427 $ resp ['content ' ] .= $ buf ;
419428 }
@@ -473,15 +482,16 @@ class Client
473482 *
474483 * @param array $params Array of parameters
475484 * @param string $stdin Content
485+ * @param int $readLimit [optional] the number of bytes to accept in a single packet or -1 if unlimited
476486 * @return array
477487 * @throws ForbiddenException
478488 * @throws TimedOutException
479489 * @throws \Exception
480490 */
481- public function request_data (array $ params , $ stdin )
491+ public function request_data (array $ params , $ stdin, $ readLimit = - 1 )
482492 {
483493 $ id = $ this ->async_request ($ params , $ stdin );
484- return $ this ->wait_for_response_data ($ id );
494+ return $ this ->wait_for_response_data ($ id, 0 , $ readLimit );
485495 }
486496
487497 /**
@@ -579,12 +589,13 @@ class Client
579589 *
580590 * @param int $requestId
581591 * @param int $timeoutMs [optional] the number of milliseconds to wait.
592+ * @param int $readLimit [optional] the number of bytes to accept in a single packet or -1 if unlimited
582593 * @return array response data
583594 * @throws ForbiddenException
584595 * @throws TimedOutException
585596 * @throws \Exception
586597 */
587- public function wait_for_response_data ($ requestId , $ timeoutMs = 0 )
598+ public function wait_for_response_data ($ requestId , $ timeoutMs = 0 , $ readLimit = - 1 )
588599 {
589600 if (!isset ($ this ->_requests [$ requestId ])) {
590601 throw new \Exception ('Invalid request id given ' );
@@ -608,7 +619,7 @@ class Client
608619 // but still not get the response requested
609620 $ startTime = microtime (true );
610621
611- while ($ resp = $ this ->readPacket ()) {
622+ while ($ resp = $ this ->readPacket ($ readLimit )) {
612623 if ($ resp ['type ' ] == self ::STDOUT || $ resp ['type ' ] == self ::STDERR ) {
613624 if ($ resp ['type ' ] == self ::STDERR ) {
614625 $ this ->_requests [$ resp ['requestId ' ]]['state ' ] = self ::REQ_STATE_ERR ;
0 commit comments