Merge branch '5.2' into 5.x

* 5.2:
  [HttpClient] fix binding to network interfaces
  [HttpClient] fix binding to network interfaces
This commit is contained in:
Nicolas Grekas 2020-11-28 14:34:21 +01:00
commit cf31b29ea1
4 changed files with 22 additions and 5 deletions

View File

@ -82,6 +82,15 @@ final class AmpHttpClient implements HttpClientInterface, LoggerAwareInterface,
throw new \LogicException('You cannot use the "proxy" option as the "amphp/http-tunnel" package is not installed. Try running "composer require amphp/http-tunnel".'); throw new \LogicException('You cannot use the "proxy" option as the "amphp/http-tunnel" package is not installed. Try running "composer require amphp/http-tunnel".');
} }
if ($options['bindto']) {
if (0 === strpos($options['bindto'], 'if!')) {
throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.');
}
if (0 === strpos($options['bindto'], 'host!')) {
$options['bindto'] = substr($options['bindto'], 5);
}
}
if ('' !== $options['body'] && 'POST' === $method && !isset($options['normalized_headers']['content-type'])) { if ('' !== $options['body'] && 'POST' === $method && !isset($options['normalized_headers']['content-type'])) {
$options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded';
} }
@ -141,7 +150,7 @@ final class AmpHttpClient implements HttpClientInterface, LoggerAwareInterface,
if ($responses instanceof AmpResponse) { if ($responses instanceof AmpResponse) {
$responses = [$responses]; $responses = [$responses];
} elseif (!is_iterable($responses)) { } elseif (!is_iterable($responses)) {
throw new \TypeError(sprintf('%s() expects parameter 1 to be an iterable of AmpResponse objects, %s given.', __METHOD__, get_debug_type($responses))); throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AmpResponse objects, "%s" given.', __METHOD__, get_debug_type($responses)));
} }
return new ResponseStream(AmpResponse::stream($responses, $timeout)); return new ResponseStream(AmpResponse::stream($responses, $timeout));

View File

@ -272,7 +272,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
if ($options['bindto']) { if ($options['bindto']) {
if (file_exists($options['bindto'])) { if (file_exists($options['bindto'])) {
$curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto']; $curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto'];
} elseif (preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { } elseif (0 !== strpos($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) {
$curlopts[\CURLOPT_INTERFACE] = $matches[1]; $curlopts[\CURLOPT_INTERFACE] = $matches[1];
$curlopts[\CURLOPT_LOCALPORT] = $matches[2]; $curlopts[\CURLOPT_LOCALPORT] = $matches[2];
} else { } else {

View File

@ -119,7 +119,7 @@ final class AmpClientState extends ClientState
private function getClient(array $options): array private function getClient(array $options): array
{ {
$options = [ $options = [
'bindto' => $options['bindto'] ?: '0', 'bindto' => $options['bindto'] ?: '0:0',
'verify_peer' => $options['verify_peer'], 'verify_peer' => $options['verify_peer'],
'capath' => $options['capath'], 'capath' => $options['capath'],
'cafile' => $options['cafile'], 'cafile' => $options['cafile'],

View File

@ -67,8 +67,16 @@ final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterfac
{ {
[$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions);
if ($options['bindto'] && file_exists($options['bindto'])) { if ($options['bindto']) {
throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); if (file_exists($options['bindto'])) {
throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.');
}
if (0 === strpos($options['bindto'], 'if!')) {
throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.');
}
if (0 === strpos($options['bindto'], 'host!')) {
$options['bindto'] = substr($options['bindto'], 5);
}
} }
$options['body'] = self::getBodyAsString($options['body']); $options['body'] = self::getBodyAsString($options['body']);