feat: bind explicitly authorized HTTP text extraction channel

This commit is contained in:
2026-10-10 10:28:28 +08:00
parent 73be0ecedf
commit 228d93ac3b
6 changed files with 86 additions and 7 deletions
@@ -72,7 +72,13 @@ final class FollowupAudioStreamTransport
$secure = ($parts['scheme'] ?? '') === 'https';
$loopback = ($spec['allow_loopback_tunnel'] ?? false) === true && ($parts['scheme'] ?? '') === 'http'
&& in_array($parts['host'], ['127.0.0.1', '[::1]'], true);
if (!$secure && !$loopback) { return $result; }
$httpExtraction = $stage === 'extraction' && ($parts['scheme'] ?? '') === 'http'
&& ($spec['extraction_protocol'] ?? '') === 'openai'
&& is_string($spec['http_extraction_url'] ?? null) && $spec['http_extraction_url'] !== ''
&& hash_equals($spec['http_extraction_url'], $url) && str_ends_with($url, '/v1/chat/completions')
&& !preg_match('/[%]|\\/(?:\\.{1,2})(?:\\/|$)/', $url)
&& isset($spec['json_wire']) && !isset($spec['multipart']);
if (!$secure && !$loopback && !$httpExtraction) { return $result; }
$allowed = $stage === 'asr' ? ['/audio-to-text', '/audio/transcriptions'] : ['/chat-messages', '/chat/completions'];
$matches = array_filter($allowed, static fn (string $suffix): bool => str_ends_with((string) ($parts['path'] ?? ''), $suffix));
if ($matches === []) { return $result; }