Use Host-header loopback for billing force_ip.
Deploy Ladill QR Plus / deploy (push) Successful in 1m45s
Deploy Ladill QR Plus / deploy (push) Successful in 1m45s
CURLOPT_RESOLVE was not reliably faster; rewrite the billing base URL to the forced IP and send the original Host header instead.
This commit is contained in:
@@ -18,11 +18,36 @@ class BillingClient
|
||||
{
|
||||
private const BALANCE_CACHE_TTL_SECONDS = 8;
|
||||
|
||||
private function base(): string
|
||||
private function configuredBase(): string
|
||||
{
|
||||
return rtrim((string) config('billing.api_url'), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Public billing URL rewritten to a same-host IP when force_ip is set.
|
||||
* Example: https://ladill.com/api/billing + 127.0.0.1
|
||||
* → https://127.0.0.1/api/billing (Host: ladill.com)
|
||||
*/
|
||||
private function base(): string
|
||||
{
|
||||
$base = $this->configuredBase();
|
||||
$forceIp = trim((string) config('billing.force_ip', ''));
|
||||
if ($forceIp === '') {
|
||||
return $base;
|
||||
}
|
||||
|
||||
$parts = parse_url($base);
|
||||
if (! is_array($parts) || empty($parts['host'])) {
|
||||
return $base;
|
||||
}
|
||||
|
||||
$scheme = $parts['scheme'] ?? 'https';
|
||||
$path = $parts['path'] ?? '';
|
||||
$port = isset($parts['port']) ? ':'.$parts['port'] : '';
|
||||
|
||||
return $scheme.'://'.$forceIp.$port.$path;
|
||||
}
|
||||
|
||||
private function token(): string
|
||||
{
|
||||
return (string) (config('billing.api_key') ?? '');
|
||||
@@ -40,29 +65,20 @@ class BillingClient
|
||||
return $pending;
|
||||
}
|
||||
|
||||
$host = parse_url($this->base(), PHP_URL_HOST);
|
||||
$scheme = parse_url($this->base(), PHP_URL_SCHEME) ?: 'https';
|
||||
$port = parse_url($this->base(), PHP_URL_PORT);
|
||||
if (! is_int($port) || $port <= 0) {
|
||||
$port = $scheme === 'http' ? 80 : 443;
|
||||
}
|
||||
|
||||
$host = parse_url($this->configuredBase(), PHP_URL_HOST);
|
||||
if (! is_string($host) || $host === '') {
|
||||
return $pending;
|
||||
}
|
||||
|
||||
$options = [
|
||||
'curl' => [
|
||||
CURLOPT_RESOLVE => [sprintf('%s:%d:%s', $host, $port, $forceIp)],
|
||||
],
|
||||
];
|
||||
$pending = $pending->withHeaders(['Host' => $host]);
|
||||
|
||||
// Loopback TLS often uses the public cert; skip verify only for forced local IP.
|
||||
if (in_array($forceIp, ['127.0.0.1', '::1', 'localhost'], true)) {
|
||||
$options['verify'] = false;
|
||||
// Loopback TLS cert is issued for the public host, not the IP.
|
||||
if (in_array($forceIp, ['127.0.0.1', '::1', 'localhost'], true)
|
||||
|| filter_var($forceIp, FILTER_VALIDATE_IP)) {
|
||||
$pending = $pending->withOptions(['verify' => false]);
|
||||
}
|
||||
|
||||
return $pending->withOptions($options);
|
||||
return $pending;
|
||||
}
|
||||
|
||||
private function get(string $path, array $query): array
|
||||
|
||||
Reference in New Issue
Block a user