-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Support force_ip_resolve in StreamHandler #1659
Conversation
9e03f48
to
f2337fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution. I added a few comments, can you please take a look at them?
src/Handler/StreamHandler.php
Outdated
@@ -286,7 +288,7 @@ private function createStream(RequestInterface $request, array $options) | |||
foreach ($options as $key => $value) { | |||
$method = "add_{$key}"; | |||
if (isset($methods[$method])) { | |||
$this->{$method}($request, $context, $value, $params); | |||
$this->{$method}($request, $context, $value, $params, $uri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really necessary to add the URI as a parameter? It's accessible from the request, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but I chose to preserve the original URI in the request in case other callbacks, middleware etc. need it. The modified $url
is not the actual URL being requested but a version where the hostname has been replaced with an IP address, i.e. it lacks information about HTTP virtual host. This version is only used to "trick" fopen() into binding to the proper IP. The virtual host information is sent to the server in the Host
HTTP header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay, you are totally right. For some reasons I thought you are trying to set the host in the original request. Even then, adding the URI to all methods bellow seems to be too much. How about a resolveUri
or resolveAddress
or something similar method? It would make things easier IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/Handler/StreamHandler.php
Outdated
@@ -277,6 +278,7 @@ private function createStream(RequestInterface $request, array $options) | |||
|
|||
$params = []; | |||
$context = $this->getDefaultContext($request, $options); | |||
$uri = $request->getUri()->withFragment(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this better than the original code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact it's not a good idea IMO as the reference for this object will not be the same as you expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment below on why I created a separate $uri
variable outside the callback.
src/Handler/StreamHandler.php
Outdated
@@ -350,7 +352,7 @@ private function getDefaultContext(RequestInterface $request) | |||
return $context; | |||
} | |||
|
|||
private function add_proxy(RequestInterface $request, &$options, $value, &$params) | |||
private function add_proxy(RequestInterface $request, &$options, $value, &$params, UriInterface &$uri) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Objects are passed by reference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but URIs are immutable, so I have to change the value by reference.
src/Handler/StreamHandler.php
Outdated
if (!isset($records[0]['ip'])) { | ||
throw new ConnectException("Could not resolve IPv4 address for host '{$uri->getHost()}'", $request); | ||
} | ||
$uri = $uri->withHost($records[0]['ip']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly this is also not going to work as you expect. HTTP Messages are immutable, which means if you "modify" one them you will get a new object. The new URI will not be present in the request object. What you can do is saving the resolved IP address in the options array and passing it to the URI, then the URI to the request somewhere in the above code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. I am not modifying the HTTP message here, only $uri that is passed by reference.
If you have IPv6 connectivity, you can test the code using this script:
|
f2337fe
to
e980738
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please also add StreamHandler to the list of supportet handlers in the note added in #1608?
src/Handler/StreamHandler.php
Outdated
if ('v4' === $options['force_ip_resolve']) { | ||
$records = dns_get_record($uri->getHost(), DNS_A); | ||
if (!isset($records[0]['ip'])) { | ||
throw new ConnectException("Could not resolve IPv4 address for host '{$uri->getHost()}'", $request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please use sprintf instead? I am not really fan of this kind of resolution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/Handler/StreamHandler.php
Outdated
$this->lastHeaders = $http_response_header; | ||
return $resource; | ||
} | ||
); | ||
} | ||
|
||
private function resolveUri(UriInterface $uri, array $options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe call it resolveIp or resolveAddress? Since that's what we do here, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I chose the name resolveHost
(we are resolving the hostname to an IP address).
Rename resolveUri() to resolveHost() Check that URI host is not already an IP Pass $request to ConnectException
8b0fa76
to
eb79b37
Compare
Thanks for your work and patience. 6.3 is on it's way |
The option
force_ip_resolve
that was added in #1608 is only supported forCurlHandler
.This patch adds support for
force_ip_resolve
toStreamHandler
.