Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add http proxy option for curl client #775

Merged
merged 13 commits into from
Feb 23, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Updated .gitattributes to reduce package footprint (#770)
- Use multibyte functions to handle unicode paths (#774)
- Remove `Hub::getScope()` to deny direct access to `Scope` instances (#776)
- Reintroduce `http_proxy` option (#775)

## 2.0.0-beta2 (2019-02-11)
- Rename `SentryAuth` class to `SentryAuthentication` (#742)
Expand Down
2 changes: 0 additions & 2 deletions UPGRADE-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

### Client options

- The `http_proxy` option has been removed.

- The `exclude` option has been removed.

- The `excluded_app_path` option has been renamed to `in_app_exclude`
Expand Down
16 changes: 16 additions & 0 deletions src/ClientBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Http\Client\Common\Plugin\HeaderSetPlugin;
use Http\Client\Common\Plugin\RetryPlugin;
use Http\Client\Common\PluginClient;
use Http\Client\Curl\Client as HttpCurlClient;
use Http\Client\HttpAsyncClient;
use Http\Discovery\HttpAsyncClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
Expand Down Expand Up @@ -314,6 +315,21 @@ private function createTransportInstance(): TransportInterface

$this->messageFactory = $this->messageFactory ?? MessageFactoryDiscovery::find();
$this->uriFactory = $this->uriFactory ?? UriFactoryDiscovery::find();

if (null !== $this->options->getHttpProxy()) {
if (null !== $this->httpClient) {
throw new \RuntimeException('The `http_proxy` option does not work together with a custom client.');
}

if (HttpAsyncClientDiscovery::safeClassExists(HttpCurlClient::class)) {
$this->httpClient = new HttpCurlClient(null, null, [
CURLOPT_PROXY => $this->options->getHttpProxy(),
]);
} else {
throw new \RuntimeException('The `http_proxy` option requires the `php-http/curl-client` package to be installed.');
}
}

$this->httpClient = $this->httpClient ?? HttpAsyncClientDiscovery::find();

if (null === $this->messageFactory) {
Expand Down
24 changes: 24 additions & 0 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,28 @@ public function setMaxValueLength(int $maxValueLength): void
$this->options = $this->resolver->resolve($options);
}

/**
* Gets the http proxy setting.
*
* @return string|null
*/
public function getHttpProxy(): ?string
{
return $this->options['http_proxy'];
}

/**
* Sets the http proxy. Be aware this option only works when curl client is used.
*
* @param string|null $httpProxy The http proxy
*/
public function setHttpProxy(?string $httpProxy): void
{
$options = array_merge($this->options, ['http_proxy' => $httpProxy]);

$this->options = $this->resolver->resolve($options);
}

/**
* Configures the options of the client.
*
Expand Down Expand Up @@ -657,6 +679,7 @@ private function configureOptions(OptionsResolver $resolver): void
'in_app_exclude' => [],
'send_default_pii' => false,
'max_value_length' => 1024,
'http_proxy' => null,
]);

$resolver->setAllowedTypes('send_attempts', 'int');
Expand All @@ -682,6 +705,7 @@ private function configureOptions(OptionsResolver $resolver): void
$resolver->setAllowedTypes('send_default_pii', 'bool');
$resolver->setAllowedTypes('default_integrations', 'bool');
$resolver->setAllowedTypes('max_value_length', 'int');
$resolver->setAllowedTypes('http_proxy', ['null', 'string']);

$resolver->setAllowedValues('dsn', \Closure::fromCallable([$this, 'validateDsnOption']));
$resolver->setAllowedValues('integrations', \Closure::fromCallable([$this, 'validateIntegrationsOption']));
Expand Down
16 changes: 16 additions & 0 deletions tests/ClientBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ public function testCreateWithNoOptionsIsTheSameAsDefaultOptions(): void
ClientBuilder::create([])
);
}

public function testCreateWithHttpProxyAndCustomTransportThrowsException(): void
{
$options = new Options([
'dsn' => 'http://public:secret@example.com/sentry/1',
'http_proxy' => 'some-proxy',
]);

$clientBuilder = new ClientBuilder($options);
$clientBuilder->setHttpClient($this->createMock(HttpAsyncClient::class));

$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('The `http_proxy` option does not work together with a custom client.');

$clientBuilder->getClient();
}
}

final class StubIntegration implements IntegrationInterface
Expand Down
1 change: 1 addition & 0 deletions tests/OptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public function optionsDataProvider(): array
['send_default_pii', true, 'shouldSendDefaultPii', 'setSendDefaultPii'],
['default_integrations', false, 'hasDefaultIntegrations', 'setDefaultIntegrations'],
['max_value_length', 50, 'getMaxValueLength', 'setMaxValueLength'],
['http_proxy', '127.0.0.1', 'getHttpProxy', 'setHttpProxy'],
];
}

Expand Down