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

Proxy syntax not consistent across handlers #2848

Closed
TimWolla opened this issue Feb 1, 2021 · 1 comment · Fixed by #2850
Closed

Proxy syntax not consistent across handlers #2848

TimWolla opened this issue Feb 1, 2021 · 1 comment · Fixed by #2850

Comments

@TimWolla
Copy link
Contributor

TimWolla commented Feb 1, 2021

Guzzle version(s) affected: Current git master (3a0543e / 7.2.0)
PHP version: 7.4.12
cURL version: 7.64.0

Description

The correct proxy syntax is not consistent across handlers. This is problematic, because certain request options automatically switch to another handler (namely stream).

How to reproduce

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;

require('vendor/autoload.php');

$client = new Client();

echo "####################".PHP_EOL;
echo "Stream: false".PHP_EOL;
echo "####################".PHP_EOL;

try {
	$request = new Request('GET', 'http://www.example.com');
	$response = $client->send($request, [
		'stream' => false,
	]);
	var_dump(substr($response->getBody(), 0, 100));
} catch (\Exception $e) {
	echo $e.PHP_EOL;
}

echo PHP_EOL;
echo "####################".PHP_EOL;
echo "Stream: true".PHP_EOL;
echo "####################".PHP_EOL;

try {
	$request = new Request('GET', 'http://www.example.com');
	$response = $client->send($request, [
		'stream' => true,
	]);
	var_dump(substr($response->getBody(), 0, 100));
} catch (\Exception $e) {
	echo $e.PHP_EOL;
}

Running this script against Tinyproxy:

With HTTP_PROXY=http://127.0.0.1:8888:

root@d96cb194032e:/pwd# HTTP_PROXY=http://127.0.0.1:8888 php test.php
####################
Stream: false
####################
/pwd/test.php:19:
string(100) "<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <m"

####################
Stream: true
####################
GuzzleHttp\Exception\ConnectException: Connection refused for URI http://www.example.com in /pwd/src/Handler/StreamHandler.php:311
Stack trace:
#0 /pwd/src/Handler/StreamHandler.php(230): GuzzleHttp\Handler\StreamHandler->GuzzleHttp\Handler\{closure}()
#1 /pwd/src/Handler/StreamHandler.php(322): GuzzleHttp\Handler\StreamHandler->createResource(Object(Closure))
#2 /pwd/src/Handler/StreamHandler.php(58): GuzzleHttp\Handler\StreamHandler->createStream(Object(GuzzleHttp\Psr7\Request), Array)
#3 /pwd/src/Handler/Proxy.php(48): GuzzleHttp\Handler\StreamHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 /pwd/src/PrepareBodyMiddleware.php(35): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#5 /pwd/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#6 /pwd/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#7 /pwd/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#8 /pwd/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#9 /pwd/src/Client.php(331): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#10 /pwd/src/Client.php(107): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
#11 /pwd/src/Client.php(123): GuzzleHttp\Client->sendAsync(Object(GuzzleHttp\Psr7\Request), Array)
#12 /pwd/test.php(32): GuzzleHttp\Client->send(Object(GuzzleHttp\Psr7\Request), Array)
#13 {main}

Next GuzzleHttp\Exception\ConnectException: Connection refused for URI http://www.example.com in /pwd/src/Handler/StreamHandler.php:72
Stack trace:
#0 /pwd/src/Handler/Proxy.php(48): GuzzleHttp\Handler\StreamHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#1 /pwd/src/PrepareBodyMiddleware.php(35): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#2 /pwd/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#3 /pwd/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#4 /pwd/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#5 /pwd/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#6 /pwd/src/Client.php(331): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#7 /pwd/src/Client.php(107): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
#8 /pwd/src/Client.php(123): GuzzleHttp\Client->sendAsync(Object(GuzzleHttp\Psr7\Request), Array)
#9 /pwd/test.php(32): GuzzleHttp\Client->send(Object(GuzzleHttp\Psr7\Request), Array)
#10 {main}

With tcp://127.0.0.1:8888

root@d96cb194032e:/pwd# HTTP_PROXY=tcp://127.0.0.1:8888 php test.php
####################
Stream: false
####################
GuzzleHttp\Exception\ConnectException: cURL error 7: Unsupported proxy scheme for 'tcp://127.0.0.1:8888' (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://www.example.com in /pwd/src/Handler/CurlFactory.php:210
Stack trace:
#0 /pwd/src/Handler/CurlFactory.php(158): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 /pwd/src/Handler/CurlFactory.php(110): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 /pwd/src/Handler/CurlHandler.php(47): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 /pwd/src/Handler/Proxy.php(28): GuzzleHttp\Handler\CurlHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 /pwd/src/Handler/Proxy.php(48): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#5 /pwd/src/PrepareBodyMiddleware.php(35): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#6 /pwd/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#7 /pwd/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#8 /pwd/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#9 /pwd/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#10 /pwd/src/Client.php(331): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#11 /pwd/src/Client.php(107): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
#12 /pwd/src/Client.php(123): GuzzleHttp\Client->sendAsync(Object(GuzzleHttp\Psr7\Request), Array)
#13 /pwd/test.php(17): GuzzleHttp\Client->send(Object(GuzzleHttp\Psr7\Request), Array)
#14 {main}

####################
Stream: true
####################
/pwd/test.php:34:
string(100) "<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <m"

Possible Solution

  1. The proxy syntax should be normalized. The http://<host>:<port> one from cURL probably is the canonical one.
  2. cURL should support streaming responses.

Additional context

This is problematic for my use case, because I provide a factory that returns Guzzle clients that are readily configured to use a proxy. This factory cannot know whether the user of this client will request a streaming response or not. Streaming responses might be required to properly consume only the first few bytes of a response for URL unfurling if the remote end might be an infinite stream (e.g. a web radio).

@TimWolla
Copy link
Contributor Author

TimWolla commented Feb 1, 2021

This issue probably is a duplicate of #2616. But that one is marked stale, without any responses and I believe it lacks some detail I was able to provide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant