Chris@0: write($message); Chris@0: return static::fromStream($stream); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Parse a response from a stream. Chris@0: * Chris@0: * @param StreamInterface $stream Chris@0: * @return Response Chris@0: * @throws InvalidArgumentException when the stream is not readable. Chris@0: * @throws UnexpectedValueException when errors occur parsing the message. Chris@0: */ Chris@0: public static function fromStream(StreamInterface $stream) Chris@0: { Chris@0: if (! $stream->isReadable() || ! $stream->isSeekable()) { Chris@0: throw new InvalidArgumentException('Message stream must be both readable and seekable'); Chris@0: } Chris@0: Chris@0: $stream->rewind(); Chris@0: Chris@0: list($version, $status, $reasonPhrase) = self::getStatusLine($stream); Chris@0: list($headers, $body) = self::splitStream($stream); Chris@0: Chris@0: return (new Response($body, $status, $headers)) Chris@0: ->withProtocolVersion($version) Chris@0: ->withStatus((int) $status, $reasonPhrase); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Create a string representation of a response. Chris@0: * Chris@0: * @param ResponseInterface $response Chris@0: * @return string Chris@0: */ Chris@0: public static function toString(ResponseInterface $response) Chris@0: { Chris@0: $reasonPhrase = $response->getReasonPhrase(); Chris@0: $headers = self::serializeHeaders($response->getHeaders()); Chris@0: $body = (string) $response->getBody(); Chris@0: $format = 'HTTP/%s %d%s%s%s'; Chris@0: Chris@0: if (! empty($headers)) { Chris@0: $headers = "\r\n" . $headers; Chris@0: } Chris@0: Chris@0: $headers .= "\r\n\r\n"; Chris@0: Chris@0: return sprintf( Chris@0: $format, Chris@0: $response->getProtocolVersion(), Chris@0: $response->getStatusCode(), Chris@0: ($reasonPhrase ? ' ' . $reasonPhrase : ''), Chris@0: $headers, Chris@0: $body Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieve the status line for the message. Chris@0: * Chris@0: * @param StreamInterface $stream Chris@0: * @return array Array with three elements: 0 => version, 1 => status, 2 => reason Chris@0: * @throws UnexpectedValueException if line is malformed Chris@0: */ Chris@0: private static function getStatusLine(StreamInterface $stream) Chris@0: { Chris@0: $line = self::getLine($stream); Chris@0: Chris@0: if (! preg_match( Chris@0: '#^HTTP/(?P[1-9]\d*\.\d) (?P[1-5]\d{2})(\s+(?P.+))?$#', Chris@0: $line, Chris@0: $matches Chris@0: )) { Chris@0: throw new UnexpectedValueException('No status line detected'); Chris@0: } Chris@0: Chris@0: return [$matches['version'], $matches['status'], isset($matches['reason']) ? $matches['reason'] : '']; Chris@0: } Chris@0: }