diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f9cfb41..9a762083 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,6 @@ jobs: - 7.4 - 7.3 - 7.2 - - 7.1 steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 diff --git a/composer.json b/composer.json index 809e81c9..50e1fc69 100644 --- a/composer.json +++ b/composer.json @@ -26,17 +26,16 @@ } ], "require": { - "php": ">=7.1", + "php": ">=7.2 || ^8.0", "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "fig/http-message-util": "^1.1", - "psr/http-message": "^1.0", + "psr/http-message": "^2.0", "react/event-loop": "^1.2", "react/promise": "^3.2 || ^2.3 || ^1.2.1", "react/socket": "^1.16", "react/stream": "^1.4" }, "require-dev": { - "clue/http-proxy-react": "^1.8", "clue/reactphp-ssh-proxy": "^1.4", "clue/socks-react": "^1.4", "phpunit/phpunit": "^9.6 || ^7.5", diff --git a/examples/11-client-http-proxy.php b/examples/11-client-http-proxy.php deleted file mode 100644 index f15cf2a0..00000000 --- a/examples/11-client-http-proxy.php +++ /dev/null @@ -1,31 +0,0 @@ - $proxy, - 'dns' => false -]); - -$browser = new Browser($connector); - -// demo fetching HTTP headers (or bail out otherwise) -$browser->get('https://www.google.com/')->then(function (ResponseInterface $response) { - echo (string) $response->getBody(); -}, function (Exception $e) { - echo 'Error: ' . $e->getMessage() . PHP_EOL; -}); diff --git a/src/Io/AbstractMessage.php b/src/Io/AbstractMessage.php index 232a5442..085e6b2c 100644 --- a/src/Io/AbstractMessage.php +++ b/src/Io/AbstractMessage.php @@ -65,45 +65,45 @@ protected function __construct($protocolVersion, array $headers, StreamInterface $this->body = $body; } - public function getProtocolVersion() + public function getProtocolVersion(): string { return $this->protocolVersion; } - public function withProtocolVersion($version) + public function withProtocolVersion(string $version): MessageInterface { - if ((string) $version === $this->protocolVersion) { + if ($version === $this->protocolVersion) { return $this; } $message = clone $this; - $message->protocolVersion = (string) $version; + $message->protocolVersion = $version; return $message; } - public function getHeaders() + public function getHeaders(): array { return $this->headers; } - public function hasHeader($name) + public function hasHeader(string $name): bool { return isset($this->headerNamesLowerCase[\strtolower($name)]); } - public function getHeader($name) + public function getHeader(string $name): array { $lower = \strtolower($name); return isset($this->headerNamesLowerCase[$lower]) ? $this->headers[$this->headerNamesLowerCase[$lower]] : []; } - public function getHeaderLine($name) + public function getHeaderLine(string $name): string { return \implode(', ', $this->getHeader($name)); } - public function withHeader($name, $value) + public function withHeader(string $name, $value): MessageInterface { if ($value === []) { return $this->withoutHeader($name); @@ -131,7 +131,7 @@ public function withHeader($name, $value) return $message; } - public function withAddedHeader($name, $value) + public function withAddedHeader(string $name, $value): MessageInterface { if ($value === []) { return $this; @@ -140,7 +140,7 @@ public function withAddedHeader($name, $value) return $this->withHeader($name, \array_merge($this->getHeader($name), \is_array($value) ? $value : [$value])); } - public function withoutHeader($name) + public function withoutHeader(string $name): MessageInterface { $lower = \strtolower($name); if (!isset($this->headerNamesLowerCase[$lower])) { @@ -153,12 +153,12 @@ public function withoutHeader($name) return $message; } - public function getBody() + public function getBody(): StreamInterface { return $this->body; } - public function withBody(StreamInterface $body) + public function withBody(StreamInterface $body): MessageInterface { if ($body === $this->body) { return $this; diff --git a/src/Io/AbstractRequest.php b/src/Io/AbstractRequest.php index 1182f7ab..7e9f5b9a 100644 --- a/src/Io/AbstractRequest.php +++ b/src/Io/AbstractRequest.php @@ -71,7 +71,7 @@ protected function __construct( $this->uri = $uri; } - public function getRequestTarget() + public function getRequestTarget(): string { if ($this->requestTarget !== null) { return $this->requestTarget; @@ -88,9 +88,9 @@ public function getRequestTarget() return $target; } - public function withRequestTarget($requestTarget) + public function withRequestTarget(string $requestTarget): RequestInterface { - if ((string) $requestTarget === $this->requestTarget) { + if ($requestTarget === $this->requestTarget) { return $this; } @@ -100,12 +100,12 @@ public function withRequestTarget($requestTarget) return $request; } - public function getMethod() + public function getMethod(): string { return $this->method; } - public function withMethod($method) + public function withMethod(string $method): RequestInterface { if ((string) $method === $this->method) { return $this; @@ -117,12 +117,12 @@ public function withMethod($method) return $request; } - public function getUri() + public function getUri(): UriInterface { return $this->uri; } - public function withUri(UriInterface $uri, $preserveHost = false) + public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface { if ($uri === $this->uri) { return $this; diff --git a/src/Io/BufferedBody.php b/src/Io/BufferedBody.php index 9b1d9887..87d9f882 100644 --- a/src/Io/BufferedBody.php +++ b/src/Io/BufferedBody.php @@ -23,7 +23,7 @@ public function __construct($buffer) $this->buffer = $buffer; } - public function __toString() + public function __toString(): string { if ($this->closed) { return ''; @@ -34,7 +34,7 @@ public function __toString() return $this->getContents(); } - public function close() + public function close(): void { $this->buffer = ''; $this->position = 0; @@ -48,12 +48,12 @@ public function detach() return null; } - public function getSize() + public function getSize(): ?int { return $this->closed ? null : \strlen($this->buffer); } - public function tell() + public function tell(): int { if ($this->closed) { throw new \RuntimeException('Unable to tell position of closed stream'); @@ -62,17 +62,17 @@ public function tell() return $this->position; } - public function eof() + public function eof(): bool { return $this->position >= \strlen($this->buffer); } - public function isSeekable() + public function isSeekable(): bool { return !$this->closed; } - public function seek($offset, $whence = \SEEK_SET) + public function seek($offset, $whence = \SEEK_SET): void { if ($this->closed) { throw new \RuntimeException('Unable to seek on closed stream'); @@ -96,17 +96,17 @@ public function seek($offset, $whence = \SEEK_SET) } } - public function rewind() + public function rewind(): void { $this->seek(0); } - public function isWritable() + public function isWritable(): bool { return !$this->closed; } - public function write($string) + public function write(string $string): int { if ($this->closed) { throw new \RuntimeException('Unable to write to closed stream'); @@ -127,12 +127,12 @@ public function write($string) return $len; } - public function isReadable() + public function isReadable(): bool { return !$this->closed; } - public function read($length) + public function read(int $length): string { if ($this->closed) { throw new \RuntimeException('Unable to read from closed stream'); @@ -156,7 +156,7 @@ public function read($length) return \substr($this->buffer, $pos, $length); } - public function getContents() + public function getContents(): string { if ($this->closed) { throw new \RuntimeException('Unable to read from closed stream'); diff --git a/src/Io/EmptyBodyStream.php b/src/Io/EmptyBodyStream.php index 7f9c8ad0..257dde4f 100644 --- a/src/Io/EmptyBodyStream.php +++ b/src/Io/EmptyBodyStream.php @@ -29,7 +29,7 @@ class EmptyBodyStream extends EventEmitter implements StreamInterface, ReadableS { private $closed = false; - public function isReadable() + public function isReadable(): bool { return !$this->closed; } @@ -51,7 +51,7 @@ public function pipe(WritableStreamInterface $dest, array $options = []) return $dest; } - public function close() + public function close(): void { if ($this->closed) { return; @@ -63,13 +63,13 @@ public function close() $this->removeAllListeners(); } - public function getSize() + public function getSize(): ?int { return 0; } /** @ignore */ - public function __toString() + public function __toString(): string { return ''; } @@ -81,55 +81,55 @@ public function detach() } /** @ignore */ - public function tell() + public function tell(): int { throw new \BadMethodCallException(); } /** @ignore */ - public function eof() + public function eof(): bool { throw new \BadMethodCallException(); } /** @ignore */ - public function isSeekable() + public function isSeekable(): bool { return false; } /** @ignore */ - public function seek($offset, $whence = SEEK_SET) + public function seek($offset, $whence = SEEK_SET): void { throw new \BadMethodCallException(); } /** @ignore */ - public function rewind() + public function rewind(): void { throw new \BadMethodCallException(); } /** @ignore */ - public function isWritable() + public function isWritable(): bool { return false; } /** @ignore */ - public function write($string) + public function write($string): int { throw new \BadMethodCallException(); } /** @ignore */ - public function read($length) + public function read($length): string { throw new \BadMethodCallException(); } /** @ignore */ - public function getContents() + public function getContents(): string { return ''; } diff --git a/src/Io/HttpBodyStream.php b/src/Io/HttpBodyStream.php index 8be9b854..d41f6063 100644 --- a/src/Io/HttpBodyStream.php +++ b/src/Io/HttpBodyStream.php @@ -45,7 +45,7 @@ public function __construct(ReadableStreamInterface $input, $size) $this->input->on('close', [$this, 'close']); } - public function isReadable() + public function isReadable(): bool { return !$this->closed && $this->input->isReadable(); } @@ -67,7 +67,7 @@ public function pipe(WritableStreamInterface $dest, array $options = []) return $dest; } - public function close() + public function close(): void { if ($this->closed) { return; @@ -81,13 +81,13 @@ public function close() $this->removeAllListeners(); } - public function getSize() + public function getSize(): ?int { return $this->size; } /** @ignore */ - public function __toString() + public function __toString(): string { return ''; } @@ -99,55 +99,55 @@ public function detach() } /** @ignore */ - public function tell() + public function tell(): int { throw new \BadMethodCallException(); } /** @ignore */ - public function eof() + public function eof(): bool { throw new \BadMethodCallException(); } /** @ignore */ - public function isSeekable() + public function isSeekable(): bool { return false; } /** @ignore */ - public function seek($offset, $whence = SEEK_SET) + public function seek($offset, $whence = SEEK_SET): void { throw new \BadMethodCallException(); } /** @ignore */ - public function rewind() + public function rewind(): void { throw new \BadMethodCallException(); } /** @ignore */ - public function isWritable() + public function isWritable(): bool { return false; } /** @ignore */ - public function write($string) + public function write(string $string): int { throw new \BadMethodCallException(); } /** @ignore */ - public function read($length) + public function read(int $length): string { throw new \BadMethodCallException(); } /** @ignore */ - public function getContents() + public function getContents(): string { return ''; } diff --git a/src/Io/ReadableBodyStream.php b/src/Io/ReadableBodyStream.php index 9a8bd105..63d991c2 100644 --- a/src/Io/ReadableBodyStream.php +++ b/src/Io/ReadableBodyStream.php @@ -39,7 +39,7 @@ public function __construct(ReadableStreamInterface $input, $size = null) $input->on('close', [$this, 'close']); } - public function close() + public function close(): void { if (!$this->closed) { $this->closed = true; @@ -50,7 +50,7 @@ public function close() } } - public function isReadable() + public function isReadable(): bool { return $this->input->isReadable(); } @@ -72,12 +72,12 @@ public function pipe(WritableStreamInterface $dest, array $options = []) return $dest; } - public function eof() + public function eof(): bool { return !$this->isReadable(); } - public function __toString() + public function __toString(): string { return ''; } @@ -87,47 +87,47 @@ public function detach() throw new \BadMethodCallException(); } - public function getSize() + public function getSize(): ?int { return $this->size; } - public function tell() + public function tell(): int { throw new \BadMethodCallException(); } - public function isSeekable() + public function isSeekable(): bool { return false; } - public function seek($offset, $whence = SEEK_SET) + public function seek(int $offset, int $whence = SEEK_SET): void { throw new \BadMethodCallException(); } - public function rewind() + public function rewind(): void { throw new \BadMethodCallException(); } - public function isWritable() + public function isWritable(): bool { return false; } - public function write($string) + public function write(string $string): int { throw new \BadMethodCallException(); } - public function read($length) + public function read(int $length): string { throw new \BadMethodCallException(); } - public function getContents() + public function getContents(): string { throw new \BadMethodCallException(); } diff --git a/src/Io/UploadedFile.php b/src/Io/UploadedFile.php index b0d0dd98..b42e96ea 100644 --- a/src/Io/UploadedFile.php +++ b/src/Io/UploadedFile.php @@ -79,7 +79,7 @@ public function __construct(StreamInterface $stream, $size, $error, $filename, $ /** * {@inheritdoc} */ - public function getStream() + public function getStream(): StreamInterface { if ($this->error !== \UPLOAD_ERR_OK) { throw new RuntimeException('Cannot retrieve stream due to upload error'); @@ -91,7 +91,7 @@ public function getStream() /** * {@inheritdoc} */ - public function moveTo($targetPath) + public function moveTo(string $targetPath): void { throw new RuntimeException('Not implemented'); } @@ -99,7 +99,7 @@ public function moveTo($targetPath) /** * {@inheritdoc} */ - public function getSize() + public function getSize(): ?int { return $this->size; } @@ -107,7 +107,7 @@ public function getSize() /** * {@inheritdoc} */ - public function getError() + public function getError(): int { return $this->error; } @@ -115,7 +115,7 @@ public function getError() /** * {@inheritdoc} */ - public function getClientFilename() + public function getClientFilename(): ?string { return $this->filename; } @@ -123,7 +123,7 @@ public function getClientFilename() /** * {@inheritdoc} */ - public function getClientMediaType() + public function getClientMediaType(): ?string { return $this->mediaType; } diff --git a/src/Message/Response.php b/src/Message/Response.php index 93557fab..1c8c96f8 100644 --- a/src/Message/Response.php +++ b/src/Message/Response.php @@ -319,29 +319,29 @@ public function __construct( $this->reasonPhrase = ($reason !== '' && $reason !== null) ? (string) $reason : self::getReasonPhraseForStatusCode($status); } - public function getStatusCode() + public function getStatusCode(): int { return $this->statusCode; } - public function withStatus($code, $reasonPhrase = '') + public function withStatus(int $code, string $reasonPhrase = ''): ResponseInterface { - if ((string) $reasonPhrase === '') { + if ($reasonPhrase === '') { $reasonPhrase = self::getReasonPhraseForStatusCode($code); } - if ($this->statusCode === (int) $code && $this->reasonPhrase === (string) $reasonPhrase) { + if ($this->statusCode === $code && $this->reasonPhrase === $reasonPhrase) { return $this; } $response = clone $this; - $response->statusCode = (int) $code; - $response->reasonPhrase = (string) $reasonPhrase; + $response->statusCode = $code; + $response->reasonPhrase = $reasonPhrase; return $response; } - public function getReasonPhrase() + public function getReasonPhrase(): string { return $this->reasonPhrase; } diff --git a/src/Message/ServerRequest.php b/src/Message/ServerRequest.php index da0d76ab..562f01dd 100644 --- a/src/Message/ServerRequest.php +++ b/src/Message/ServerRequest.php @@ -87,41 +87,41 @@ public function __construct( } } - public function getServerParams() + public function getServerParams(): array { return $this->serverParams; } - public function getCookieParams() + public function getCookieParams(): array { return $this->cookies; } - public function withCookieParams(array $cookies) + public function withCookieParams(array $cookies): ServerRequestInterface { $new = clone $this; $new->cookies = $cookies; return $new; } - public function getQueryParams() + public function getQueryParams(): array { return $this->queryParams; } - public function withQueryParams(array $query) + public function withQueryParams(array $query): ServerRequestInterface { $new = clone $this; $new->queryParams = $query; return $new; } - public function getUploadedFiles() + public function getUploadedFiles(): array { return $this->fileParams; } - public function withUploadedFiles(array $uploadedFiles) + public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface { $new = clone $this; $new->fileParams = $uploadedFiles; @@ -133,14 +133,14 @@ public function getParsedBody() return $this->parsedBody; } - public function withParsedBody($data) + public function withParsedBody($data): ServerRequestInterface { $new = clone $this; $new->parsedBody = $data; return $new; } - public function getAttributes() + public function getAttributes(): array { return $this->attributes; } @@ -153,14 +153,14 @@ public function getAttribute($name, $default = null) return $this->attributes[$name]; } - public function withAttribute($name, $value) + public function withAttribute(string $name, $value): ServerRequestInterface { $new = clone $this; $new->attributes[$name] = $value; return $new; } - public function withoutAttribute($name) + public function withoutAttribute(string $name): ServerRequestInterface { $new = clone $this; unset($new->attributes[$name]); diff --git a/src/Message/Uri.php b/src/Message/Uri.php index 661f90c4..c3f31cf9 100644 --- a/src/Message/Uri.php +++ b/src/Message/Uri.php @@ -79,12 +79,12 @@ public function __construct($uri) } } - public function getScheme() + public function getScheme(): string { return $this->scheme; } - public function getAuthority() + public function getAuthority(): string { if ($this->host === '') { return ''; @@ -93,37 +93,37 @@ public function getAuthority() return ($this->userInfo !== '' ? $this->userInfo . '@' : '') . $this->host . ($this->port !== null ? ':' . $this->port : ''); } - public function getUserInfo() + public function getUserInfo(): string { return $this->userInfo; } - public function getHost() + public function getHost(): string { return $this->host; } - public function getPort() + public function getPort(): ?int { return $this->port; } - public function getPath() + public function getPath(): string { return $this->path; } - public function getQuery() + public function getQuery(): string { return $this->query; } - public function getFragment() + public function getFragment(): string { return $this->fragment; } - public function withScheme($scheme) + public function withScheme(string $scheme): UriInterface { $scheme = \strtolower($scheme); if ($scheme === $this->scheme) { @@ -144,7 +144,7 @@ public function withScheme($scheme) return $new; } - public function withUserInfo($user, $password = null) + public function withUserInfo(string $user, ?string $password = null): UriInterface { $userInfo = $this->encode($user, \PHP_URL_USER) . ($password !== null ? ':' . $this->encode($password, \PHP_URL_PASS) : ''); if ($userInfo === $this->userInfo) { @@ -157,7 +157,7 @@ public function withUserInfo($user, $password = null) return $new; } - public function withHost($host) + public function withHost(string $host): UriInterface { $host = \strtolower($host); if ($host === $this->host) { @@ -174,9 +174,8 @@ public function withHost($host) return $new; } - public function withPort($port) + public function withPort(?int $port): UriInterface { - $port = $port === null ? null : (int) $port; if (($port === 80 && $this->scheme === 'http') || ($port === 443 && $this->scheme === 'https')) { $port = null; } @@ -195,7 +194,7 @@ public function withPort($port) return $new; } - public function withPath($path) + public function withPath(string $path): UriInterface { $path = $this->encode($path, \PHP_URL_PATH); if ($path === $this->path) { @@ -208,7 +207,7 @@ public function withPath($path) return $new; } - public function withQuery($query) + public function withQuery(string $query): UriInterface { $query = $this->encode($query, \PHP_URL_QUERY); if ($query === $this->query) { @@ -221,7 +220,7 @@ public function withQuery($query) return $new; } - public function withFragment($fragment) + public function withFragment(string $fragment): UriInterface { $fragment = $this->encode($fragment, \PHP_URL_FRAGMENT); if ($fragment === $this->fragment) { @@ -234,7 +233,7 @@ public function withFragment($fragment) return $new; } - public function __toString() + public function __toString(): string { $uri = ''; if ($this->scheme !== '') { diff --git a/tests/Io/HttpBodyStreamTest.php b/tests/Io/HttpBodyStreamTest.php index c246bd96..6634906f 100644 --- a/tests/Io/HttpBodyStreamTest.php +++ b/tests/Io/HttpBodyStreamTest.php @@ -10,7 +10,10 @@ class HttpBodyStreamTest extends TestCase { + /** @var ThroughStream */ private $input; + + /** @var HttpBodyStream */ private $bodyStream; /** @@ -133,7 +136,7 @@ public function testWrite() public function testRead() { $this->expectException(\BadMethodCallException::class); - $this->bodyStream->read(''); + $this->bodyStream->read(0); } public function testGetContents()