1<?php 2namespace Ratchet\Http; 3use Ratchet\MessageInterface; 4use Ratchet\ConnectionInterface; 5use GuzzleHttp\Psr7 as gPsr; 6 7/** 8 * This class receives streaming data from a client request 9 * and parses HTTP headers, returning a PSR-7 Request object 10 * once it's been buffered 11 */ 12class HttpRequestParser implements MessageInterface { 13 const EOM = "\r\n\r\n"; 14 15 /** 16 * The maximum number of bytes the request can be 17 * This is a security measure to prevent attacks 18 * @var int 19 */ 20 public $maxSize = 4096; 21 22 /** 23 * @param \Ratchet\ConnectionInterface $context 24 * @param string $data Data stream to buffer 25 * @return \Psr\Http\Message\RequestInterface 26 * @throws \OverflowException If the message buffer has become too large 27 */ 28 public function onMessage(ConnectionInterface $context, $data) { 29 if (!isset($context->httpBuffer)) { 30 $context->httpBuffer = ''; 31 } 32 33 $context->httpBuffer .= $data; 34 35 if (strlen($context->httpBuffer) > (int)$this->maxSize) { 36 throw new \OverflowException("Maximum buffer size of {$this->maxSize} exceeded parsing HTTP header"); 37 } 38 39 if ($this->isEom($context->httpBuffer)) { 40 $request = $this->parse($context->httpBuffer); 41 42 unset($context->httpBuffer); 43 44 return $request; 45 } 46 } 47 48 /** 49 * Determine if the message has been buffered as per the HTTP specification 50 * @param string $message 51 * @return boolean 52 */ 53 public function isEom($message) { 54 return (boolean)strpos($message, static::EOM); 55 } 56 57 /** 58 * @param string $headers 59 * @return \Psr\Http\Message\RequestInterface 60 */ 61 public function parse($headers) { 62 return gPsr\parse_request($headers); 63 } 64} 65