diff --git a/README.md b/README.md index 5a58c02b..e5c5f339 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,7 @@ Event-driven, streaming plaintext HTTP and secure HTTPS server for [ReactPHP](ht * [getHeader()](#getheader) * [getHeaderLine()](#getheaderline) * [hasHeader()](#hasheader) - * [expectsContinue()](#expectscontinue) * [Response](#response) - * [writeContinue()](#writecontinue) * [writeHead()](#writehead) * [Install](#install) * [Tests](#tests) @@ -197,18 +195,6 @@ Returns a comma-separated list of all values for this header name or an empty st The `hasHeader(string $name): bool` method can be used to check if a header exists by the given case-insensitive name. -#### expectsContinue() - -The `expectsContinue(): bool` method can be used to -check if the request headers contain the `Expect: 100-continue` header. - -This header MAY be included when an HTTP/1.1 client wants to send a bigger -request body. -See [`writeContinue()`](#writecontinue) for more details. - -This will always be `false` for HTTP/1.0 requests, regardless of what -any header values say. - ### Response The `Response` class is responsible for streaming the outgoing response body. @@ -227,48 +213,6 @@ See [`writeHead()`](#writehead) for more details. See the above usage example and the class outline for details. -#### writeContinue() - -The `writeContinue(): void` method can be used to -send an intermediary `HTTP/1.1 100 continue` response. - -This is a feature that is implemented by *many* HTTP/1.1 clients. -When clients want to send a bigger request body, they MAY send only the request -headers with an additional `Expect: 100-continue` header and wait before -sending the actual (large) message body. - -The server side MAY use this header to verify if the request message is -acceptable by checking the request headers (such as `Content-Length` or HTTP -authentication) and then ask the client to continue with sending the message body. -Otherwise, the server can send a normal HTTP response message and save the -client from transfering the whole body at all. - -This method is mostly useful in combination with the -[`expectsContinue()`](#expectscontinue) method like this: - -```php -$http->on('request', function (Request $request, Response $response) { - if ($request->expectsContinue()) { - $response->writeContinue(); - } - - $response->writeHead(200, array('Content-Type' => 'text/plain')); - $response->end("Hello World!\n"); -}); -``` - -Note that calling this method is strictly optional for HTTP/1.1 responses. -If you do not use it, then a HTTP/1.1 client MUST continue sending the -request body after waiting some time. - -This method MUST NOT be invoked after calling [`writeHead()`](#writehead). -This method MUST NOT be invoked if this is not a HTTP/1.1 response -(please check [`expectsContinue()`](#expectscontinue) as above). -Calling this method after sending the headers or if this is not a HTTP/1.1 -response is an error that will result in an `Exception` -(unless the response has ended/closed already). -Calling this method after the response has ended/closed is a NOOP. - #### writeHead() The `writeHead(int $status = 200, array $headers = array(): void` method can be used to diff --git a/src/Request.php b/src/Request.php index e3559560..05df869e 100644 --- a/src/Request.php +++ b/src/Request.php @@ -149,24 +149,6 @@ public function hasHeader($name) return $this->request->hasHeader($name); } - /** - * Checks if the request headers contain the `Expect: 100-continue` header. - * - * This header MAY be included when an HTTP/1.1 client wants to send a bigger - * request body. - * See [`writeContinue()`] for more details. - * - * This will always be `false` for HTTP/1.0 requests, regardless of what - * any header values say. - * - * @return bool - * @see Response::writeContinue() - */ - public function expectsContinue() - { - return $this->getProtocolVersion() !== '1.0' && '100-continue' === strtolower($this->getHeaderLine('Expect')); - } - public function isReadable() { return $this->readable; diff --git a/src/Response.php b/src/Response.php index e7e34182..5442f7a5 100644 --- a/src/Response.php +++ b/src/Response.php @@ -66,65 +66,6 @@ public function isWritable() return $this->writable; } - /** - * Sends an intermediary `HTTP/1.1 100 continue` response. - * - * This is a feature that is implemented by *many* HTTP/1.1 clients. - * When clients want to send a bigger request body, they MAY send only the request - * headers with an additional `Expect: 100-continue` header and wait before - * sending the actual (large) message body. - * - * The server side MAY use this header to verify if the request message is - * acceptable by checking the request headers (such as `Content-Length` or HTTP - * authentication) and then ask the client to continue with sending the message body. - * Otherwise, the server can send a normal HTTP response message and save the - * client from transfering the whole body at all. - * - * This method is mostly useful in combination with the - * [`expectsContinue()`] method like this: - * - * ```php - * $http->on('request', function (Request $request, Response $response) { - * if ($request->expectsContinue()) { - * $response->writeContinue(); - * } - * - * $response->writeHead(200, array('Content-Type' => 'text/plain')); - * $response->end("Hello World!\n"); - * }); - * ``` - * - * Note that calling this method is strictly optional for HTTP/1.1 responses. - * If you do not use it, then a HTTP/1.1 client MUST continue sending the - * request body after waiting some time. - * - * This method MUST NOT be invoked after calling `writeHead()`. - * This method MUST NOT be invoked if this is not a HTTP/1.1 response - * (please check [`expectsContinue()`] as above). - * Calling this method after sending the headers or if this is not a HTTP/1.1 - * response is an error that will result in an `Exception` - * (unless the response has ended/closed already). - * Calling this method after the response has ended/closed is a NOOP. - * - * @return void - * @throws \Exception - * @see Request::expectsContinue() - */ - public function writeContinue() - { - if (!$this->writable) { - return; - } - if ($this->protocolVersion !== '1.1') { - throw new \Exception('Continue requires a HTTP/1.1 message'); - } - if ($this->headWritten) { - throw new \Exception('Response head has already been written.'); - } - - $this->conn->write("HTTP/1.1 100 Continue\r\n\r\n"); - } - /** * Writes the given HTTP message header. * diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 3d010b7f..bafb17ac 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -14,42 +14,6 @@ public function setUp() $this->stream = $this->getMockBuilder('React\Stream\ReadableStreamInterface')->getMock(); } - /** @test */ - public function expectsContinueShouldBeFalseByDefault() - { - $headers = array(); - $request = new Request(new Psr('GET', '/', $headers, null, '1.1'), $this->stream); - - $this->assertFalse($request->expectsContinue()); - } - - /** @test */ - public function expectsContinueShouldBeTrueIfContinueExpected() - { - $headers = array('Expect' => array('100-continue')); - $request = new Request(new Psr('GET', '/', $headers, null, '1.1'), $this->stream); - - $this->assertTrue($request->expectsContinue()); - } - - /** @test */ - public function expectsContinueShouldBeTrueIfContinueExpectedCaseInsensitive() - { - $headers = array('EXPECT' => array('100-CONTINUE')); - $request = new Request(new Psr('GET', '/', $headers, null, '1.1'), $this->stream); - - $this->assertTrue($request->expectsContinue()); - } - - /** @test */ - public function expectsContinueShouldBeFalseForHttp10() - { - $headers = array('Expect' => array('100-continue')); - $request = new Request(new Psr('GET', '/', $headers, null, '1.0'), $this->stream); - - $this->assertFalse($request->expectsContinue()); - } - public function testEmptyHeader() { $request = new Request(new Psr('GET', '/', array()), $this->stream); diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index b6367d37..65fc0598 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -330,55 +330,6 @@ public function testResponseBodyShouldSkipEmptyChunks() $response->end(); } - /** @test */ - public function writeContinueShouldSendContinueLineBeforeRealHeaders() - { - $conn = $this - ->getMockBuilder('React\Socket\ConnectionInterface') - ->getMock(); - $conn - ->expects($this->at(3)) - ->method('write') - ->with("HTTP/1.1 100 Continue\r\n\r\n"); - $conn - ->expects($this->at(4)) - ->method('write') - ->with($this->stringContains("HTTP/1.1 200 OK\r\n")); - - $response = new Response($conn); - $response->writeContinue(); - $response->writeHead(); - } - - /** - * @test - * @expectedException Exception - */ - public function writeContinueShouldThrowForHttp10() - { - $conn = $this - ->getMockBuilder('React\Socket\ConnectionInterface') - ->getMock(); - - $response = new Response($conn, '1.0'); - $response->writeContinue(); - } - - /** @expectedException Exception */ - public function testWriteContinueAfterWriteHeadShouldThrowException() - { - $conn = $this - ->getMockBuilder('React\Socket\ConnectionInterface') - ->getMock(); - $conn - ->expects($this->once()) - ->method('write'); - - $response = new Response($conn); - $response->writeHead(); - $response->writeContinue(); - } - /** @test */ public function shouldRemoveNewlinesFromHeaders() { @@ -551,18 +502,6 @@ public function testWriteHeadAfterCloseIsNoOp() $response->writeHead(); } - public function testWriteContinueAfterCloseIsNoOp() - { - $input = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock(); - $input->expects($this->once())->method('close'); - $input->expects($this->never())->method('write'); - - $response = new Response($input); - $response->close(); - - $response->writeContinue(); - } - public function testEndAfterCloseIsNoOp() { $input = $this->getMockBuilder('React\Stream\WritableStreamInterface')->getMock();