8889841chome/clixcotz/mars.clix.co.tz/vendor/react/dns/src/Model/Message.php000066600000013276150515414520021411 0ustar00id = self::generateId(); $request->rd = true; $request->questions[] = $query; return $request; } /** * Creates a new response message for the given query with the given answer records * * @param Query $query * @param Record[] $answers * @return self */ public static function createResponseWithAnswersForQuery(Query $query, array $answers) { $response = new Message(); $response->id = self::generateId(); $response->qr = true; $response->rd = true; $response->questions[] = $query; foreach ($answers as $record) { $response->answers[] = $record; } return $response; } /** * generates a random 16 bit message ID * * This uses a CSPRNG so that an outside attacker that is sending spoofed * DNS response messages can not guess the message ID to avoid possible * cache poisoning attacks. * * The `random_int()` function is only available on PHP 7+ or when * https://github.com/paragonie/random_compat is installed. As such, using * the latest supported PHP version is highly recommended. This currently * falls back to a less secure random number generator on older PHP versions * in the hope that this system is properly protected against outside * attackers, for example by using one of the common local DNS proxy stubs. * * @return int * @see self::getId() * @codeCoverageIgnore */ private static function generateId() { if (function_exists('random_int')) { return random_int(0, 0xffff); } return mt_rand(0, 0xffff); } /** * The 16 bit message ID * * The response message ID has to match the request message ID. This allows * the receiver to verify this is the correct response message. An outside * attacker may try to inject fake responses by "guessing" the message ID, * so this should use a proper CSPRNG to avoid possible cache poisoning. * * @var int 16 bit message ID * @see self::generateId() */ public $id = 0; /** * @var bool Query/Response flag, query=false or response=true */ public $qr = false; /** * @var int specifies the kind of query (4 bit), see self::OPCODE_* constants * @see self::OPCODE_QUERY */ public $opcode = self::OPCODE_QUERY; /** * * @var bool Authoritative Answer */ public $aa = false; /** * @var bool TrunCation */ public $tc = false; /** * @var bool Recursion Desired */ public $rd = false; /** * @var bool Recursion Available */ public $ra = false; /** * @var int response code (4 bit), see self::RCODE_* constants * @see self::RCODE_OK */ public $rcode = Message::RCODE_OK; /** * An array of Query objects * * ```php * $questions = array( * new Query( * 'reactphp.org', * Message::TYPE_A, * Message::CLASS_IN * ) * ); * ``` * * @var Query[] */ public $questions = array(); /** * @var Record[] */ public $answers = array(); /** * @var Record[] */ public $authority = array(); /** * @var Record[] */ public $additional = array(); } home/clixcotz/mars.clix.co.tz/vendor/guzzlehttp/psr7/src/Message.php000066600000020201150515514540021567 0ustar00getMethod() . ' ' . $message->getRequestTarget()) . ' HTTP/' . $message->getProtocolVersion(); if (!$message->hasHeader('host')) { $msg .= "\r\nHost: " . $message->getUri()->getHost(); } } elseif ($message instanceof ResponseInterface) { $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' . $message->getStatusCode() . ' ' . $message->getReasonPhrase(); } else { throw new \InvalidArgumentException('Unknown message type'); } foreach ($message->getHeaders() as $name => $values) { if (strtolower($name) === 'set-cookie') { foreach ($values as $value) { $msg .= "\r\n{$name}: " . $value; } } else { $msg .= "\r\n{$name}: " . implode(', ', $values); } } return "{$msg}\r\n\r\n" . $message->getBody(); } /** * Get a short summary of the message body. * * Will return `null` if the response is not printable. * * @param MessageInterface $message The message to get the body summary * @param int $truncateAt The maximum allowed size of the summary */ public static function bodySummary(MessageInterface $message, int $truncateAt = 120): ?string { $body = $message->getBody(); if (!$body->isSeekable() || !$body->isReadable()) { return null; } $size = $body->getSize(); if ($size === 0) { return null; } $body->rewind(); $summary = $body->read($truncateAt); $body->rewind(); if ($size > $truncateAt) { $summary .= ' (truncated...)'; } // Matches any printable character, including unicode characters: // letters, marks, numbers, punctuation, spacing, and separators. if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary)) { return null; } return $summary; } /** * Attempts to rewind a message body and throws an exception on failure. * * The body of the message will only be rewound if a call to `tell()` * returns a value other than `0`. * * @param MessageInterface $message Message to rewind * * @throws \RuntimeException */ public static function rewindBody(MessageInterface $message): void { $body = $message->getBody(); if ($body->tell()) { $body->rewind(); } } /** * Parses an HTTP message into an associative array. * * The array contains the "start-line" key containing the start line of * the message, "headers" key containing an associative array of header * array values, and a "body" key containing the body of the message. * * @param string $message HTTP request or response to parse. */ public static function parseMessage(string $message): array { if (!$message) { throw new \InvalidArgumentException('Invalid message'); } $message = ltrim($message, "\r\n"); $messageParts = preg_split("/\r?\n\r?\n/", $message, 2); if ($messageParts === false || count($messageParts) !== 2) { throw new \InvalidArgumentException('Invalid message: Missing header delimiter'); } [$rawHeaders, $body] = $messageParts; $rawHeaders .= "\r\n"; // Put back the delimiter we split previously $headerParts = preg_split("/\r?\n/", $rawHeaders, 2); if ($headerParts === false || count($headerParts) !== 2) { throw new \InvalidArgumentException('Invalid message: Missing status line'); } [$startLine, $rawHeaders] = $headerParts; if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') { // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0 $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders); } /** @var array[] $headerLines */ $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER); // If these aren't the same, then one line didn't match and there's an invalid header. if ($count !== substr_count($rawHeaders, "\n")) { // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4 if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); } throw new \InvalidArgumentException('Invalid header syntax'); } $headers = []; foreach ($headerLines as $headerLine) { $headers[$headerLine[1]][] = $headerLine[2]; } return [ 'start-line' => $startLine, 'headers' => $headers, 'body' => $body, ]; } /** * Constructs a URI for an HTTP request message. * * @param string $path Path from the start-line * @param array $headers Array of headers (each value an array). */ public static function parseRequestUri(string $path, array $headers): string { $hostKey = array_filter(array_keys($headers), function ($k) { // Numeric array keys are converted to int by PHP. $k = (string) $k; return strtolower($k) === 'host'; }); // If no host is found, then a full URI cannot be constructed. if (!$hostKey) { return $path; } $host = $headers[reset($hostKey)][0]; $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; return $scheme . '://' . $host . '/' . ltrim($path, '/'); } /** * Parses a request message string into a request object. * * @param string $message Request message string. */ public static function parseRequest(string $message): RequestInterface { $data = self::parseMessage($message); $matches = []; if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { throw new \InvalidArgumentException('Invalid request string'); } $parts = explode(' ', $data['start-line'], 3); $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1'; $request = new Request( $parts[0], $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1], $data['headers'], $data['body'], $version ); return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); } /** * Parses a response message string into a response object. * * @param string $message Response message string. */ public static function parseResponse(string $message): ResponseInterface { $data = self::parseMessage($message); // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space // between status-code and reason-phrase is required. But browsers accept // responses without space and reason as well. if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']); } $parts = explode(' ', $data['start-line'], 3); return new Response( (int) $parts[1], $data['headers'], $data['body'], explode('/', $parts[0])[1], $parts[2] ?? null ); } }