krz/vox-populi

A Tumblr web client.

clone: git clone https://gitbay.org/krz/vox-populi.git

main: vendor/guzzlehttp/guzzle/src/MessageFormatter.php · raw

  1<?php
  2namespace GuzzleHttp;
  3
  4use Psr\Http\Message\MessageInterface;
  5use Psr\Http\Message\RequestInterface;
  6use Psr\Http\Message\ResponseInterface;
  7
  8/**
  9 * Formats log messages using variable substitutions for requests, responses,
 10 * and other transactional data.
 11 *
 12 * The following variable substitutions are supported:
 13 *
 14 * - {request}:        Full HTTP request message
 15 * - {response}:       Full HTTP response message
 16 * - {ts}:             ISO 8601 date in GMT
 17 * - {date_iso_8601}   ISO 8601 date in GMT
 18 * - {date_common_log} Apache common log date using the configured timezone.
 19 * - {host}:           Host of the request
 20 * - {method}:         Method of the request
 21 * - {uri}:            URI of the request
 22 * - {version}:        Protocol version
 23 * - {target}:         Request target of the request (path + query + fragment)
 24 * - {hostname}:       Hostname of the machine that sent the request
 25 * - {code}:           Status code of the response (if available)
 26 * - {phrase}:         Reason phrase of the response  (if available)
 27 * - {error}:          Any error messages (if available)
 28 * - {req_header_*}:   Replace `*` with the lowercased name of a request header to add to the message
 29 * - {res_header_*}:   Replace `*` with the lowercased name of a response header to add to the message
 30 * - {req_headers}:    Request headers
 31 * - {res_headers}:    Response headers
 32 * - {req_body}:       Request body
 33 * - {res_body}:       Response body
 34 */
 35class MessageFormatter
 36{
 37    /**
 38     * Apache Common Log Format.
 39     * @link http://httpd.apache.org/docs/2.4/logs.html#common
 40     * @var string
 41     */
 42    const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
 43    const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
 44    const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
 45
 46    /** @var string Template used to format log messages */
 47    private $template;
 48
 49    /**
 50     * @param string $template Log message template
 51     */
 52    public function __construct($template = self::CLF)
 53    {
 54        $this->template = $template ?: self::CLF;
 55    }
 56
 57    /**
 58     * Returns a formatted message string.
 59     *
 60     * @param RequestInterface  $request  Request that was sent
 61     * @param ResponseInterface $response Response that was received
 62     * @param \Exception        $error    Exception that was received
 63     *
 64     * @return string
 65     */
 66    public function format(
 67        RequestInterface $request,
 68        ResponseInterface $response = null,
 69        \Exception $error = null
 70    ) {
 71        $cache = [];
 72
 73        return preg_replace_callback(
 74            '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
 75            function (array $matches) use ($request, $response, $error, &$cache) {
 76                if (isset($cache[$matches[1]])) {
 77                    return $cache[$matches[1]];
 78                }
 79
 80                $result = '';
 81                switch ($matches[1]) {
 82                    case 'request':
 83                        $result = Psr7\str($request);
 84                        break;
 85                    case 'response':
 86                        $result = $response ? Psr7\str($response) : '';
 87                        break;
 88                    case 'req_headers':
 89                        $result = trim($request->getMethod()
 90                                . ' ' . $request->getRequestTarget())
 91                            . ' HTTP/' . $request->getProtocolVersion() . "\r\n"
 92                            . $this->headers($request);
 93                        break;
 94                    case 'res_headers':
 95                        $result = $response ?
 96                            sprintf(
 97                                'HTTP/%s %d %s',
 98                                $response->getProtocolVersion(),
 99                                $response->getStatusCode(),
100                                $response->getReasonPhrase()
101                            ) . "\r\n" . $this->headers($response)
102                            : 'NULL';
103                        break;
104                    case 'req_body':
105                        $result = $request->getBody();
106                        break;
107                    case 'res_body':
108                        $result = $response ? $response->getBody() : 'NULL';
109                        break;
110                    case 'ts':
111                    case 'date_iso_8601':
112                        $result = gmdate('c');
113                        break;
114                    case 'date_common_log':
115                        $result = date('d/M/Y:H:i:s O');
116                        break;
117                    case 'method':
118                        $result = $request->getMethod();
119                        break;
120                    case 'version':
121                        $result = $request->getProtocolVersion();
122                        break;
123                    case 'uri':
124                    case 'url':
125                        $result = $request->getUri();
126                        break;
127                    case 'target':
128                        $result = $request->getRequestTarget();
129                        break;
130                    case 'req_version':
131                        $result = $request->getProtocolVersion();
132                        break;
133                    case 'res_version':
134                        $result = $response
135                            ? $response->getProtocolVersion()
136                            : 'NULL';
137                        break;
138                    case 'host':
139                        $result = $request->getHeaderLine('Host');
140                        break;
141                    case 'hostname':
142                        $result = gethostname();
143                        break;
144                    case 'code':
145                        $result = $response ? $response->getStatusCode() : 'NULL';
146                        break;
147                    case 'phrase':
148                        $result = $response ? $response->getReasonPhrase() : 'NULL';
149                        break;
150                    case 'error':
151                        $result = $error ? $error->getMessage() : 'NULL';
152                        break;
153                    default:
154                        // handle prefixed dynamic headers
155                        if (strpos($matches[1], 'req_header_') === 0) {
156                            $result = $request->getHeaderLine(substr($matches[1], 11));
157                        } elseif (strpos($matches[1], 'res_header_') === 0) {
158                            $result = $response
159                                ? $response->getHeaderLine(substr($matches[1], 11))
160                                : 'NULL';
161                        }
162                }
163
164                $cache[$matches[1]] = $result;
165                return $result;
166            },
167            $this->template
168        );
169    }
170
171    /**
172     * Get headers from message as string
173     *
174     * @return string
175     */
176    private function headers(MessageInterface $message)
177    {
178        $result = '';
179        foreach ($message->getHeaders() as $name => $values) {
180            $result .= $name . ': ' . implode(', ', $values) . "\r\n";
181        }
182
183        return trim($result);
184    }
185}