JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrFILE ON : __1054b1/index.php gilour
<?php namespace Sentry\Laravel\Features; use GuzzleHttp\Psr7\Uri; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Http\Client\Events\ConnectionFailed; use Illuminate\Http\Client\Events\RequestSending; use Illuminate\Http\Client\Events\ResponseReceived; use Illuminate\Http\Client\Factory; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\UriInterface; use Sentry\Breadcrumb; use Sentry\Laravel\Features\Concerns\TracksPushedScopesAndSpans; use Sentry\Laravel\Integration; use Sentry\SentrySdk; use Sentry\Tracing\SpanContext; use Sentry\Tracing\SpanStatus; use function Sentry\getBaggage; use function Sentry\getTraceparent; use function Sentry\getW3CTraceparent; class HttpClientIntegration extends Feature { use TracksPushedScopesAndSpans; private const FEATURE_KEY = 'http_client_requests'; public function isApplicable(): bool { return $this->isTracingFeatureEnabled(self::FEATURE_KEY) || $this->isBreadcrumbFeatureEnabled(self::FEATURE_KEY); } public function onBoot(Dispatcher $events, Factory $factory): void { if ($this->isTracingFeatureEnabled(self::FEATURE_KEY)) { $events->listen(RequestSending::class, [$this, 'handleRequestSendingHandlerForTracing']); $events->listen(ResponseReceived::class, [$this, 'handleResponseReceivedHandlerForTracing']); $events->listen(ConnectionFailed::class, [$this, 'handleConnectionFailedHandlerForTracing']); // The `globalRequestMiddleware` functionality was introduced in Laravel 10.14 if (method_exists($factory, 'globalRequestMiddleware')) { $factory->globalRequestMiddleware([$this, 'attachTracingHeadersToRequest']); } } if ($this->isBreadcrumbFeatureEnabled(self::FEATURE_KEY)) { $events->listen(ResponseReceived::class, [$this, 'handleResponseReceivedHandlerForBreadcrumb']); $events->listen(ConnectionFailed::class, [$this, 'handleConnectionFailedHandlerForBreadcrumb']); } } public function attachTracingHeadersToRequest(RequestInterface $request) { if ($this->shouldAttachTracingHeaders($request)) { return $request ->withHeader('baggage', getBaggage()) ->withHeader('sentry-trace', getTraceparent()) ->withHeader('traceparent', getW3CTraceparent()); } return $request; } public function handleRequestSendingHandlerForTracing(RequestSending $event): void { $parentSpan = SentrySdk::getCurrentHub()->getSpan(); // If there is no tracing span active there is no need to handle the event if ($parentSpan === null) { return; } $context = new SpanContext; $fullUri = $this->getFullUri($event->request->url()); $partialUri = $this->getPartialUri($fullUri); $context->setOp('http.client'); $context->setDescription($event->request->method() . ' ' . $partialUri); $context->setData([ 'url' => $partialUri, // See: https://develop.sentry.dev/sdk/performance/span-data-conventions/#http 'http.query' => $fullUri->getQuery(), 'http.fragment' => $fullUri->getFragment(), 'http.request.method' => $event->request->method(), 'http.request.body.size' => $event->request->toPsrRequest()->getBody()->getSize(), ]); $this->pushSpan($parentSpan->startChild($context)); } public function handleResponseReceivedHandlerForTracing(ResponseReceived $event): void { $span = $this->maybePopSpan(); if ($span !== null) { $span->setData(array_merge($span->getData(), [ // See: https://develop.sentry.dev/sdk/performance/span-data-conventions/#http 'http.response.status_code' => $event->response->status(), 'http.response.body.size' => $event->response->toPsrResponse()->getBody()->getSize(), ])); $span->setHttpStatus($event->response->status()); $span->finish(); } } public function handleConnectionFailedHandlerForTracing(ConnectionFailed $event): void { $span = $this->maybePopSpan(); if ($span !== null) { $span->setStatus(SpanStatus::internalError()); $span->finish(); } } public function handleResponseReceivedHandlerForBreadcrumb(ResponseReceived $event): void { $level = Breadcrumb::LEVEL_INFO; if ($event->response->failed()) { $level = Breadcrumb::LEVEL_ERROR; } $fullUri = $this->getFullUri($event->request->url()); Integration::addBreadcrumb(new Breadcrumb( $level, Breadcrumb::TYPE_HTTP, 'http', null, [ 'url' => $this->getPartialUri($fullUri), // See: https://develop.sentry.dev/sdk/performance/span-data-conventions/#http 'http.query' => $fullUri->getQuery(), 'http.fragment' => $fullUri->getFragment(), 'http.request.method' => $event->request->method(), 'http.response.status_code' => $event->response->status(), 'http.request.body.size' => $event->request->toPsrRequest()->getBody()->getSize(), 'http.response.body.size' => $event->response->toPsrResponse()->getBody()->getSize(), ] )); } public function handleConnectionFailedHandlerForBreadcrumb(ConnectionFailed $event): void { $fullUri = $this->getFullUri($event->request->url()); Integration::addBreadcrumb(new Breadcrumb( Breadcrumb::LEVEL_ERROR, Breadcrumb::TYPE_HTTP, 'http', null, [ 'url' => $this->getPartialUri($fullUri), // See: https://develop.sentry.dev/sdk/performance/span-data-conventions/#http 'http.query' => $fullUri->getQuery(), 'http.fragment' => $fullUri->getFragment(), 'http.request.method' => $event->request->method(), 'http.request.body.size' => $event->request->toPsrRequest()->getBody()->getSize(), ] )); } /** * Construct a full URI. * * @param string $url * * @return UriInterface */ private function getFullUri(string $url): UriInterface { return new Uri($url); } /** * Construct a partial URI, excluding the authority, query and fragment parts. * * @param UriInterface $uri * * @return string */ private function getPartialUri(UriInterface $uri): string { return (string)Uri::fromParts([ 'scheme' => $uri->getScheme(), 'host' => $uri->getHost(), 'port' => $uri->getPort(), 'path' => $uri->getPath(), ]); } private function shouldAttachTracingHeaders(RequestInterface $request): bool { $client = SentrySdk::getCurrentHub()->getClient(); if ($client === null) { return false; } $sdkOptions = $client->getOptions(); // Check if the request destination is allow listed in the trace_propagation_targets option. return $sdkOptions->getTracePropagationTargets() === null || in_array($request->getUri()->getHost(), $sdkOptions->getTracePropagationTargets()); } }