', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}']; private const EXCLUDED_VALUE_CHARS = [' ', '"', ',', ';', '\\']; private const EQUALS = '='; /** @readonly */ private string $baggageHeader; public function __construct(string $baggageHeader) { $this->baggageHeader = $baggageHeader; } public function parseInto(BaggageBuilderInterface $baggageBuilder): void { foreach (explode(',', $this->baggageHeader) as $baggageString) { if (empty(trim($baggageString))) { continue; } $explodedString = explode(';', $baggageString, 2); $keyValue = trim($explodedString[0]); if (empty($keyValue) || mb_strpos($keyValue, self::EQUALS) === false) { continue; } $metadataString = $explodedString[1] ?? null; if ($metadataString && !empty(trim(($metadataString)))) { $metadata = new Metadata(trim($metadataString)); } else { $metadata = null; } [$key, $value] = explode(self::EQUALS, $keyValue, 2); $key = urldecode($key); $value = urldecode($value); $key = str_replace(self::EXCLUDED_KEY_CHARS, '', trim($key), $invalidKeyCharacters); if (empty($key) || $invalidKeyCharacters > 0) { continue; } $value = str_replace(self::EXCLUDED_VALUE_CHARS, '', trim($value), $invalidValueCharacters); if (empty($value) || $invalidValueCharacters > 0) { continue; } $baggageBuilder->set($key, $value, $metadata); } } }