44
55Event-driven, streaming plaintext HTTP and secure HTTPS server for [ ReactPHP] ( https://reactphp.org/ ) .
66
7- ** Table of Contents **
7+ ** Table of contents **
88
99* [ Quickstart example] ( #quickstart-example )
1010* [ Usage] ( #usage )
@@ -15,13 +15,13 @@ Event-driven, streaming plaintext HTTP and secure HTTPS server for [ReactPHP](ht
1515 * [ Request parameters] ( #request-parameters )
1616 * [ Query parameters] ( #query-parameters )
1717 * [ Request body] ( #request-body )
18- * [ Streaming request] ( #streaming-request )
18+ * [ Streaming incoming request] ( #streaming-incoming -request )
1919 * [ Request method] ( #request-method )
2020 * [ Cookie parameters] ( #cookie-parameters )
2121 * [ Invalid request] ( #invalid-request )
2222 * [ Response] ( #response )
2323 * [ Deferred response] ( #deferred-response )
24- * [ Streaming response] ( #streaming-response )
24+ * [ Streaming outgoing response] ( #streaming-outgoing -response )
2525 * [ Response length] ( #response-length )
2626 * [ Invalid response] ( #invalid-response )
2727 * [ Default response headers] ( #default-response-headers )
@@ -220,7 +220,7 @@ in memory. It will invoke the request handler function once the HTTP request
220220headers have been received, i.e. before receiving the potentially much larger
221221HTTP request body. This means the [ request] ( #request ) passed to your request
222222handler function may not be fully compatible with PSR-7. See also
223- [ streaming request] ( #streaming-request ) below for more details.
223+ [ streaming incoming request] ( #streaming-incoming -request ) below for more details.
224224
225225### listen()
226226
@@ -389,7 +389,7 @@ This includes the parsed request body and any file uploads.
389389
390390> If you're using the advanced [ ` StreamingServer ` ] ( #streamingserver ) class, jump
391391 to the next chapter to learn more about how to process a
392- [ streaming request] ( #streaming-request ) .
392+ [ streaming incoming request] ( #streaming-incoming -request ) .
393393
394394As stated above, each incoming HTTP request is always represented by the
395395[ PSR-7 ` ServerRequestInterface ` ] ( https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface ) .
@@ -485,7 +485,9 @@ header or when using `Transfer-Encoding: chunked` for HTTP/1.1 requests.
485485 intermediary ` HTTP/1.1 100 Continue ` response to the client. This ensures you
486486 will receive the request body without a delay as expected.
487487
488- #### Streaming request
488+ #### Streaming incoming request
489+
490+ <a id =" streaming-request " ></a ><!-- legacy fragment id -->
489491
490492If you're using the advanced [ ` StreamingServer ` ] ( #streamingserver ) , the
491493request object will be processed once the request headers have been received.
@@ -784,7 +786,9 @@ The promise cancellation handler can be used to clean up any pending resources
784786allocated in this case (if applicable).
785787If a promise is resolved after the client closes, it will simply be ignored.
786788
787- #### Streaming response
789+ #### Streaming outgoing response
790+
791+ <a id =" streaming-response " ></a ><!-- legacy fragment id -->
788792
789793The ` Response ` class in this project supports to add an instance which implements the
790794[ ReactPHP ReadableStreamInterface] ( https://github.com/reactphp/stream#readablestreaminterface )
@@ -897,7 +901,7 @@ $server = new Server(function (ServerRequestInterface $request) {
897901```
898902
899903If the response body size is unknown, a ` Content-Length ` response header can not
900- be added automatically. When using a [ streaming response] ( #streaming-response )
904+ be added automatically. When using a [ streaming outgoing response] ( #streaming-outgoing -response )
901905without an explicit ` Content-Length ` response header, outgoing HTTP/1.1 response
902906messages will automatically use ` Transfer-Encoding: chunked ` while legacy HTTP/1.0
903907response messages will contain the plain response body. If you know the length
@@ -959,8 +963,8 @@ $server->on('error', function (Exception $e) {
959963Note that the server will also emit an ` error ` event if the client sends an
960964invalid HTTP request that never reaches your request handler function. See
961965also [ invalid request] ( #invalid-request ) for more details.
962- Additionally, a [ streaming request] ( #streaming-request ) body can also emit
963- an ` error ` event on the request body.
966+ Additionally, a [ streaming incoming request] ( #streaming-incoming- request ) body
967+ can also emit an ` error ` event on the request body.
964968
965969The server will only send a very generic ` 500 ` (Interval Server Error) HTTP
966970error response without any further details to the client if an unhandled
@@ -1199,6 +1203,64 @@ feel free to add it to this list.
11991203
12001204### React\Http\Middleware
12011205
1206+ #### StreamingRequestMiddleware
1207+
1208+ The ` StreamingRequestMiddleware ` can be used to
1209+ process incoming requests with a streaming request body (without buffering).
1210+
1211+ This allows you to process requests of any size without buffering the request
1212+ body in memory. Instead, it will represent the request body as a
1213+ [ ` ReadableStreamInterface ` ] ( https://github.com/reactphp/stream#readablestreaminterface )
1214+ that emit chunks of incoming data as it is received:
1215+
1216+ ``` php
1217+ $server = new React\Http\Server(array(
1218+ new React\Http\Middleware\StreamingRequestMiddleware(),
1219+ function (Psr\Http\Message\ServerRequestInterface $request) {
1220+ $body = $request->getBody();
1221+ assert($body instanceof Psr\Http\Message\StreamInterface);
1222+ assert($body instanceof React\Stream\ReadableStreamInterface);
1223+
1224+ return new React\Promise\Promise(function ($resolve) use ($body) {
1225+ $bytes = 0;
1226+ $body->on('data', function ($chunk) use (& $bytes) {
1227+ $bytes += \count($chunk);
1228+ });
1229+ $body->on('close', function () use (& $bytes, $resolve) {
1230+ $resolve(new React\Http\Response(
1231+ 200,
1232+ [],
1233+ "Received $bytes bytes\n"
1234+ ));
1235+ });
1236+ });
1237+ }
1238+ ));
1239+ ```
1240+
1241+ See also [ streaming incoming request] ( #streaming-incoming-request )
1242+ for more details.
1243+
1244+ Additionally, this middleware can be used in combination with the
1245+ [ ` LimitConcurrentRequestsMiddleware ` ] ( #limitconcurrentrequestsmiddleware ) and
1246+ [ ` RequestBodyBufferMiddleware ` ] ( #requestbodybuffermiddleware ) (see below)
1247+ to explicitly configure the total number of requests that can be handled at
1248+ once:
1249+
1250+ ``` php
1251+ $server = new React\Http\Server(array(
1252+ new React\Http\Middleware\StreamingRequestMiddleware(),
1253+ new React\Http\Middleware\LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
1254+ new React\Http\Middleware\RequestBodyBufferMiddleware(2 * 1024 * 1024), // 2 MiB per request
1255+ new React\Http\Middleware\RequestBodyParserMiddleware(),
1256+ $handler
1257+ ));
1258+ ```
1259+
1260+ > Internally, this class is used as a "marker" to not trigger the default
1261+ request buffering behavior in the ` Server ` . It does not implement any logic
1262+ on its own.
1263+
12021264#### LimitConcurrentRequestsMiddleware
12031265
12041266The ` LimitConcurrentRequestsMiddleware ` can be used to
0 commit comments