Skip to content

Commit 5d252d9

Browse files
committed
use temp streams to store the body
1 parent 3674f19 commit 5d252d9

File tree

2 files changed

+42
-31
lines changed

2 files changed

+42
-31
lines changed

src/Http/CurlDispatcher.php

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class CurlDispatcher
1616
private RequestInterface $request;
1717
private $curl;
1818
private array $headers = [];
19-
private bool $multi = false;
19+
private $body;
2020
private ?int $error = null;
2121

2222
/**
@@ -28,7 +28,7 @@ public static function fetch(?ResponseFactoryInterface $responseFactory, Request
2828

2929
if (count($requests) === 1) {
3030
$connection = new static($requests[0]);
31-
return [$connection($responseFactory)];
31+
return [$connection->exec($responseFactory)];
3232
}
3333

3434
//Init connections
@@ -37,7 +37,6 @@ public static function fetch(?ResponseFactoryInterface $responseFactory, Request
3737

3838
foreach ($requests as $request) {
3939
$connection = new static($request);
40-
$connection->multi = true;
4140
curl_multi_add_handle($multi, $connection->curl);
4241

4342
$connections[] = $connection;
@@ -72,7 +71,7 @@ public static function fetch(?ResponseFactoryInterface $responseFactory, Request
7271
curl_multi_close($multi);
7372

7473
return array_map(
75-
fn ($connection) => $connection($responseFactory),
74+
fn ($connection) => $connection->exec($responseFactory),
7675
$connections
7776
);
7877
}
@@ -101,33 +100,14 @@ private function __construct(RequestInterface $request)
101100
CURLOPT_USERAGENT => $request->getHeaderLine('User-Agent'),
102101
CURLOPT_COOKIEJAR => $cookies,
103102
CURLOPT_COOKIEFILE => $cookies,
103+
CURLOPT_HEADERFUNCTION => [$this, 'writeHeader'],
104+
CURLOPT_WRITEFUNCTION => [$this, 'writeBody'],
104105
]);
105-
106-
curl_setopt(
107-
$this->curl,
108-
CURLOPT_HEADERFUNCTION,
109-
function ($resource, $string) {
110-
if (preg_match('/^([\w-]+):(.*)$/', $string, $matches)) {
111-
$name = strtolower($matches[1]);
112-
$value = trim($matches[2]);
113-
$this->headers[] = [$name, $value];
114-
} elseif ($this->headers) {
115-
$key = array_key_last($this->headers);
116-
$this->headers[$key][1] .= ' '.trim($string);
117-
}
118-
119-
return strlen($string);
120-
}
121-
);
122106
}
123107

124-
public function __invoke(ResponseFactoryInterface $responseFactory): ResponseInterface
108+
private function exec(ResponseFactoryInterface $responseFactory): ResponseInterface
125109
{
126-
if ($this->multi) {
127-
$body = curl_multi_getcontent($this->curl);
128-
} else {
129-
$body = curl_exec($this->curl);
130-
}
110+
curl_exec($this->curl);
131111

132112
$info = curl_getinfo($this->curl);
133113

@@ -148,11 +128,14 @@ public function __invoke(ResponseFactoryInterface $responseFactory): ResponseInt
148128
$response = $response->withAddedHeader($name, $value);
149129
}
150130

151-
if (!$response->hasHeader('Content-Location')) {
152-
$response = $response->withHeader('Content-Location', $info['url']);
153-
}
131+
$response = $response
132+
->withAddedHeader('Content-Location', $info['url'])
133+
->withAddedHeader('X-Request-Time', sprintf('%.3f ms', $info['total_time']));
154134

155-
$response->getBody()->write($body);
135+
if ($this->body) {
136+
//5Mb max
137+
$response->getBody()->write(stream_get_contents($this->body, 5000000, 0));
138+
}
156139

157140
return $response;
158141
}
@@ -177,4 +160,27 @@ private function getRequestHeaders(): array
177160

178161
return $headers;
179162
}
163+
164+
private function writeHeader($curl, $string): int
165+
{
166+
if (preg_match('/^([\w-]+):(.*)$/', $string, $matches)) {
167+
$name = strtolower($matches[1]);
168+
$value = trim($matches[2]);
169+
$this->headers[] = [$name, $value];
170+
} elseif ($this->headers) {
171+
$key = array_key_last($this->headers);
172+
$this->headers[$key][1] .= ' '.trim($string);
173+
}
174+
175+
return strlen($string);
176+
}
177+
178+
private function writeBody($curl, $string): int
179+
{
180+
if (!$this->body) {
181+
$this->body = fopen('php://temp', 'w+');
182+
}
183+
184+
return fwrite($this->body, $string);
185+
}
180186
}

tests/MultipleRequestsTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ public function testParallel()
1919

2020
$this->assertCount(3, $infos);
2121
$this->assertEquals('https://oscarotero.com/', $infos[0]->url);
22+
$this->assertEquals('Óscar Otero - Web designer and developer', $infos[0]->title);
23+
2224
$this->assertEquals('https://github.com/oscarotero', $infos[1]->url);
25+
$this->assertEquals('oscarotero - Overview', $infos[1]->title);
26+
2327
$this->assertEquals('https://twitter.com/misteroom', $infos[2]->url);
28+
$this->assertEquals('en', $infos[2]->language);
2429
}
2530
}

0 commit comments

Comments
 (0)