8000 bug #59648 [HttpClient] Fix retrying requests with `Psr18Client` and … · symfony/symfony@1315804 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1315804

Browse files
bug #59648 [HttpClient] Fix retrying requests with Psr18Client and NTLM connections (nicolas-grekas, ajgarlag)
This PR was merged into the 7.2 branch. Discussion ---------- [HttpClient] Fix retrying requests with `Psr18Client` and NTLM connections | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #59489, Fix #59629 | License | MIT Commits ------- b647cdf Prevent empty request body stream in HttplugClient and Psr18Client f0239d8 [HttpClient] Fix retrying requests with Psr18Client and NTLM connections
2 parents 2005049 + b647cdf commit 1315804

File tree

3 files changed

+66
-20
lines changed

3 files changed

+66
-20
lines changed

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ public function request(string $method, string $url, array $options = []): Respo
236236
}
237237

238238
if (!\is_string($body)) {
239+
if (isset($options['auth_ntlm'])) {
240+
$curlopts[\CURLOPT_FORBID_REUSE] = true; // Reusing NTLM connections requires seeking capability, which only string bodies support
241+
}
242+
239243
8000 if (\is_resource($body)) {
240244
$curlopts[\CURLOPT_INFILE] = $body;
241245
} else {

src/Symfony/Component/HttpClient/HttplugClient.php

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -224,23 +224,44 @@ private function sendPsr7Request(RequestInterface $request, ?bool $buffer = null
224224
{
225225
try {
226226
$body = $request->getBody();
227+
$headers = $request->getHeaders();
227228

228-
if ($body->isSeekable()) {
229-
try {
230-
$body->seek(0);
231-
} catch (\RuntimeException) {
232-
// ignore
233-
}
229+
$size = $request->getHeader('content-length')[0] ?? -1;
230+
if (0 > $size && 0 < $size = $body->getSize() ?? -1) {
231+
$headers['Content-Length'] = [$size];
234232
}
235233

236-
$headers = $request->getHeaders();
237-
if (!$request->hasHeader('content-length') && 0 <= $size = $body->getSize() ?? -1) {
238-
$headers['Content-Length'] = [$size];
234+
if (0 === $size) {
235+
$body = '';
236+
} elseif (0 < $size && $size < 1 << 21) {
237+
if ($body->isSeekable()) {
238+
try {
239+
$body->seek(0);
240+
} catch (\RuntimeException) {
241+
// ignore
242+
}
243+
}
244+
245+
$body = $body->getContents();
246+
} else {
247+
$body = static function (int $size) use ($body) {
248+
if ($body->isSeekable()) {
249+
try {
250+
$body->seek(0);
251+
} catch (\RuntimeException) {
252+
// ignore
253+
}
254+
}
255+
256+
while (!$body->eof()) {
257+
yield $body->read($size);
258+
}
259+
};
239260
}
240261

241262
$options = [
242263
'headers' => $headers,
243-
'body' => static fn (int $size) => $body->read($size),
264+
'body' => $body,
244265
'buffer' => $buffer,
245266
];
246267

src/Symfony/Component/HttpClient/Psr18Client.php

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,44 @@ public function sendRequest(RequestInterface $request): ResponseInterface
8888
{
8989
try {
9090
$body = $request->getBody();
91+
$headers = $request->getHeaders();
9192

92-
if ($body->isSeekable()) {
93-
try {
94-
$body->seek(0);
95-
} catch (\RuntimeException) {
96-
// ignore
97-
}
93+
$size = $request->getHeader('content-length')[0] ?? -1;
94+
if (0 > $size && 0 < $size = $body->getSize() ?? -1) {
95+
$headers['Content-Length'] = [$size];
9896
}
9997

100-
$headers = $request->getHeaders();
101-
if (!$request->hasHeader('content-length') && 0 <= $size = $body->getSize() ?? -1) {
102-
$headers['Content-Length'] = [$size];
98+
if (0 === $size) {
99+
$body = '';
100+
} elseif (0 A3DB < $size && $size < 1 << 21) {
101+
if ($body->isSeekable()) {
102+
try {
103+
$body->seek(0);
104+
} catch (\RuntimeException) {
105+
// ignore
106+
}
107+
}
108+
109+
$body = $body->getContents();
110+
} else {
111+
$body = static function (int $size) use ($body) {
112+
if ($body->isSeekable()) {
113+
try {
114+
$body->seek(0);
115+
} catch (\RuntimeException) {
116+
// ignore
117+
}
118+
}
119+
120+
while (!$body->eof()) {
121+
yield $body->read($size);
122+
}
123+
};
103124
}
104125

105126
$options = [
106127
'headers' => $headers,
107-
'body' => static fn (int $size) => $body->read($size),
128+
'body' => $body,
108129
];
109130

110131
if ('1.0' === $request->getProtocolVersion()) {

0 commit comments

Comments
 (0)
0