From e9ae153474940b82fbaabeec058aa682ef043756 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:35:57 +0800 Subject: [PATCH 01/25] fix: improve handling of binary responses in GuzzleHttpClientAspect - Check Content-Type header to determine if response is textual before reading - Return 'Binary Response' placeholder for non-textual content - Avoid unnecessary stream operations on binary responses - Maintain backward compatibility for textual responses This prevents attempting to read or process binary content as text, which could cause memory issues or corrupted logs when dealing with file downloads, images, or other binary API responses. --- .../src/Aspect/GuzzleHttpClientAspect.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 127b85619..79485307a 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -94,11 +94,19 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) public function getResponsePayload(ResponseInterface $response) { $stream = $response->getBody(); - try { - if ($stream->isSeekable()) { - $stream->rewind(); - } + // Determine if the response is textual based on the Content-Type header. + $isTextual = \preg_match( + '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + $response->getHeaderLine('Content-Type') + ) === 1; + + // If the response is not textual or the stream is not seekable, we will return a placeholder. + if (! ($isTextual && $stream->isSeekable())) { + return 'Binary Response'; + } + + try { $content = $stream->getContents(); if (is_string($content)) { From 5bfa99e3abf931a7a20d830188d28a4af35e2384 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:49:41 +0800 Subject: [PATCH 02/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E5=93=8D=E5=BA=94=E6=9C=89?= =?UTF-8?q?=E6=95=88=E8=B4=9F=E8=BD=BD=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 79485307a..3951353e1 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -60,7 +60,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) // Add or override the on_stats option to record the request duration. $onStats = $options['on_stats'] ?? null; - $proceedingJoinPoint->arguments['keys']['options']['on_stats'] = function (TransferStats $stats) use ($onStats) { + $proceedingJoinPoint->arguments['keys']['options']['on_stats'] = function (TransferStats $stats) use ($onStats, $options) { try { $request = $stats->getRequest(); $response = $stats->getResponse(); @@ -75,7 +75,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) $content['response_status'] = $response->getStatusCode(); $content['response_headers'] = $response->getHeaders(); $content['response_reason'] = $response->getReasonPhrase(); - $content['response_payload'] = $this->getResponsePayload($response); + $content['response_payload'] = $this->getResponsePayload($response, $options); } Telescope::recordClientRequest(IncomingEntry::make($content)); @@ -91,8 +91,12 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) return $proceedingJoinPoint->process(); } - public function getResponsePayload(ResponseInterface $response) + public function getResponsePayload(ResponseInterface $response, array $options = []): mixed { + if (! empty($options['stream'])) { + return 'Streamed Response'; + } + $stream = $response->getBody(); // Determine if the response is textual based on the Content-Type header. From 8c7588b3bd94f43a509e337a89b8fc5a894d9da6 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:50:08 +0800 Subject: [PATCH 03/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E6=B5=81=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 3951353e1..8fbe8a761 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -93,7 +93,7 @@ public function process(ProceedingJoinPoint $proceedingJoinPoint) public function getResponsePayload(ResponseInterface $response, array $options = []): mixed { - if (! empty($options['stream'])) { + if (isset($options['stream']) && $options['stream'] === true) { return 'Streamed Response'; } From b187ab51dd280dc332f1d1f9a659c3b2bf553f87 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:54:44 +0800 Subject: [PATCH 04/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E6=B5=81=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 39035f6da..1547e7141 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -122,7 +122,11 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req ) === 1; $body = $response->getBody(); - if ($isTextual && $body->isSeekable()) { + if (isset($options['stream']) && $options['stream'] === true) { + $span->setData([ + 'http.response.body.contents' => '[streamed response]', + ]); + } elseif ($isTextual && $body->isSeekable()) { $pos = $body->tell(); $span->setData([ 'http.response.body.contents' => \GuzzleHttp\Psr7\Utils::copyToString($body, 8192), // 8KB 上限 From a07dd7d9062badf0c98e39d14df38528ff9516da Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:04:04 +0800 Subject: [PATCH 05/25] =?UTF-8?q?fix:=20=E6=94=B9=E8=BF=9B=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E4=BA=8C=E8=BF=9B=E5=88=B6?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tracing/Aspect/GuzzleHttpClientAspect.php | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 1547e7141..906dce008 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -22,6 +22,7 @@ use Sentry\State\Scope; use Sentry\Tracing\SpanContext; use Sentry\Tracing\SpanStatus; +use Throwable; use function FriendsOfHyperf\Sentry\trace; @@ -116,27 +117,9 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req ]); if ($this->feature->isTracingTagEnabled('http.response.body.contents')) { - $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', - $response->getHeaderLine('Content-Type') - ) === 1; - $body = $response->getBody(); - - if (isset($options['stream']) && $options['stream'] === true) { - $span->setData([ - 'http.response.body.contents' => '[streamed response]', - ]); - } elseif ($isTextual && $body->isSeekable()) { - $pos = $body->tell(); - $span->setData([ - 'http.response.body.contents' => \GuzzleHttp\Psr7\Utils::copyToString($body, 8192), // 8KB 上限 - ]); - $body->seek($pos); - } else { - $span->setData([ - 'http.response.body.contents' => '[binary omitted]', - ]); - } + $span->setData([ + 'http.response.body.contents' => $this->getResponsePayload($response, $options), + ]); } $span->setHttpStatus($response->getStatusCode()); @@ -160,4 +143,41 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req ->setOrigin('auto.http.client') ); } + + protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $response, array $options = []): mixed + { + if (isset($options['stream']) && $options['stream'] === true) { + return '[Streamed Response]'; + } + + $stream = $response->getBody(); + + // Determine if the response is textual based on the Content-Type header. + $isTextual = \preg_match( + '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + $response->getHeaderLine('Content-Type') + ) === 1; + + // If the response is not textual or the stream is not seekable, we will return a placeholder. + if (! ($isTextual && $stream->isSeekable())) { + return '[Binary Omitted]'; + } + + try { + $content = $stream->getContents(); + + if (is_string($content)) { + return $content; + } + + return '[Non-String Response]'; + } catch (Throwable $e) { + return '[Error Retrieving Response Content]'; + } finally { + // Rewind the stream to its original position. + if ($stream->isSeekable()) { + $stream->rewind(); + } + } + } } From 2f539be4e88209c915f3b209bbfc49d14d9ac212 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:12:16 +0800 Subject: [PATCH 06/25] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E6=B5=81=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 7 ++----- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 4 +--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 906dce008..c85f6f8c2 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -166,7 +166,7 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp try { $content = $stream->getContents(); - if (is_string($content)) { + if (! empty($content)) { return $content; } @@ -174,10 +174,7 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp } catch (Throwable $e) { return '[Error Retrieving Response Content]'; } finally { - // Rewind the stream to its original position. - if ($stream->isSeekable()) { - $stream->rewind(); - } + $stream->rewind(); } } } diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 8fbe8a761..36ac2498b 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -139,9 +139,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = } catch (Throwable $e) { return 'Purged By Hyperf Telescope: ' . $e->getMessage(); } finally { - if ($stream->isSeekable()) { - $stream->rewind(); - } + $stream->rewind(); } return 'HTML Response'; From 9714791bf7fef7bde5a27af82e84b0db711ad9cb Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:14:59 +0800 Subject: [PATCH 07/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E4=BA=8C=E8=BF=9B=E5=88=B6?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 8 ++++---- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index c85f6f8c2..0a9b2c31b 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -150,8 +150,6 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp return '[Streamed Response]'; } - $stream = $response->getBody(); - // Determine if the response is textual based on the Content-Type header. $isTextual = \preg_match( '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', @@ -159,10 +157,12 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp ) === 1; // If the response is not textual or the stream is not seekable, we will return a placeholder. - if (! ($isTextual && $stream->isSeekable())) { + if (! $isTextual) { return '[Binary Omitted]'; } + $stream = $response->getBody(); + try { $content = $stream->getContents(); @@ -174,7 +174,7 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp } catch (Throwable $e) { return '[Error Retrieving Response Content]'; } finally { - $stream->rewind(); + $stream->isSeekable() && $stream->rewind(); } } } diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 36ac2498b..356bb16f6 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -97,8 +97,6 @@ public function getResponsePayload(ResponseInterface $response, array $options = return 'Streamed Response'; } - $stream = $response->getBody(); - // Determine if the response is textual based on the Content-Type header. $isTextual = \preg_match( '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', @@ -106,10 +104,12 @@ public function getResponsePayload(ResponseInterface $response, array $options = ) === 1; // If the response is not textual or the stream is not seekable, we will return a placeholder. - if (! ($isTextual && $stream->isSeekable())) { + if (! $isTextual) { return 'Binary Response'; } + $stream = $response->getBody(); + try { $content = $stream->getContents(); @@ -139,7 +139,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = } catch (Throwable $e) { return 'Purged By Hyperf Telescope: ' . $e->getMessage(); } finally { - $stream->rewind(); + $stream->isSeekable() && $stream->rewind(); } return 'HTML Response'; From 8f9479bff12e844f2d7747958ce0ab2a4500b932 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:19:12 +0800 Subject: [PATCH 08/25] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E7=A9=BA=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E5=93=8D=E5=BA=94=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 0a9b2c31b..72d62fe88 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -170,7 +170,7 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp return $content; } - return '[Non-String Response]'; + return '[Empty-String Response]'; } catch (Throwable $e) { return '[Error Retrieving Response Content]'; } finally { From 91bb46a4b9ac48de73035d29ea32944d59903f18 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:20:46 +0800 Subject: [PATCH 09/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=E5=8F=AF=E5=9B=9E=E6=BA=AF?= =?UTF-8?q?=E6=B5=81=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 4 ++++ src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 72d62fe88..b6cfc8bac 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -164,6 +164,10 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp $stream = $response->getBody(); try { + if ($stream->isSeekable()) { + $stream->rewind(); + } + $content = $stream->getContents(); if (! empty($content)) { diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 356bb16f6..c6381ad4e 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -111,6 +111,10 @@ public function getResponsePayload(ResponseInterface $response, array $options = $stream = $response->getBody(); try { + if ($stream->isSeekable()) { + $stream->rewind(); + } + $content = $stream->getContents(); if (is_string($content)) { From 84dfa49b7b74c31a07691d26de0a6f7bfc7695dd Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:23:45 +0800 Subject: [PATCH 10/25] Add grpc to textual Content-Type detection Updated the regex in GuzzleHttpClientAspect to include 'application/grpc' as a textual Content-Type. This ensures that gRPC responses are correctly identified as textual for further processing. --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 2 +- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index b6cfc8bac..ae836cdfb 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -152,7 +152,7 @@ protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $resp // Determine if the response is textual based on the Content-Type header. $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', $response->getHeaderLine('Content-Type') ) === 1; diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index c6381ad4e..e207d86d6 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -99,7 +99,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = // Determine if the response is textual based on the Content-Type header. $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', $response->getHeaderLine('Content-Type') ) === 1; From c85d065376e3d15cd592e3d3257abecbdd5f1350 Mon Sep 17 00:00:00 2001 From: Deeka Wong Date: Fri, 12 Dec 2025 11:24:12 +0800 Subject: [PATCH 11/25] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/Aspect/GuzzleHttpClientAspect.php | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index e207d86d6..44c1ba35b 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -98,14 +98,22 @@ public function getResponsePayload(ResponseInterface $response, array $options = } // Determine if the response is textual based on the Content-Type header. - $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', - $response->getHeaderLine('Content-Type') - ) === 1; + $contentType = $response->getHeaderLine('Content-Type'); + if ($contentType === '' || $contentType === null) { + // If Content-Type is missing or empty, default to textual. + $isTextual = true; + } else { + $isTextual = \preg_match( + '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + $contentType + ) === 1; + } // If the response is not textual or the stream is not seekable, we will return a placeholder. - if (! $isTextual) { - return 'Binary Response'; + if (! ($isTextual && $stream->isSeekable())) { + return $contentType === '' || $contentType === null + ? 'No Content-Type Header (treated as text)' + : 'Binary Response'; } $stream = $response->getBody(); From 5449c776f0c7fb8860fac23ee188334c89bbdeca Mon Sep 17 00:00:00 2001 From: Deeka Wong Date: Fri, 12 Dec 2025 11:24:41 +0800 Subject: [PATCH 12/25] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 44c1ba35b..cfa712334 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -109,8 +109,8 @@ public function getResponsePayload(ResponseInterface $response, array $options = ) === 1; } - // If the response is not textual or the stream is not seekable, we will return a placeholder. - if (! ($isTextual && $stream->isSeekable())) { + // If the response is not textual, we will return a placeholder. + if (! $isTextual) { return $contentType === '' || $contentType === null ? 'No Content-Type Header (treated as text)' : 'Binary Response'; From 528477f513a6d8a0598a4518b9e401d03c93cb3b Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:26:29 +0800 Subject: [PATCH 13/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E5=AF=B9=20Content-Type=20=E5=A4=B4?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index cfa712334..3b0a253d9 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -99,7 +99,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = // Determine if the response is textual based on the Content-Type header. $contentType = $response->getHeaderLine('Content-Type'); - if ($contentType === '' || $contentType === null) { + if ($contentType === '') { // If Content-Type is missing or empty, default to textual. $isTextual = true; } else { @@ -111,7 +111,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = // If the response is not textual, we will return a placeholder. if (! $isTextual) { - return $contentType === '' || $contentType === null + return $contentType === '' ? 'No Content-Type Header (treated as text)' : 'Binary Response'; } From 7f918c9414380f44fa6ba322ccb3620750d4af3f Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:29:50 +0800 Subject: [PATCH 14/25] =?UTF-8?q?fix:=20=E5=A4=84=E7=90=86=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E7=A9=BA=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index ae836cdfb..a6f0a9301 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -146,6 +146,10 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $response, array $options = []): mixed { + if ($response === null) { + return '[No Response]'; + } + if (isset($options['stream']) && $options['stream'] === true) { return '[Streamed Response]'; } From 02d2b4e7bcdf66e460879c2bfb45fbd83f309af9 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:30:20 +0800 Subject: [PATCH 15/25] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index a6f0a9301..28133810e 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -19,6 +19,7 @@ use Hyperf\Di\Aop\ProceedingJoinPoint; use Psr\Container\ContainerInterface; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; use Sentry\State\Scope; use Sentry\Tracing\SpanContext; use Sentry\Tracing\SpanStatus; @@ -144,7 +145,7 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req ); } - protected function getResponsePayload(?\Psr\Http\Message\ResponseInterface $response, array $options = []): mixed + protected function getResponsePayload(?ResponseInterface $response, array $options = []): mixed { if ($response === null) { return '[No Response]'; From 58d28de2239a2f4879911e0973d2eea515031122 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:38:48 +0800 Subject: [PATCH 16/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE=E4=BF=9D=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E6=8E=A5=E5=8F=97=E7=A9=BA=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 28133810e..d2cda66e1 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -145,12 +145,8 @@ function (Scope $scope) use ($proceedingJoinPoint, $options, $guzzleConfig, $req ); } - protected function getResponsePayload(?ResponseInterface $response, array $options = []): mixed + protected function getResponsePayload(ResponseInterface $response, array $options = []): mixed { - if ($response === null) { - return '[No Response]'; - } - if (isset($options['stream']) && $options['stream'] === true) { return '[Streamed Response]'; } From 7b4ecd92e05f4b83eaa1c82d0acadc6c3eaf3b4c Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:56:56 +0800 Subject: [PATCH 17/25] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E6=A3=80=E6=9F=A5=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E6=AD=A3=E7=A1=AE=E5=A4=84=E7=90=86=E7=A9=BA=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index d2cda66e1..e1fd4b162 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -152,9 +152,10 @@ protected function getResponsePayload(ResponseInterface $response, array $option } // Determine if the response is textual based on the Content-Type header. - $isTextual = \preg_match( + $contentType = $response->getHeaderLine('Content-Type'); + $isTextual = $contentType === '' || \preg_match( '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', - $response->getHeaderLine('Content-Type') + $contentType ) === 1; // If the response is not textual or the stream is not seekable, we will return a placeholder. @@ -171,7 +172,7 @@ protected function getResponsePayload(ResponseInterface $response, array $option $content = $stream->getContents(); - if (! empty($content)) { + if ($content !== '') { return $content; } From 4dbb73fe61fee6104843a2aea8b2c263970f9a7a Mon Sep 17 00:00:00 2001 From: Deeka Wong Date: Fri, 12 Dec 2025 11:57:42 +0800 Subject: [PATCH 18/25] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 3b0a253d9..cb737d921 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -111,9 +111,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = // If the response is not textual, we will return a placeholder. if (! $isTextual) { - return $contentType === '' - ? 'No Content-Type Header (treated as text)' - : 'Binary Response'; + return 'Binary Response'; } $stream = $response->getBody(); From dbf7222c63c3fb8694623f6ba829fe4f72be27f9 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 12:02:39 +0800 Subject: [PATCH 19/25] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=A4=84=E7=90=86=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E5=86=85=E5=AE=B9=E6=88=AA=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tracing/Aspect/GuzzleHttpClientAspect.php | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index e1fd4b162..6dfa946e5 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -33,6 +33,8 @@ */ class GuzzleHttpClientAspect extends AbstractAspect { + private const MAX_RESPONSE_BODY_SIZE = 8192; // 8KB,和 Telescope 对齐 + public array $classes = [ Client::class . '::transfer', ]; @@ -166,17 +168,27 @@ protected function getResponsePayload(ResponseInterface $response, array $option $stream = $response->getBody(); try { + $pos = null; if ($stream->isSeekable()) { + $pos = $stream->tell(); $stream->rewind(); } - $content = $stream->getContents(); + $content = \GuzzleHttp\Psr7\Utils::copyToString( + $stream, + self::MAX_RESPONSE_BODY_SIZE + 1 // 多读 1 byte 用来判断是否截断 + ); + + if ($pos !== null) { + $stream->seek($pos); + } - if ($content !== '') { - return $content; + if (strlen($content) > self::MAX_RESPONSE_BODY_SIZE) { + return substr($content, 0, self::MAX_RESPONSE_BODY_SIZE) + . '… [truncated]'; } - return '[Empty-String Response]'; + return $content === '' ? '[Empty-String Response]' : $content; } catch (Throwable $e) { return '[Error Retrieving Response Content]'; } finally { From 31b5b748d412a132223f50441f6ae2c53472a4b5 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 12:04:10 +0800 Subject: [PATCH 20/25] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E6=88=AA=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E5=96=84=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 6dfa946e5..8b3876f81 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -184,8 +184,11 @@ protected function getResponsePayload(ResponseInterface $response, array $option } if (strlen($content) > self::MAX_RESPONSE_BODY_SIZE) { - return substr($content, 0, self::MAX_RESPONSE_BODY_SIZE) - . '… [truncated]'; + return substr( + $content, + 0, + self::MAX_RESPONSE_BODY_SIZE + ) . '… [truncated]'; } return $content === '' ? '[Empty-String Response]' : $content; From 94936334075475ed0d1737c70cec50ef6b324f39 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 12:20:20 +0800 Subject: [PATCH 21/25] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=B8=B8=E9=87=8F=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E6=A0=BC=E5=BC=8F=EF=BC=8C=E6=94=B9=E5=96=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=B8=80=E8=87=B4=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 8b3876f81..1355106e8 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -33,7 +33,7 @@ */ class GuzzleHttpClientAspect extends AbstractAspect { - private const MAX_RESPONSE_BODY_SIZE = 8192; // 8KB,和 Telescope 对齐 + private const MAX_RESPONSE_BODY_SIZE = 8192; // 8 KB public array $classes = [ Client::class . '::transfer', From abf899f446ee6cba0c3ad417985b81e8739bc10f Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:17:40 +0800 Subject: [PATCH 22/25] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E5=9C=A8=E5=BC=82=E5=B8=B8=E6=83=85=E5=86=B5=E4=B8=8B?= =?UTF-8?q?=E4=B8=8D=E5=BD=B1=E5=93=8D=E8=AF=B7=E6=B1=82=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Tracing/Aspect/GuzzleHttpClientAspect.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php index 1355106e8..53d1a9f3d 100644 --- a/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php +++ b/src/sentry/src/Tracing/Aspect/GuzzleHttpClientAspect.php @@ -166,9 +166,9 @@ protected function getResponsePayload(ResponseInterface $response, array $option } $stream = $response->getBody(); + $pos = null; try { - $pos = null; if ($stream->isSeekable()) { $pos = $stream->tell(); $stream->rewind(); @@ -179,10 +179,6 @@ protected function getResponsePayload(ResponseInterface $response, array $option self::MAX_RESPONSE_BODY_SIZE + 1 // 多读 1 byte 用来判断是否截断 ); - if ($pos !== null) { - $stream->seek($pos); - } - if (strlen($content) > self::MAX_RESPONSE_BODY_SIZE) { return substr( $content, @@ -195,7 +191,13 @@ protected function getResponsePayload(ResponseInterface $response, array $option } catch (Throwable $e) { return '[Error Retrieving Response Content]'; } finally { - $stream->isSeekable() && $stream->rewind(); + if ($pos !== null) { + try { + $stream->seek($pos); + } catch (Throwable) { + // ignore: tracing must not break the request flow + } + } } } } From 62c36f94300e7b0af49b5cc01ecfd314d98bc317 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:19:33 +0800 Subject: [PATCH 23/25] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=86=85=E5=AE=B9=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=8C=B9=E9=85=8D=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20gRPC=20=E5=93=8D=E5=BA=94=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index cb737d921..f6f997360 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -104,7 +104,7 @@ public function getResponsePayload(ResponseInterface $response, array $options = $isTextual = true; } else { $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded))/i', + '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', $contentType ) === 1; } From a3749ee404cfe214b85b955d4794868c92560b09 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:20:11 +0800 Subject: [PATCH 24/25] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E7=B1=BB=E5=9E=8B=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/telescope/src/Aspect/GuzzleHttpClientAspect.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index f6f997360..832b6bbbc 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -99,15 +99,10 @@ public function getResponsePayload(ResponseInterface $response, array $options = // Determine if the response is textual based on the Content-Type header. $contentType = $response->getHeaderLine('Content-Type'); - if ($contentType === '') { - // If Content-Type is missing or empty, default to textual. - $isTextual = true; - } else { - $isTextual = \preg_match( - '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', - $contentType - ) === 1; - } + $isTextual = $contentType === '' || \preg_match( + '/^(text\/|application\/(json|xml|x-www-form-urlencoded|grpc))/i', + $contentType + ) === 1; // If the response is not textual, we will return a placeholder. if (! $isTextual) { From 01a9c1d2edd49b7b0848b575131631e890b407ea Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:27:12 +0800 Subject: [PATCH 25/25] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20GuzzleHttpCli?= =?UTF-8?q?entAspect=20=E4=B8=AD=E7=9A=84=E5=93=8D=E5=BA=94=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20gRPC=20=E5=92=8C=E7=BA=AF=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Aspect/GuzzleHttpClientAspect.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php index 832b6bbbc..7476e5aac 100644 --- a/src/telescope/src/Aspect/GuzzleHttpClientAspect.php +++ b/src/telescope/src/Aspect/GuzzleHttpClientAspect.php @@ -119,23 +119,25 @@ public function getResponsePayload(ResponseInterface $response, array $options = $content = $stream->getContents(); if (is_string($content)) { + // Check if the content is within the size limits. if (! $this->contentWithinLimits($content)) { return 'Purged By Hyperf Telescope'; } + // Try to decode JSON responses and hide sensitive parameters. if ( is_array(json_decode($content, true)) && json_last_error() === JSON_ERROR_NONE ) { - return $this->contentWithinLimits($content) /* @phpstan-ignore-line */ - ? $this->hideParameters(json_decode($content, true), Telescope::$hiddenResponseParameters) - : 'Purged By Hyperf Telescope'; - } - if (Str::startsWith(strtolower($response->getHeaderLine('content-type') ?: ''), 'text/plain')) { - return $this->contentWithinLimits($content) ? $content : 'Purged By Hyperf Telescope'; /* @phpstan-ignore-line */ + return $this->hideParameters(json_decode($content, true), Telescope::$hiddenResponseParameters); } + // Return gRPC responses and plain text responses as is. if (Str::contains($response->getHeaderLine('content-type'), 'application/grpc') !== false) { return TelescopeContext::getGrpcResponsePayload() ?: 'Purged By Hyperf Telescope'; } + // Return plain text responses as is. + if (Str::startsWith(strtolower($response->getHeaderLine('content-type') ?: ''), 'text/plain')) { + return $content; + } } if (empty($content)) {