44
55use React \Http \Io \RequestHeaderParser ;
66use React \Tests \Http \TestCase ;
7+ use Psr \Http \Message \ServerRequestInterface ;
78
89class RequestHeaderParserTest extends TestCase
910{
@@ -59,24 +60,21 @@ public function testFeedTwoRequestsOnSeparateConnections()
5960 $ this ->assertEquals (2 , $ called );
6061 }
6162
62- public function testHeadersEventShouldReturnRequestAndBodyBufferAndConnection ()
63+ public function testHeadersEventShouldEmitRequestAndConnection ()
6364 {
6465 $ request = null ;
65- $ bodyBuffer = null ;
6666 $ conn = null ;
6767
6868 $ parser = new RequestHeaderParser ();
69- $ parser ->on ('headers ' , function ($ parsedRequest , $ parsedBodyBuffer , $ connection ) use (&$ request, & $ bodyBuffer , &$ conn ) {
69+ $ parser ->on ('headers ' , function ($ parsedRequest , $ connection ) use (&$ request , &$ conn ) {
7070 $ request = $ parsedRequest ;
71- $ bodyBuffer = $ parsedBodyBuffer ;
7271 $ conn = $ connection ;
7372 });
7473
7574 $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
7675 $ parser ->handle ($ connection );
7776
7877 $ data = $ this ->createGetRequest ();
79- $ data .= 'RANDOM DATA ' ;
8078 $ connection ->emit ('data ' , array ($ data ));
8179
8280 $ this ->assertInstanceOf ('Psr\Http\Message\RequestInterface ' , $ request );
@@ -85,36 +83,143 @@ public function testHeadersEventShouldReturnRequestAndBodyBufferAndConnection()
8583 $ this ->assertSame ('1.1 ' , $ request ->getProtocolVersion ());
8684 $ this ->assertSame (array ('Host ' => array ('example.com ' ), 'Connection ' => array ('close ' )), $ request ->getHeaders ());
8785
88- $ this ->assertSame ('RANDOM DATA ' , $ bodyBuffer );
89-
9086 $ this ->assertSame ($ connection , $ conn );
9187 }
9288
93- public function testHeadersEventShouldReturnBinaryBodyBuffer ()
89+ public function testHeadersEventShouldEmitRequestWhichShouldEmitEndForStreamingBodyWithoutContentLengthFromInitialRequestBody ()
9490 {
95- $ bodyBuffer = null ;
91+ $ parser = new RequestHeaderParser ();
92+
93+ $ ended = false ;
94+ $ that = $ this ;
95+ $ parser ->on ('headers ' , function (ServerRequestInterface $ request ) use (&$ ended , $ that ) {
96+ $ body = $ request ->getBody ();
97+ $ that ->assertInstanceOf ('React\Stream\ReadableStreamInterface ' , $ body );
98+
99+ $ body ->on ('end ' , function () use (&$ ended ) {
100+ $ ended = true ;
101+ });
102+ });
103+
104+ $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
105+ $ parser ->handle ($ connection );
106+
107+ $ data = "GET / HTTP/1.0 \r\n\r\n" ;
108+ $ connection ->emit ('data ' , array ($ data ));
96109
110+ $ this ->assertTrue ($ ended );
111+ }
112+
113+ public function testHeadersEventShouldEmitRequestWhichShouldEmitStreamingBodyDataFromInitialRequestBody ()
114+ {
97115 $ parser = new RequestHeaderParser ();
98- $ parser ->on ('headers ' , function ($ parsedRequest , $ parsedBodyBuffer ) use (&$ bodyBuffer ) {
99- $ bodyBuffer = $ parsedBodyBuffer ;
116+
117+ $ buffer = '' ;
118+ $ that = $ this ;
119+ $ parser ->on ('headers ' , function (ServerRequestInterface $ request ) use (&$ buffer , $ that ) {
120+ $ body = $ request ->getBody ();
121+ $ that ->assertInstanceOf ('React\Stream\ReadableStreamInterface ' , $ body );
122+
123+ $ body ->on ('data ' , function ($ chunk ) use (&$ buffer ) {
124+ $ buffer .= $ chunk ;
125+ });
126+ $ body ->on ('end ' , function () use (&$ buffer ) {
127+ $ buffer .= '. ' ;
128+ });
100129 });
101130
102131 $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
103132 $ parser ->handle ($ connection );
104133
105- $ data = $ this ->createGetRequest ();
106- $ data .= "\0x01 \0x02 \0x03 \0x04 \0x05 " ;
134+ $ data = "POST / HTTP/1.0 \r\nContent-Length: 11 \r\n\r\n" ;
135+ $ data .= 'RANDOM DATA ' ;
136+ $ connection ->emit ('data ' , array ($ data ));
137+
138+ $ this ->assertSame ('RANDOM DATA. ' , $ buffer );
139+ }
140+
141+ public function testHeadersEventShouldEmitRequestWhichShouldEmitStreamingBodyWithPlentyOfDataFromInitialRequestBody ()
142+ {
143+ $ parser = new RequestHeaderParser ();
144+
145+ $ buffer = '' ;
146+ $ that = $ this ;
147+ $ parser ->on ('headers ' , function (ServerRequestInterface $ request ) use (&$ buffer , $ that ) {
148+ $ body = $ request ->getBody ();
149+ $ that ->assertInstanceOf ('React\Stream\ReadableStreamInterface ' , $ body );
150+
151+ $ body ->on ('data ' , function ($ chunk ) use (&$ buffer ) {
152+ $ buffer .= $ chunk ;
153+ });
154+ });
155+
156+ $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
157+ $ parser ->handle ($ connection );
158+
159+ $ size = 10000 ;
160+ $ data = "POST / HTTP/1.0 \r\nContent-Length: $ size \r\n\r\n" ;
161+ $ data .= str_repeat ('x ' , $ size );
162+ $ connection ->emit ('data ' , array ($ data ));
163+
164+ $ this ->assertSame ($ size , strlen ($ buffer ));
165+ }
166+
167+ public function testHeadersEventShouldEmitRequestWhichShouldNotEmitStreamingBodyDataWithoutContentLengthFromInitialRequestBody ()
168+ {
169+ $ parser = new RequestHeaderParser ();
170+
171+ $ buffer = '' ;
172+ $ that = $ this ;
173+ $ parser ->on ('headers ' , function (ServerRequestInterface $ request ) use (&$ buffer , $ that ) {
174+ $ body = $ request ->getBody ();
175+ $ that ->assertInstanceOf ('React\Stream\ReadableStreamInterface ' , $ body );
176+
177+ $ body ->on ('data ' , function ($ chunk ) use (&$ buffer ) {
178+ $ buffer .= $ chunk ;
179+ });
180+ });
181+
182+ $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
183+ $ parser ->handle ($ connection );
184+
185+ $ data = "POST / HTTP/1.0 \r\n\r\n" ;
186+ $ data .= 'RANDOM DATA ' ;
107187 $ connection ->emit ('data ' , array ($ data ));
108188
109- $ this ->assertSame ("\0x01 \0x02 \0x03 \0x04 \0x05 " , $ bodyBuffer );
189+ $ this ->assertSame ('' , $ buffer );
190+ }
191+
192+ public function testHeadersEventShouldEmitRequestWhichShouldEmitStreamingBodyDataUntilContentLengthBoundaryFromInitialRequestBody ()
193+ {
194+ $ parser = new RequestHeaderParser ();
195+
196+ $ buffer = '' ;
197+ $ that = $ this ;
198+ $ parser ->on ('headers ' , function (ServerRequestInterface $ request ) use (&$ buffer , $ that ) {
199+ $ body = $ request ->getBody ();
200+ $ that ->assertInstanceOf ('React\Stream\ReadableStreamInterface ' , $ body );
201+
202+ $ body ->on ('data ' , function ($ chunk ) use (&$ buffer ) {
203+ $ buffer .= $ chunk ;
204+ });
205+ });
206+
207+ $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
208+ $ parser ->handle ($ connection );
209+
210+ $ data = "POST / HTTP/1.0 \r\nContent-Length: 6 \r\n\r\n" ;
211+ $ data .= 'RANDOM DATA ' ;
212+ $ connection ->emit ('data ' , array ($ data ));
213+
214+ $ this ->assertSame ('RANDOM ' , $ buffer );
110215 }
111216
112217 public function testHeadersEventShouldParsePathAndQueryString ()
113218 {
114219 $ request = null ;
115220
116221 $ parser = new RequestHeaderParser ();
117- $ parser ->on ('headers ' , function ($ parsedRequest, $ parsedBodyBuffer ) use (&$ request ) {
222+ $ parser ->on ('headers ' , function ($ parsedRequest ) use (&$ request ) {
118223 $ request = $ parsedRequest ;
119224 });
120225
@@ -197,35 +302,6 @@ public function testHeaderOverflowShouldEmitError()
197302 $ this ->assertSame ($ connection , $ passedConnection );
198303 }
199304
200- public function testHeaderOverflowShouldNotEmitErrorWhenDataExceedsMaxHeaderSize ()
201- {
202- $ request = null ;
203- $ bodyBuffer = null ;
204-
205- $ parser = new RequestHeaderParser ();
206- $ parser ->on ('headers ' , function ($ parsedRequest , $ parsedBodyBuffer ) use (&$ request , &$ bodyBuffer ) {
207- $ request = $ parsedRequest ;
208- $ bodyBuffer = $ parsedBodyBuffer ;
209- });
210-
211- $ connection = $ this ->getMockBuilder ('React\Socket\Connection ' )->disableOriginalConstructor ()->setMethods (null )->getMock ();
212- $ parser ->handle ($ connection );
213-
214- $ data = $ this ->createAdvancedPostRequest ();
215- $ body = str_repeat ('A ' , 8193 - strlen ($ data ));
216- $ data .= $ body ;
217- $ connection ->emit ('data ' , array ($ data ));
218-
219- $ headers = array (
220- 'Host ' => array ('example.com ' ),
221- 'User-Agent ' => array ('react/alpha ' ),
222- 'Connection ' => array ('close ' ),
223- );
224- $ this ->assertSame ($ headers , $ request ->getHeaders ());
225-
226- $ this ->assertSame ($ body , $ bodyBuffer );
227- }
228-
229305 public function testInvalidEmptyRequestHeadersParseException ()
230306 {
231307 $ error = null ;
0 commit comments