This commit is contained in:
Your Name
2026-08-27 16:26:14 +08:00
parent 4b8b4eb649
commit 43ad07208f
2 changed files with 43 additions and 5 deletions
+24 -5
View File
@@ -726,6 +726,21 @@ class DifyChatService
];
}
/**
* libcurl 7.32+ exposes CURLOPT_XFERINFOFUNCTION, while CentOS/RHEL 7 commonly
* ships libcurl 7.29 with only CURLOPT_PROGRESSFUNCTION. Resolve the option
* by name so loading this class never evaluates an undefined PHP constant.
*/
private static function curlProgressOption(): ?int
{
foreach (['CURLOPT_XFERINFOFUNCTION', 'CURLOPT_PROGRESSFUNCTION'] as $name) {
if (defined($name)) {
return (int) constant($name);
}
}
return null;
}
/**
* @param array<string,mixed> $payload
* @param callable(string):mixed $onDelta
@@ -783,7 +798,7 @@ class DifyChatService
self::consumeStreamBytes($protocol, $buffer, $chunk, $state, $onDelta);
return $state['callback_error'] ? 0 : strlen($chunk);
};
$progress = static function () use (&$state, $shouldAbort): int {
$progress = static function (...$unused) use (&$state, $shouldAbort): int {
if ($shouldAbort !== null && $shouldAbort()) {
$state['client_aborted'] = true;
return 1;
@@ -791,7 +806,7 @@ class DifyChatService
return 0;
};
curl_setopt_array($ch, [
$curlOptions = [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
@@ -807,9 +822,13 @@ class DifyChatService
],
CURLOPT_HEADERFUNCTION => $header,
CURLOPT_WRITEFUNCTION => $write,
CURLOPT_NOPROGRESS => false,
CURLOPT_XFERINFOFUNCTION => $progress,
]);
];
$progressOption = self::curlProgressOption();
if ($progressOption !== null) {
$curlOptions[CURLOPT_NOPROGRESS] = false;
$curlOptions[$progressOption] = $progress;
}
curl_setopt_array($ch, $curlOptions);
curl_exec($ch);
$errno = curl_errno($ch);
@@ -95,6 +95,25 @@ $explicitOpenAi = callDifyStreamPrivate('buildRequestSpecs', [
difyStreamExpect(count($explicitDify) === 1 && $explicitDify[0]['protocol'] === 'dify', 'explicit Dify endpoint never changes protocol');
difyStreamExpect(count($explicitOpenAi) === 1 && $explicitOpenAi[0]['protocol'] === 'openai', 'explicit OpenAI endpoint never changes protocol');
$progressOption = callDifyStreamPrivate('curlProgressOption', []);
$expectedProgressOption = null;
foreach (['CURLOPT_XFERINFOFUNCTION', 'CURLOPT_PROGRESSFUNCTION'] as $optionName) {
if (defined($optionName)) {
$expectedProgressOption = (int) constant($optionName);
break;
}
}
difyStreamExpect(
$progressOption === $expectedProgressOption,
'stream cancellation selects the newest cURL progress callback available at runtime'
);
$serviceSource = file_get_contents(dirname(__DIR__) . '/app/common/service/DifyChatService.php');
difyStreamExpect(
is_string($serviceSource)
&& str_contains($serviceSource, "'CURLOPT_XFERINFOFUNCTION', 'CURLOPT_PROGRESSFUNCTION'"),
'stream cancellation retains the libcurl 7.29 progress callback fallback'
);
$retryableStream = [
'errno' => 0,
'http_code' => 200,