8000 [HttpClient] make $response->getInfo('debug') return extended logs ab… · symfony/symfony@5a8157d · GitHub
[go: up one dir, main page]

Skip to content

Commit 5a8157d

Browse files
[HttpClient] make $response->getInfo('debug') return extended logs about the HTTP transaction
1 parent 97d378a commit 5a8157d

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public function request(string $method, string $url, array $options = []): Respo
108108
'size_body' => \strlen($options['body']),
109109
'primary_ip' => '',
110110
'primary_port' => 'http:' === $url['scheme'] ? 80 : 443,
111+
'debug' => \extension_loaded('curl') ? '' : "* Enable the curl extension for better performance\n",
111112
];
112113

113114
if ($onProgress = $options['on_progress']) {
@@ -139,6 +140,8 @@ public function request(string $method, string $url, array $options = []): Respo
139140
$info['size_download'] = $dlNow;
140141
} elseif (STREAM_NOTIFY_CONNECT === $code) {
141142
$info['connect_time'] += $now - $info['fopen_time'];
143+
$info['debug'] .= $info['request_header'];
144+
unset($info['request_header']);
142145
} else {
143146
return;
144147
}
@@ -160,13 +163,16 @@ public function request(string $method, string $url, array $options = []): Respo
160163
$options['request_headers'][] = 'host: '.$host.$port;
161164
}
162165

166+
if (!isset($options['headers']['user-agent'])) {
167+
$options['request_headers'][] = 'user-agent: Symfony HttpClient/Native';
168+
}
169+
163170
$context = [
164171
'http' => [
165172
'protocol_version' => $options['http_version'] ?: '1.1',
166173
'method' => $method,
167174
'content' => $options['body'],
168175
'ignore_errors' => true,
169-
'user_agent' => 'Symfony HttpClient/Native',
170176
'curl_verify_ssl_peer' => $options['verify_peer'],
171177
'curl_verify_ssl_host' => $options['verify_host'],
172178
'auto_decode' => false, // Disable dechunk filter, it's incompatible with stream_select()
@@ -296,6 +302,7 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
296302
$host = parse_url($url['authority'], PHP_URL_HOST);
297303

298304
if (null === $ip = $multi->dnsCache[$host] ?? null) {
305+
$info['debug'] .= "* Hostname was NOT found in DNS cache\n";
299306
$now = microtime(true);
300307

301308
if (!$ip = gethostbynamel($host)) {
@@ -304,6 +311,9 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
304311

305312
$info['namelookup_time'] += microtime(true) - $now;
306313
$multi->dnsCache[$host] = $ip = $ip[0];
314+
$info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n";
315+
} else {
316+
$info['debug'] .= "* Hostname was found in DNS cache\n";
307317
}
308318

309319
$info['primary_ip'] = $ip;

src/Symfony/Component/HttpClient/Response/CurlResponse.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ final class CurlResponse implements ResponseInterface
2828

2929
private static $performing = false;
3030
private $multi;
31+
private $debugBuffer;
3132

3233
/**
3334
* @internal
@@ -38,6 +39,9 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
3839

3940
if (\is_resource($ch)) {
4041
$this->handle = $ch;
42+
$this->debugBuffer = fopen('php://temp', 'w+');
43+
curl_setopt($ch, CURLOPT_VERBOSE, true);
44+
curl_setopt($ch, CURLOPT_STDERR, $this->debugBuffer);
4145
} else {
4246
$this->info['url'] = $ch;
4347
$ch = $this->handle;
@@ -143,6 +147,13 @@ public function getInfo(string $type = null)
143147
{
144148
if (!$info = $this->finalInfo) {
145149
self::perform($this->multi);
150+
151+
if ('debug' === $type) {
152+
rewind($this->debugBuffer);
153+
154+
return stream_get_contents($this->debugBuffer);
155+
}
156+
146157
$info = array_merge($this->info, curl_getinfo($this->handle));
147158
$info['url'] = $this->info['url'] ?? $info['url'];
148159
$info['redirect_url'] = $this->info['redirect_url'] ?? null;
@@ -154,6 +165,10 @@ public function getInfo(string $type = null)
154165
}
155166

156167
if (!\in_array(curl_getinfo($this->handle, CURLINFO_PRIVATE), ['headers', 'content'], true)) {
168+
rewind($this->debugBuffer);
169+
$info['debug'] = stream_get_contents($this->debugBuffer);
170+
fclose($this->debugBuffer);
171+
$this->debugBuffer = null;
157172
$this->finalInfo = $info;
158173
}
159174
}

src/Symfony/Component/HttpClient/Response/NativeResponse.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ final class NativeResponse implements ResponseInterface
3434
private $buffer;
3535
private $inflate;
3636
private $multi;
37+
private $debugBuffer;
3738

3839
/**
3940
* @internal
@@ -76,12 +77,19 @@ public function getInfo(string $type = null)
7677
{
7778
if (!$info = $this->finalInfo) {
7879
self::perform($this->multi);
80+
81+
if ('debug' === $type) {
82+
return $this->info['debug'];
83+
}
84+
7985
$info = $this->info;
8086
$info['url'] = implode('', $info['url']);
81-
unset($info['fopen_time'], $info['size_body']);
87+
unset($info['fopen_time'], $info['size_body'], $info['request_header']);
8288

8389
if (null === $this->buffer) {
8490
$this->finalInfo = $info;
91+
} else {
92+
unset($info['debug']);
8593
}
8694
}
8795

@@ -112,10 +120,23 @@ private function open(): void
112120
$url = $this->url;
113121

114122
while (true) {
123+
$context = stream_context_get_options($this->context);
124+
125+
if ($proxy = $context['http']['proxy'] ?? null) {
126+
$this->info['debug'] .= "* Establish HTTP proxy tunnel to {$proxy}\n";
127+
$this->info['request_header'] = $url;
128+
} else {
129+
$this->info['debug'] .= "* Trying {$this->info['primary_ip']}...\n";
130+
$this->info['request_header'] = $this->info['url']['path'].$this->info['url']['query'];
131+
}
132+
133+
$this->info['request_header'] = sprintf("> %s %s HTTP/%s \r\n", $context['http']['method'], $this->info['request_header'], $context['http']['protocol_version']);
134+
$this->info['request_header'] .= implode("\r\n", $context['http']['header'])."\r\n\r\n";
135+
115136
// Send request and follow redirects when needed
116137
$this->info['fopen_time'] = microtime(true);
117138
$this->handle = $h = fopen($url, 'r', false, $this->context);
118-
self::addResponseHeaders($http_response_header, $this->info, $this->headers);
139+
self::addResponseHeaders($http_response_header, $this->info, $this->headers, $this->info['debug']);
119140
$url = ($this->resolveRedirect)($this->multi, $this->headers['location'][0] ?? null, $this->context);
120141

121142
if (null === $url) {
@@ -136,7 +157,6 @@ private function open(): void
136157
}
137158

138159
stream_set_blocking($h, false);
139-
$context = stream_context_get_options($this->context);
140160
$this->context = $this->resolveRedirect = null;
141161

142162
if (isset($context['ssl']['peer_certificate_chain'])) {

src/Symfony/Component/HttpClient/Response/ResponseTrait.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,25 @@ abstract protected static function perform(ClientState $multi, array &$responses
189189
*/
190190
abstract protected static function select(ClientState $multi, float $timeout): int;
191191

192-
private static function addResponseHeaders(array $responseHeaders, array &$info, array &$headers): void
192+
private static function addResponseHeaders(array $responseHeaders, array &$info, array &$headers, string &$debug = ''): void
193193
{
194194
foreach ($responseHeaders as $h) {
195195
if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? ([12345]\d\d) .*#', $h, $m)) {
196-
$headers = [];
196+
if ($headers) {
197+
$debug .= "< \r\n";
198+
$headers = [];
199+
}
197200
$info['http_code'] = (int) $m[1];
198201
} elseif (2 === \count($m = explode(':', $h, 2))) {
199202
$headers[strtolower($m[0])][] = ltrim($m[1]);
200203
}
201204

205+
$debug .= "< {$h}\r\n";
202206
$info['response_headers'][] = $h;
203207
}
204208

209+
$debug .= "< \r\n";
210+
205211
if (!$info['http_code']) {
206212
throw new TransportException('Invalid or missing HTTP status line.');
207213
}

0 commit comments

Comments
 (0)
0