geocoder-php / GeocoderLaravel

Geocoder service provider for Laravel
http://geocoder-php.org/GeocoderLaravel/
MIT License
701 stars 102 forks source link

How to set curl proxy in config ? #45

Open philippejadin opened 8 years ago

philippejadin commented 8 years ago

Hello,

In config/geocoder.php, how can I set the proxy? I tried that :

return [
    // Providers get called in the chain order given here.
    // The first one to return a result will be used.
    'providers' => [
        'Geocoder\Provider\GoogleMapsProvider' => ['fr-FR', 'Île-de-France', true],
        'Geocoder\Provider\FreeGeoIpProvider'  => null,
    ],
    'adapter'  => new Geocoder\HttpAdapter\CurlHttpAdapter(['http_proxy' => 'myproxy.domain.name']),
];

But it doesn't work :-/

mikebronner commented 7 years ago

This might not be possible just yet. Have you found a work-around in the meantime? None of the adapters I seem to document how to implement a proxy. The library egeloen/http-adapter (https://github.com/egeloen/ivory-http-adapter) used for adapters in Geocoder 3.x has since been deprecated, and doesn't document use of proxies (at least that I can find) either.

If anyone can contribute to this discussion on how to implement proxies with Geocoder 3.x, please let us know. :)

mikebronner commented 7 years ago

Closing this for now. No plans to implement unless someone can submit a PR for this, or a work-around can be documented. Haven't heard back from OP, please re-open if this is a critical issue.

extraric commented 5 years ago

I don't know if its still relevant, I solve this way for temporarily: in geocoder.php insert after 'reader' line:

/*
|---------------------------------------------------------------------------
| CURL options
|---------------------------------------------------------------------------
|
| CURL custom option declaration
|
| Default: []
*/
'client_options' => [
    CURLOPT_PROXY => env('CURL_PROXY', null),
    CURLOPT_PROXYUSERPWD => env('CURL_PROXYUSERPWD', '')
],

in the .env file:

CURL_PROXY=<proxy.ip>:<proxy.port>
CURL_PROXYUSERPWD=<proxyauth.username>:<proxy.password>

In the ProviderAndDumperAggregator.php I edited getArguments() function:

...
    if ($adapter) {
        if ($this->requiresReader($provider)) {
            $reader = config('geocoder.reader');
        }
        if ($this->curlOpt($adapter)) {
            $curlOpt = config('geocoder.client_options');
            array_unshift($arguments, new $adapter(null,null,$curlOpt));
        } else {
            array_unshift($arguments, new $adapter($reader));
        }
    }
...

and copied requiresReader() function to this at the end:

...
    protected function curlOpt(string $class) : bool
    {
        $specificAdapters = collect([
            'Http\Client\Curl\Client',
        ]);

        return $specificAdapters->contains($class);
    }

Not perfect but working for me, obviously not working GeoIP2 reader with CULR together, but not needed for me. I fear of editing vendor files, but I'm very newbie, not know how to do anyway.

mikebronner commented 5 years ago

Reopening and will review in the near future.

tbruckmaier commented 7 months ago

As a possible workaround you can extend GuzzleHttp\Client, override the construcor and set proxy options there, and use that class in the geocoder config.

Example with guzzle (though the principal idea can be adapted with curl too):

// app/Support/GuzzleClient.php
<?php

namespace App\Support;

use GuzzleHttp\Client;

class GuzzleClient extends Client
{
    public function __construct(array $config = [])
    {
        parent::__construct(['proxy' => 'proxy.example.com:3128', ...$config]);
    }
}
// config/geocoder.php
<?php
use App\Support\GuzzleClient;

return [
    // ...
    'adapter'  => GuzzleClient::class,
    // ...
];

As a bonus, you can use the pre-configured GuzzleClient in laravel's Http client too (so any Http::... calls use the same proxy configuration)


<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Support\GuzzleClient;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $this->app->extend(\Illuminate\Http\Client\Factory::class, function ($service, $app) {
            return $service->setClient(new GuzzleClient);
        });
    }