Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Http Proxy React Laravel Package

clue/http-proxy-react

Async HTTP proxy with support for forward and reverse proxying (including HTTPS via CONNECT), built on ReactPHP. Useful for tunneling, debugging and routing HTTP(S) traffic in event-driven PHP apps, with streaming I/O and low overhead.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

To integrate clue/http-proxy-react in a Laravel application, start by installing the package via Composer:

composer require clue/http-proxy-react react/socket react/http

First Use Case: Proxying HTTPS Requests

Leverage the package to route HTTPS traffic through a proxy (e.g., for scraping or bypassing geo-restrictions). Example:

use Clue\React\HttpProxy\ProxyConnector;
use React\Socket\Connector;
use React\Http\Browser;

public function proxyRequest()
{
    $loop = React\EventLoop\Factory::create();
    $proxy = new ProxyConnector('proxy.example.com:8080');
    $connector = new Connector(['tcp' => $proxy, 'dns' => false], $loop);

    $browser = new Browser($connector);
    $browser->get('https://example.com')->then(
        fn($response) => dd($response->getBody()->getContents()),
        fn($e) => dd($e->getMessage())
    );

    $loop->run();
}

Key Steps:

  1. Initialize ReactPHP's event loop.
  2. Create a ProxyConnector with your proxy server URL.
  3. Wrap it in a Connector to integrate with ReactPHP's ecosystem.
  4. Use React\Http\Browser to send requests through the proxy.

Implementation Patterns

1. Proxying TCP Services (SMTP, IMAP, etc.)

Use the ProxyConnector to tunnel non-HTTP protocols (e.g., SMTP, IMAP) through an HTTP proxy. Example:

$proxy = new ProxyConnector('proxy.example.com:8080');
$connector = new Connector(['tcp' => $proxy], $loop);

$connector->connect('tcp://smtp.example.com:25')->then(
    fn($connection) => $connection->write("EHLO example.com\r\n"),
    fn($e) => dd($e->getMessage())
);

2. Handling Authentication

Pass credentials directly in the proxy URL:

$proxy = new ProxyConnector('user:pass@proxy.example.com:8080');

3. Customizing Timeouts

Wrap the ProxyConnector in Connector to enforce timeouts:

$connector = new Connector(['tcp' => $proxy, 'timeout' => 5.0], $loop);

4. Local vs. Remote DNS Resolution

  • Remote DNS (default): Let the proxy resolve hostnames.
    $connector = new Connector(['tcp' => $proxy, 'dns' => false], $loop);
    
  • Local DNS: Resolve hostnames locally before proxying.
    $connector = new Connector(['tcp' => $proxy, 'dns' => '8.8.8.8'], $loop);
    

5. Integration with Laravel HTTP Client

Use the package with Laravel's HTTP client by replacing the underlying connector:

use Illuminate\Support\Facades\Http;

$loop = React\EventLoop\Factory::create();
$proxy = new ProxyConnector('proxy.example.com:8080');
$connector = new Connector(['tcp' => $proxy], $loop);

Http::macro('throughProxy', function ($url) use ($connector) {
    return Http::withOptions([
        'connector' => $connector,
    ])->get($url);
});

// Usage
Http::throughProxy('https://example.com')->then(...);

Gotchas and Tips

1. Proxy Server Limitations

  • Many public proxies restrict traffic to port 443 (HTTPS). Attempting to proxy other ports (e.g., SMTP on 25) may fail.
  • Workaround: Use a private proxy or configure the proxy to allow all ports.

2. DNS Resolution Pitfalls

  • Remote DNS (default): If your Laravel app cannot resolve hostnames (e.g., no internet access), the proxy must handle DNS.
  • Local DNS: Requires manual hostname resolution (e.g., using gethostbyname()) before proxying.

3. Authentication Quirks

  • Percent-encoding: Ensure usernames/passwords with special characters (e.g., @, :) are URL-encoded:
    $url = rawurlencode('user@domain') . ':' . rawurlencode('pass!') . '@proxy.example.com';
    
  • Proxy Rejection: If authentication fails, the proxy returns a 407 error. Handle this gracefully:
    $proxy->connect('https://example.com')->otherwise(
        fn($e) => $e->getCode() === 407 ? dd('Proxy auth failed') : dd($e)
    );
    

4. Event Loop Management

  • Laravel Queues: Avoid blocking the event loop in queue workers. Use React\Promise\Timer\TimeoutException to enforce timeouts:
    $promise->timeout(3.0)->then(...)->otherwise(fn($e) => dd('Timeout'));
    
  • Synchronous Code: ReactPHP is async. Avoid mixing it with Laravel's sync code (e.g., in routes). Use React\Promise\resolve() to bridge:
    $loop->futureTick(fn() => $syncFunction());
    

5. Debugging Connections

  • Logs: Enable ReactPHP debug mode to log connection attempts:
    React\EventLoop\Factory::create(['debug' => true]);
    
  • Proxy Headers: Add custom headers (e.g., Via, X-Forwarded-For) to debug proxy hops:
    $proxy = new ProxyConnector('proxy.example.com:8080', null, [
        'headers' => ['Via' => 'Laravel/Proxy']
    ]);
    

6. Extending Functionality

  • Custom Headers: Pass additional HTTP headers to the proxy:
    $proxy = new ProxyConnector('proxy.example.com:8080', null, [
        'headers' => ['User-Agent' => 'Laravel/Proxy']
    ]);
    
  • Unix Sockets: Proxy connections via Unix domain sockets (advanced):
    $proxy = new ProxyConnector('unix:///var/run/proxy.sock');
    

7. Laravel Service Provider Integration

Register the proxy connector as a singleton in AppServiceProvider:

public function register()
{
    $this->app->singleton('proxy.connector', fn() => new ProxyConnector(config('proxy.url')));
}

Then inject it into services:

public function __construct(private ProxyConnector $proxy) {}
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi