@@ -26,6 +26,7 @@ namespace Adoy\FastCGI;
26
26
27
27
class TimedOutException extends \Exception {}
28
28
class ForbiddenException extends \Exception {}
29
+ class ReadLimitExceeded extends \Exception {}
29
30
30
31
/**
31
32
* Handles communication with a FastCGI application
@@ -404,16 +405,24 @@ class Client
404
405
/**
405
406
* Read a FastCGI Packet
406
407
*
408
+ * @param int $readLimit max content size
407
409
* @return array
410
+ * @throws ReadLimitExceeded
408
411
*/
409
- private function readPacket ()
412
+ private function readPacket ($ readLimit = - 1 )
410
413
{
411
414
if ($ packet = fread ($ this ->_sock , self ::HEADER_LEN )) {
412
415
$ resp = $ this ->decodePacketHeader ($ packet );
413
416
$ resp ['content ' ] = '' ;
414
417
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 )) {
417
426
$ len -= strlen ($ buf );
418
427
$ resp ['content ' ] .= $ buf ;
419
428
}
@@ -473,15 +482,16 @@ class Client
473
482
*
474
483
* @param array $params Array of parameters
475
484
* @param string $stdin Content
485
+ * @param int $readLimit [optional] the number of bytes to accept in a single packet or -1 if unlimited
476
486
* @return array
477
487
* @throws ForbiddenException
478
488
* @throws TimedOutException
479
489
* @throws \Exception
480
490
*/
481
- public function request_data (array $ params , $ stdin )
491
+ public function request_data (array $ params , $ stdin, $ readLimit = - 1 )
482
492
{
483
493
$ id = $ this ->async_request ($ params , $ stdin );
484
- return $ this ->wait_for_response_data ($ id );
494
+ return $ this ->wait_for_response_data ($ id, 0 , $ readLimit );
485
495
}
486
496
487
497
/**
@@ -579,12 +589,13 @@ class Client
579
589
*
580
590
* @param int $requestId
581
591
* @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
582
593
* @return array response data
583
594
* @throws ForbiddenException
584
595
* @throws TimedOutException
585
596
* @throws \Exception
586
597
*/
587
- public function wait_for_response_data ($ requestId , $ timeoutMs = 0 )
598
+ public function wait_for_response_data ($ requestId , $ timeoutMs = 0 , $ readLimit = - 1 )
588
599
{
589
600
if (!isset ($ this ->_requests [$ requestId ])) {
590
601
throw new \Exception ('Invalid request id given ' );
@@ -608,7 +619,7 @@ class Client
608
619
// but still not get the response requested
609
620
$ startTime = microtime (true );
610
621
611
- while ($ resp = $ this ->readPacket ()) {
622
+ while ($ resp = $ this ->readPacket ($ readLimit )) {
612
623
if ($ resp ['type ' ] == self ::STDOUT || $ resp ['type ' ] == self ::STDERR ) {
613
624
if ($ resp ['type ' ] == self ::STDERR ) {
614
625
$ this ->_requests [$ resp ['requestId ' ]]['state ' ] = self ::REQ_STATE_ERR ;
0 commit comments