66use React \Socket \ServerInterface as SocketServerInterface ;
77use React \Socket \ConnectionInterface ;
88use Psr \Http \Message \RequestInterface ;
9+ use Doctrine \Instantiator \Exception \InvalidArgumentException ;
910
1011/**
1112 * The `Server` class is responsible for handling incoming connections and then
12- * emit a `request` event for each incoming HTTP request.
13+ * execute the execute the callback function passed to the constructor.
14+ *
15+ * It attaches itself to an instance of `React\Socket\ServerInterface` which
16+ * emits underlying streaming connections in order to then parse incoming data
17+ * as HTTP.
18+ *
19+ * For each incoming connection, it executes the callback function with the
20+ * respective [`Request`](#request) and [`Response`](#response) objects:
1321 *
1422 * ```php
1523 * $socket = new React\Socket\Server(8080, $loop);
1624 *
17- * $http = new React\Http\Server($socket);
25+ * $http = new React\Http\Server($socket, function (Request $request, Response $response) {
26+ * $response->writeHead(200, array('Content-Type' => 'text/plain'));
27+ * $response->end("Hello World!\n");
28+ * });
1829 * ```
1930 *
20- * For each incoming connection, it emits a `request` event with the respective
21- * [`Request`](#request) and [`Response`](#response) objects:
31+ * Similarly, you can also attach this to a
32+ * [`React\Socket\SecureServer`](https://github.com/reactphp/socket#secureserver)
33+ * in order to start a secure HTTPS server like this:
2234 *
2335 * ```php
24- * $http->on('request', function (Request $request, Response $response) {
36+ * $socket = new Server(8080, $loop);
37+ * $socket = new SecureServer($socket, $loop, array(
38+ * 'local_cert' => __DIR__ . '/localhost.pem'
39+ * ));
40+ *
41+ * $http = new React\Http\Server($socket, function (Request $request, Response $response) {
2542 * $response->writeHead(200, array('Content-Type' => 'text/plain'));
2643 * $response->end("Hello World!\n");
2744 * });
2845 * ```
2946 *
30- * See also [`Request`](#request) and [`Response`](#response) for more details.
31- *
32- * > Note that you SHOULD always listen for the `request` event.
33- * Failing to do so will result in the server parsing the incoming request,
34- * but never sending a response back to the client.
47+ * See also [`Request`](#request) and [`Response`](#response)
48+ * for more details(e.g. the request data body).
3549 *
3650 * The `Server` supports both HTTP/1.1 and HTTP/1.0 request messages.
37- * If a client sends an invalid request message or uses an invalid HTTP protocol
38- * version, it will emit an `error` event, send an HTTP error response to the
39- * client and close the connection:
51+ * If a client sends an invalid request message, uses an invalid HTTP protocol
52+ * version or sends an invalid `Transfer-Encoding` in the request header, it will
53+ * emit an `error` event, send an HTTP error response to the client and
54+ * close the connection:
4055 *
4156 * ```php
4257 * $http->on('error', function (Exception $e) {
4358 * echo 'Error: ' . $e->getMessage() . PHP_EOL;
4459 * });
4560 * ```
4661 *
62+ * The request object can also emit an error. Checkout [Request](#request)
63+ * for more details.
64+ *
4765 * @see Request
4866 * @see Response
4967 */
5068class Server extends EventEmitter
5169{
70+ private $ callback ;
71+
5272 /**
5373 * Creates a HTTP server that accepts connections from the given socket.
5474 *
5575 * It attaches itself to an instance of `React\Socket\ServerInterface` which
5676 * emits underlying streaming connections in order to then parse incoming data
57- * as HTTP:
77+ * as HTTP.
78+ *
79+ * For each incoming connection, it executes the callback function with the respective
80+ * [`Request`](#request) and [`Response`](#response) objects:
5881 *
5982 * ```php
6083 * $socket = new React\Socket\Server(8080, $loop);
6184 *
62- * $http = new React\Http\Server($socket);
85+ * $http = new React\Http\Server($socket, function (Request $request, Response $response) {
86+ * $response->writeHead(200, array('Content-Type' => 'text/plain'));
87+ * $response->end("Hello World!\n");
88+ * });
6389 * ```
6490 *
6591 * Similarly, you can also attach this to a
@@ -72,14 +98,23 @@ class Server extends EventEmitter
7298 * 'local_cert' => __DIR__ . '/localhost.pem'
7399 * ));
74100 *
75- * $http = new React\Http\Server($socket);
76- * ```
101+ * $http = new React\Http\Server($socket, function (Request $request, Response $response) {
102+ * $response->writeHead(200, array('Content-Type' => 'text/plain'));
103+ * $response->end("Hello World!\n");
104+ * });
105+ *```
77106 *
78107 * @param \React\Socket\ServerInterface $io
108+ * @param callable $callback
79109 */
80- public function __construct (SocketServerInterface $ io )
110+ public function __construct (SocketServerInterface $ io, $ callback )
81111 {
112+ if (!is_callable ($ callback )) {
113+ throw new InvalidArgumentException ();
114+ }
115+
82116 $ io ->on ('connection ' , array ($ this , 'handleConnection ' ));
117+ $ this ->callback = $ callback ;
83118 }
84119
85120 /** @internal */
@@ -176,7 +211,8 @@ public function handleRequest(ConnectionInterface $conn, RequestInterface $reque
176211 '[] '
177212 );
178213
179- $ this ->emit ('request ' , array ($ request , $ response ));
214+ $ callback = $ this ->callback ;
215+ $ callback ($ request , $ response );
180216
181217 if ($ contentLength === 0 ) {
182218 // If Body is empty or Content-Length is 0 and won't emit further data,
0 commit comments