Skip to content

Commit 7c50ecf

Browse files
committed
opz: (http) connection && response cookie
1 parent 2a4862d commit 7c50ecf

6 files changed

Lines changed: 204 additions & 209 deletions

File tree

src/Net/Http/Client.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,11 @@ class Client
6868
];
6969

7070
/**
71-
* @param array $config 客户端配置
71+
* @param array|null $config 客户端配置
7272
*/
73-
public function __construct(array $config = [])
73+
public function __construct(?array $config = [])
7474
{
7575
$this->config = array_merge($this->config, $config);
76-
if (!empty($config['base_uri'])) {
77-
$this->config['base_uri'] = rtrim($config['base_uri'], '/');
78-
}
7976
}
8077

8178
/**

src/Net/Http/Response.php

Lines changed: 83 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@
2727
use function is_string;
2828
use function strlen;
2929
use function strval;
30-
use function array_key_exists;
31-
use function is_int;
3230
use function is_file;
3331
use function strtolower;
3432
use function is_callable;
33+
use function gmdate;
34+
use function is_numeric;
35+
use function rawurlencode;
36+
use function str_replace;
37+
use function trim;
38+
use function ucfirst;
3539

3640
/**
3741
* response entity
@@ -228,7 +232,7 @@ public function cookie(string $name): mixed
228232

229233
/**
230234
* @param string $statusText
231-
* @return $this
235+
* @return static
232236
*/
233237
public function setStatusText(string $statusText): static
234238
{
@@ -238,7 +242,7 @@ public function setStatusText(string $statusText): static
238242

239243
/**
240244
* @param int $statusCode
241-
* @return $this
245+
* @return static
242246
*/
243247
public function setStatusCode(int $statusCode): static
244248
{
@@ -249,7 +253,7 @@ public function setStatusCode(int $statusCode): static
249253
/**
250254
* @param string $name
251255
* @param mixed $value
252-
* @return $this
256+
* @return static
253257
*/
254258
public function withHeader(string $name, mixed $value): static
255259
{
@@ -258,15 +262,83 @@ public function withHeader(string $name, mixed $value): static
258262
}
259263

260264
/**
265+
* @param string $name
266+
* @param string $content
267+
* @param array|null $options
268+
* @return static
261269
*/
262-
public function withCookie(string $name, array $values): static
270+
public function withCookie(string $name, string $content, ?array $options = []): static
263271
{
264-
$this->cookieLines[$name] = $this->buildCookieLine($name, $values);
272+
$options = $options ?? [];
273+
274+
$name = trim($name);
275+
if ($name === '') {
276+
return $this;
277+
}
278+
279+
$value = str_replace([';', "\r", "\n", "\0"], '', rawurlencode($content));
280+
281+
// 开始收集所有部分
282+
$parts = ["{$name}={$value}"];
283+
284+
// expires
285+
if (isset($options['expires']) && is_numeric($options['expires'])) {
286+
$exp = (int) $options['expires'];
287+
if ($exp > 0) {
288+
$expiresStr = gmdate('D, d M Y H:i:s \G\M\T', $exp);
289+
$parts[] = "Expires={$expiresStr}";
290+
}
291+
}
292+
293+
// maxAge
294+
if (isset($options['maxAge']) && is_numeric($options['maxAge'])) {
295+
$maxAge = (int) $options['maxAge'];
296+
$parts[] = "Max-Age={$maxAge}";
297+
if ($maxAge <= 0) {
298+
$parts[] = 'Expires=Thu, 01 Jan 1970 00:00:00 GMT';
299+
}
300+
}
301+
302+
// path - 默认 /
303+
$path = !empty($options['path']) ? trim($options['path']) : '/';
304+
$path = str_replace([';', "\r", "\n"], '', $path);
305+
$parts[] = "Path={$path}";
306+
307+
// domain
308+
if (!empty($options['domain'])) {
309+
$domain = trim($options['domain'], '. ');
310+
if ($domain !== '') {
311+
$domain = str_replace([';', "\r", "\n"], '', $domain);
312+
$parts[] = "Domain={$domain}";
313+
}
314+
}
315+
316+
// secure
317+
if (!empty($options['secure'])) {
318+
$parts[] = 'Secure';
319+
}
320+
321+
// httponly
322+
if (!empty($options['httponly']) || !empty($options['httpOnly'])) {
323+
$parts[] = 'HttpOnly';
324+
}
325+
326+
// samesite
327+
if (!empty($options['samesite'])) {
328+
$s = strtolower(trim($options['samesite']));
329+
if ($s === 'strict' || $s === 'lax' || $s === 'none') {
330+
$s = ucfirst($s);
331+
$parts[] = "SameSite={$s}";
332+
}
333+
}
334+
335+
$this->cookieLines[] = implode('; ', $parts);
265336
return $this;
266337
}
267338

268339
/**
269-
* @return $this
340+
* @param string $cookieLine
341+
* @return static
270342
*/
271343
public function withCookieLine(string $cookieLine): static
272344
{
@@ -301,7 +373,7 @@ public function withBody(mixed $content): static
301373

302374
/**
303375
* @param Stream $stream
304-
* @return $this
376+
* @return static
305377
*/
306378
public function withStream(Stream $stream): static
307379
{
@@ -311,7 +383,7 @@ public function withStream(Stream $stream): static
311383

312384
/**
313385
* @param string $name
314-
* @return $this
386+
* @return static
315387
*/
316388
public function removeHeader(string $name): static
317389
{
@@ -321,7 +393,7 @@ public function removeHeader(string $name): static
321393

322394
/**
323395
* 响应体发送完成后关闭连接
324-
* @return $this
396+
* @return static
325397
*/
326398
public function closeAfter(): static
327399
{
@@ -337,44 +409,4 @@ public function body(): mixed
337409
{
338410
return $this->body;
339411
}
340-
341-
/**
342-
* @param string $name
343-
* @param array $values
344-
* @return string
345-
*/
346-
private function buildCookieLine(string $name, array $values): string
347-
{
348-
$segments = [];
349-
350-
$mainValue = $values[$name] ?? $values['value'] ?? null;
351-
if (array_key_exists($name, $values)) {
352-
unset($values[$name]);
353-
}
354-
355-
if ($mainValue !== null) {
356-
$segments[] = $name . '=' . $mainValue;
357-
} else {
358-
$segments[] = $name;
359-
}
360-
361-
foreach ($values as $k => $v) {
362-
if (is_int($k)) {
363-
if ($v !== null && $v !== false && $v !== '') {
364-
$segments[] = strval($v);
365-
}
366-
continue;
367-
}
368-
369-
if ($v === null || $v === true) {
370-
$segments[] = $k;
371-
} elseif ($v === false) {
372-
continue;
373-
} else {
374-
$segments[] = $k . '=' . $v;
375-
}
376-
}
377-
378-
return implode('; ', $segments);
379-
}
380412
}

src/Net/Http/Server.php

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,16 @@ public function listen(): void
130130
$remoteInfo = parse_url("tcp://{$remoteAddr}");
131131

132132
$stream = new Stream($client);
133-
$connection = new Connection($stream, [
134-
'REMOTE_ADDR' => $remoteInfo['host'] ?? '',
135-
'REMOTE_PORT' => (int)($remoteInfo['port'] ?? 0),
136-
]);
137-
138-
$connection->start($this);
133+
$connection = new Connection(
134+
$stream,
135+
$this,
136+
[
137+
'REMOTE_ADDR' => $remoteInfo['host'] ?? '',
138+
'REMOTE_PORT' => (int)($remoteInfo['port'] ?? 0),
139+
]
140+
);
141+
142+
$connection->start();
139143
});
140144
}
141145

@@ -155,14 +159,6 @@ public function stop(): void
155159
}
156160
}
157161

158-
/**
159-
* @return HotCoroutinePool
160-
*/
161-
public function hotCoroutinePool(): HotCoroutinePool
162-
{
163-
return $this->hotCoroutinePool;
164-
}
165-
166162
/**
167163
* 获取热协程
168164
* @return Coroutine

0 commit comments

Comments
 (0)