Skip to content

Commit 24daf3c

Browse files
committedApr 26, 2023
Update for amphp/http v2
1 parent 89f6a4a commit 24daf3c

4 files changed

+90
-42
lines changed
 

‎composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@
3232
"php": ">=8.1",
3333
"amphp/amp": "^3",
3434
"amphp/byte-stream": "^2",
35-
"amphp/http": "^2-dev",
35+
"amphp/http": "^2",
3636
"amphp/http-client": "^5",
3737
"amphp/socket": "^2",
3838
"amphp/websocket": "^2",
3939
"league/uri": "^6",
4040
"psr/http-message": "^1",
41-
"revolt/event-loop": "^1 || ^0.2.4"
41+
"revolt/event-loop": "^1"
4242
},
4343
"require-dev": {
4444
"amphp/http-server": "^3",

‎src/Rfc6455Connector.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function connect(WebsocketHandshake $handshake, ?Cancellation $cancellati
7171
return;
7272
}
7373

74-
$extensions = \array_column(Http\parseFieldValueComponents($response, 'sec-websocket-extensions') ?? [], 0, 0);
74+
$extensions = Http\splitHeader($response, 'sec-websocket-extensions') ?? [];
7575

7676
foreach ($extensions as $extension) {
7777
if ($compressionContext = $compressionContextFactory?->fromServerHeader($extension)) {
@@ -111,7 +111,7 @@ private function generateRequest(WebsocketHandshake $handshake, string $key): Re
111111
$request->setTlsHandshakeTimeout($handshake->getTlsHandshakeTimeout());
112112
$request->setHeaderSizeLimit($handshake->getHeaderSizeLimit());
113113

114-
$extensions = \array_column(Http\parseFieldValueComponents($request, 'sec-websocket-extensions') ?? [], 0, 0);
114+
$extensions = Http\splitHeader($request, 'sec-websocket-extensions');
115115

116116
if ($this->compressionContextFactory && \extension_loaded('zlib')) {
117117
$extensions[] = $this->compressionContextFactory->createRequestHeader();

‎src/WebsocketHandshake.php

+85-37
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,36 @@
55
use Amp\ForbidSerialization;
66
use Amp\Http\Client\Request;
77
use Amp\Http\HttpMessage;
8+
use Amp\Http\HttpRequest;
89
use League\Uri;
910
use Psr\Http\Message\UriInterface as PsrUri;
1011

11-
final class WebsocketHandshake extends HttpMessage
12+
/**
13+
* @psalm-import-type HeaderParamArrayType from HttpMessage
14+
* @psalm-import-type HeaderParamValueType from HttpMessage
15+
* @psalm-import-type QueryArrayType from HttpRequest
16+
* @psalm-import-type QueryValueType from HttpRequest
17+
*/
18+
final class WebsocketHandshake extends HttpRequest
1219
{
1320
use ForbidSerialization;
1421

15-
private PsrUri $uri;
16-
1722
private float $tcpConnectTimeout = 10;
1823

1924
private float $tlsHandshakeTimeout = 10;
2025

2126
private int $headerSizeLimit = Request::DEFAULT_HEADER_SIZE_LIMIT;
2227

2328
/**
24-
* @param string|PsrUri $uri target address of websocket (e.g. ws://foo.bar/bar or
29+
* @param PsrUri|string $uri Target address of websocket (e.g. ws://foo.bar/bar or
2530
* wss://crypto.example/?secureConnection) or a PsrUri instance.
26-
* @param string[]|string[][] $headers
31+
* @param HeaderParamArrayType $headers
2732
*/
2833
public function __construct(PsrUri|string $uri, array $headers = [])
2934
{
30-
$this->uri = $this->makeUri($uri);
31-
$this->setHeaders($headers);
32-
}
35+
parent::__construct('GET', self::makeUri($uri));
3336

34-
/**
35-
* @return PsrUri Websocket URI (scheme will be either ws or wss).
36-
*/
37-
public function getUri(): PsrUri
38-
{
39-
return $this->uri;
37+
$this->setHeaders($headers);
4038
}
4139

4240
/**
@@ -45,7 +43,7 @@ public function getUri(): PsrUri
4543
public function withUri(PsrUri|string $uri): self
4644
{
4745
$clone = clone $this;
48-
$clone->uri = $clone->makeUri($uri);
46+
$clone->setUri(self::makeUri($uri));
4947

5048
return $clone;
5149
}
@@ -98,18 +96,13 @@ public function withHeaderSizeLimit(int $headerSizeLimit): self
9896
/**
9997
* Replaces all headers in the returned instance.
10098
*
101-
* @param array<non-empty-string, string|array<string>> $headers
99+
* @param HeaderParamArrayType $headers
102100
*
103101
* @return self Cloned object.
104102
*/
105103
public function withHeaders(array $headers): self
106104
{
107105
$clone = clone $this;
108-
109-
foreach ($clone->getRawHeaders() as [$field]) {
110-
$clone->removeHeader($field);
111-
}
112-
113106
$clone->setHeaders($headers);
114107

115108
return $clone;
@@ -119,7 +112,7 @@ public function withHeaders(array $headers): self
119112
* Replaces the given header in the returned instance.
120113
*
121114
* @param non-empty-string $name
122-
* @param string|array<string> $value
115+
* @param HeaderParamValueType $value
123116
*
124117
* @return self Cloned object.
125118
*/
@@ -135,7 +128,7 @@ public function withHeader(string $name, string|array $value): self
135128
* Adds the given header in the returned instance.
136129
*
137130
* @param non-empty-string $name
138-
* @param string|array<string> $value
131+
* @param HeaderParamValueType $value
139132
*
140133
* @return self Cloned object.
141134
*/
@@ -160,7 +153,7 @@ public function withoutHeader(string $name): self
160153
return $clone;
161154
}
162155

163-
protected function setHeader(string $name, $value): void
156+
protected function setHeader(string $name, array|string $value): void
164157
{
165158
if (($name[0] ?? ':') === ':') {
166159
throw new \Error("Header name cannot be empty or start with a colon (:)");
@@ -169,7 +162,7 @@ protected function setHeader(string $name, $value): void
169162
parent::setHeader($name, $value);
170163
}
171164

172-
protected function addHeader(string $name, $value): void
165+
protected function addHeader(string $name, array|string $value): void
173166
{
174167
if (($name[0] ?? ':') === ':') {
175168
throw new \Error("Header name cannot be empty or start with a colon (:)");
@@ -178,25 +171,80 @@ protected function addHeader(string $name, $value): void
178171
parent::addHeader($name, $value);
179172
}
180173

181-
private function makeUri(PsrUri|string $uri): PsrUri
174+
/**
175+
* @param QueryArrayType $parameters
176+
*
177+
* @return self Cloned object.
178+
*/
179+
public function withQueryParameters(array $parameters): self
180+
{
181+
$clone = clone $this;
182+
$clone->setQueryParameters($parameters);
183+
184+
return $clone;
185+
}
186+
187+
/**
188+
* @param QueryValueType $value
189+
*
190+
* @return self Cloned object.
191+
*/
192+
public function withQueryParameter(string $key, array|string|null $value): self
193+
{
194+
$clone = clone $this;
195+
$clone->setQueryParameter($key, $value);
196+
197+
return $clone;
198+
}
199+
200+
/**
201+
* @param QueryValueType $value
202+
*
203+
* @return self Cloned object.
204+
*/
205+
public function withAddedQueryParameter(string $key, array|string|null $value): self
206+
{
207+
$clone = clone $this;
208+
$clone->addQueryParameter($key, $value);
209+
210+
return $clone;
211+
}
212+
213+
/**
214+
* @return self Cloned object.
215+
*/
216+
public function withoutQueryParameter(string $key): self
217+
{
218+
$clone = clone $this;
219+
$clone->removeQueryParameter($key);
220+
221+
return $clone;
222+
}
223+
224+
/**
225+
* @return self Cloned object.
226+
*/
227+
public function withoutQuery(): self
228+
{
229+
$clone = clone $this;
230+
$clone->removeQuery();
231+
232+
return $clone;
233+
}
234+
235+
private static function makeUri(PsrUri|string $uri): PsrUri
182236
{
183237
if (\is_string($uri)) {
184238
try {
185239
$uri = Uri\Http::createFromString($uri);
186240
} catch (\Exception $exception) {
187-
throw new \Error('Invalid Websocket URI provided', 0, $exception);
241+
throw new \ValueError('Invalid Websocket URI provided', 0, $exception);
188242
}
189243
}
190244

191-
switch ($uri->getScheme()) {
192-
case 'ws':
193-
case 'wss':
194-
break;
195-
196-
default:
197-
throw new \Error('The URI scheme must be ws or wss: \'' . $uri->getScheme() . '\'');
198-
}
199-
200-
return $uri;
245+
return match ($uri->getScheme()) {
246+
'ws', 'wss' => $uri,
247+
default => throw new \ValueError('The URI scheme must be ws or wss, got "' . $uri->getScheme() . '"'),
248+
};
201249
}
202250
}

‎test/WebsocketConnectionTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ protected function createServer(WebsocketClientHandler $clientHandler): array
3535
{
3636
$logger = new NullLogger;
3737

38-
$httpServer = new SocketHttpServer($logger);
38+
$httpServer = SocketHttpServer::createForDirectAccess($logger);
3939
$httpServer->expose(new InternetAddress('127.0.0.1', 0));
4040
$httpServer->start(
4141
new Websocket($logger, new EmptyWebsocketHandshakeHandler(), $clientHandler),

0 commit comments

Comments
 (0)
Please sign in to comment.