summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/context/Propagation
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/context/Propagation')
-rw-r--r--vendor/open-telemetry/context/Propagation/ArrayAccessGetterSetter.php129
-rw-r--r--vendor/open-telemetry/context/Propagation/MultiTextMapPropagator.php83
-rw-r--r--vendor/open-telemetry/context/Propagation/NoopTextMapPropagator.php36
-rw-r--r--vendor/open-telemetry/context/Propagation/PropagationGetterInterface.php25
-rw-r--r--vendor/open-telemetry/context/Propagation/PropagationSetterInterface.php16
-rw-r--r--vendor/open-telemetry/context/Propagation/SanitizeCombinedHeadersPropagationGetter.php46
-rw-r--r--vendor/open-telemetry/context/Propagation/TextMapPropagatorInterface.php40
7 files changed, 375 insertions, 0 deletions
diff --git a/vendor/open-telemetry/context/Propagation/ArrayAccessGetterSetter.php b/vendor/open-telemetry/context/Propagation/ArrayAccessGetterSetter.php
new file mode 100644
index 000000000..51263044d
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/ArrayAccessGetterSetter.php
@@ -0,0 +1,129 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+use function array_key_first;
+use ArrayAccess;
+use function get_class;
+use function gettype;
+use InvalidArgumentException;
+use function is_array;
+use function is_object;
+use function is_string;
+use function sprintf;
+use function strcasecmp;
+use Traversable;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#textmap-propagator Getter and Setter.
+ *
+ * Default implementation of {@see PropagationGetterInterface} and {@see PropagationSetterInterface}.
+ * This type is used if no custom getter/setter is provided to {@see TextMapPropagatorInterface::inject()} or {@see TextMapPropagatorInterface::extract()}.
+ */
+final class ArrayAccessGetterSetter implements PropagationGetterInterface, PropagationSetterInterface
+{
+ private static ?self $instance = null;
+
+ /**
+ * Returns a singleton instance of `self` to avoid, multiple runtime allocations.
+ */
+ public static function getInstance(): self
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /** {@inheritdoc} */
+ public function keys($carrier): array
+ {
+ if ($this->isSupportedCarrier($carrier)) {
+ $keys = [];
+ foreach ($carrier as $key => $_) {
+ $keys[] = (string) $key;
+ }
+
+ return $keys;
+ }
+
+ throw new InvalidArgumentException(
+ sprintf(
+ 'Unsupported carrier type: %s.',
+ is_object($carrier) ? get_class($carrier) : gettype($carrier),
+ )
+ );
+ }
+
+ /** {@inheritdoc} */
+ public function get($carrier, string $key): ?string
+ {
+ if ($this->isSupportedCarrier($carrier)) {
+ $value = $carrier[$this->resolveKey($carrier, $key)] ?? null;
+ if (is_array($value) && $value) {
+ $value = $value[array_key_first($value)];
+ }
+
+ return is_string($value)
+ ? $value
+ : null;
+ }
+
+ throw new InvalidArgumentException(
+ sprintf(
+ 'Unsupported carrier type: %s. Unable to get value associated with key:%s',
+ is_object($carrier) ? get_class($carrier) : gettype($carrier),
+ $key
+ )
+ );
+ }
+
+ /** {@inheritdoc} */
+ public function set(&$carrier, string $key, string $value): void
+ {
+ if ($key === '') {
+ throw new InvalidArgumentException('Unable to set value with an empty key');
+ }
+ if ($this->isSupportedCarrier($carrier)) {
+ if (($r = $this->resolveKey($carrier, $key)) !== $key) {
+ unset($carrier[$r]);
+ }
+
+ $carrier[$key] = $value;
+
+ return;
+ }
+
+ throw new InvalidArgumentException(
+ sprintf(
+ 'Unsupported carrier type: %s. Unable to set value associated with key:%s',
+ is_object($carrier) ? get_class($carrier) : gettype($carrier),
+ $key
+ )
+ );
+ }
+
+ private function isSupportedCarrier($carrier): bool
+ {
+ return is_array($carrier) || $carrier instanceof ArrayAccess && $carrier instanceof Traversable;
+ }
+
+ private function resolveKey($carrier, string $key): string
+ {
+ if (isset($carrier[$key])) {
+ return $key;
+ }
+
+ foreach ($carrier as $k => $_) {
+ $k = (string) $k;
+ if (strcasecmp($k, $key) === 0) {
+ return $k;
+ }
+ }
+
+ return $key;
+ }
+}
diff --git a/vendor/open-telemetry/context/Propagation/MultiTextMapPropagator.php b/vendor/open-telemetry/context/Propagation/MultiTextMapPropagator.php
new file mode 100644
index 000000000..075fe98fe
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/MultiTextMapPropagator.php
@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+use function array_map;
+use function array_merge;
+use function array_unique;
+use function array_values;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+
+final class MultiTextMapPropagator implements TextMapPropagatorInterface
+{
+ /**
+ * @readonly
+ *
+ * @var list<TextMapPropagatorInterface>
+ */
+ private array $propagators = [];
+
+ /**
+ * @readonly
+ *
+ * @var list<string>
+ */
+ private array $fields;
+
+ /**
+ * @no-named-arguments
+ *
+ * @param list<TextMapPropagatorInterface> $propagators
+ */
+ public function __construct(array $propagators)
+ {
+ $this->propagators = $propagators;
+ $this->fields = $this->extractFields($propagators);
+ }
+
+ public function fields(): array
+ {
+ return $this->fields;
+ }
+
+ public function inject(&$carrier, PropagationSetterInterface $setter = null, ContextInterface $context = null): void
+ {
+ foreach ($this->propagators as $propagator) {
+ $propagator->inject($carrier, $setter, $context);
+ }
+ }
+
+ public function extract($carrier, PropagationGetterInterface $getter = null, ContextInterface $context = null): ContextInterface
+ {
+ $context ??= Context::getCurrent();
+
+ foreach ($this->propagators as $propagator) {
+ $context = $propagator->extract($carrier, $getter, $context);
+ }
+
+ return $context;
+ }
+
+ /**
+ * @param list<TextMapPropagatorInterface> $propagators
+ * @return list<string>
+ */
+ private function extractFields(array $propagators): array
+ {
+ return array_values(
+ array_unique(
+ // Phan seems to struggle here with the variadic argument
+ // @phan-suppress-next-line PhanParamTooFewInternalUnpack
+ array_merge(
+ ...array_map(
+ static fn (TextMapPropagatorInterface $propagator) => $propagator->fields(),
+ $propagators
+ )
+ )
+ )
+ );
+ }
+}
diff --git a/vendor/open-telemetry/context/Propagation/NoopTextMapPropagator.php b/vendor/open-telemetry/context/Propagation/NoopTextMapPropagator.php
new file mode 100644
index 000000000..c408cfc79
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/NoopTextMapPropagator.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+
+final class NoopTextMapPropagator implements TextMapPropagatorInterface
+{
+ private static ?self $instance = null;
+
+ public static function getInstance(): self
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ public function fields(): array
+ {
+ return [];
+ }
+
+ public function extract($carrier, PropagationGetterInterface $getter = null, ContextInterface $context = null): ContextInterface
+ {
+ return $context ?? Context::getCurrent();
+ }
+
+ public function inject(&$carrier, PropagationSetterInterface $setter = null, ContextInterface $context = null): void
+ {
+ }
+}
diff --git a/vendor/open-telemetry/context/Propagation/PropagationGetterInterface.php b/vendor/open-telemetry/context/Propagation/PropagationGetterInterface.php
new file mode 100644
index 000000000..d2976c63d
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/PropagationGetterInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#getter-argument
+ */
+interface PropagationGetterInterface
+{
+ /**
+ * Returns the list of all the keys in the carrier.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#keys
+ *
+ * @return list<string>
+ */
+ public function keys($carrier): array;
+
+ /**
+ * Gets the value of a given key from a carrier.
+ */
+ public function get($carrier, string $key) : ?string;
+}
diff --git a/vendor/open-telemetry/context/Propagation/PropagationSetterInterface.php b/vendor/open-telemetry/context/Propagation/PropagationSetterInterface.php
new file mode 100644
index 000000000..75e205628
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/PropagationSetterInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#setter-argument
+ */
+interface PropagationSetterInterface
+{
+ /**
+ * Set the value for a given key on the associated carrier.
+ */
+ public function set(&$carrier, string $key, string $value) : void;
+}
diff --git a/vendor/open-telemetry/context/Propagation/SanitizeCombinedHeadersPropagationGetter.php b/vendor/open-telemetry/context/Propagation/SanitizeCombinedHeadersPropagationGetter.php
new file mode 100644
index 000000000..40652982e
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/SanitizeCombinedHeadersPropagationGetter.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+use function preg_replace;
+
+/**
+ * Some servers concatenate multiple headers with ';' -- we need to replace these with ','
+ * This is still a workaround and doesn't get around the problem fully, specifically it doesn't
+ * handle edge cases where the header has a trailing ';' or an empty trace state.
+ * We also need to trim trailing separators from the header, found when a header is empty.
+ */
+final class SanitizeCombinedHeadersPropagationGetter implements PropagationGetterInterface
+{
+ private const LIST_MEMBERS_SEPARATOR = ',';
+ private const SERVER_CONCAT_HEADERS_REGEX = '/;(?=[^,=;]*=|$)/';
+ private const TRAILING_LEADING_SEPARATOR_REGEX = '/^' . self::LIST_MEMBERS_SEPARATOR . '+|' . self::LIST_MEMBERS_SEPARATOR . '+$/';
+
+ private PropagationGetterInterface $getter;
+
+ public function __construct(PropagationGetterInterface $getter)
+ {
+ $this->getter = $getter;
+ }
+
+ public function keys($carrier): array
+ {
+ return $this->getter->keys($carrier);
+ }
+
+ public function get($carrier, string $key): ?string
+ {
+ $value = $this->getter->get($carrier, $key);
+ if ($value === null) {
+ return null;
+ }
+
+ return preg_replace(
+ [self::SERVER_CONCAT_HEADERS_REGEX, self::TRAILING_LEADING_SEPARATOR_REGEX],
+ [self::LIST_MEMBERS_SEPARATOR],
+ $value,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/context/Propagation/TextMapPropagatorInterface.php b/vendor/open-telemetry/context/Propagation/TextMapPropagatorInterface.php
new file mode 100644
index 000000000..fdf2d5141
--- /dev/null
+++ b/vendor/open-telemetry/context/Propagation/TextMapPropagatorInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\Context\Propagation;
+
+use OpenTelemetry\Context\ContextInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#textmap-propagator
+ */
+interface TextMapPropagatorInterface
+{
+ /**
+ * Returns list of fields that will be used by this propagator.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#fields
+ *
+ * @return list<string>
+ */
+ public function fields() : array;
+
+ /**
+ * Injects specific values from the provided {@see ContextInterface} into the provided carrier
+ * via an {@see PropagationSetterInterface}.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#textmap-inject
+ *
+ * @param mixed $carrier
+ */
+ public function inject(&$carrier, PropagationSetterInterface $setter = null, ContextInterface $context = null): void;
+
+ /**
+ * Extracts specific values from the provided carrier into the provided {@see ContextInterface}
+ * via an {@see PropagationGetterInterface}.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#textmap-extract
+ */
+ public function extract($carrier, PropagationGetterInterface $getter = null, ContextInterface $context = null): ContextInterface;
+}