-
Notifications
You must be signed in to change notification settings - Fork 498
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
Prevent cURL transport from leaking on Exception #319
base: develop
Are you sure you want to change the base?
Conversation
Calling Requesting a bad URL, even if it's a mere certificate error, will not call the destructor and eventually
Breaking case: while(true) {
try {
$response = Requests::post('http://localhost:43992', array(), array(), array('transport'=>'Requests_Transport_cURL'));
} catch (Exception $e) {}
} Where http://localhost:43992 is a nonexistent local endpoint (to error out faster). |
Leaks exception for me too: Trying to catch is unsuccessful |
There is one big problem with the fix proposed here: A better fix will be: try
{
$this->process_response($response, $options);
}
finally
{
if (true === $options['blocking'])
{
// Need to remove the $this reference from the curl handle.
// Otherwise Requests_Transport_cURL wont be garbage collected and the curl_close() will never be called.
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
}
} |
As we have now moved to PHP 5.6 as a minimum requirement, it seems to make sense to take a fresh look at the execution flow, and use the |
Note for the next iteration of this PR: For testing the correct functioning of this change, the PHPUnit 9.3+ Also note: tests are only relevant for PHP < 8.0 and should be skipped on PHP 8.0+ as Curl was changed from using resources to using objects. |
9771abb
to
3d91340
Compare
1614444
to
e127137
Compare
Tests are failing because PHP 7 does check for active references to a resource before closing it, even if you explicitly use In our case, the very fact that we want to test whether the resource is closed properly creates a reference to the resource. So while there is no memory leak in the normal code path, there is one in the test - because of the test. The only way I can think of for solving this is by using weak references, but those have only been introduced with PHP 7.2. Options right now:
|
The `CURLOPT_HEADERFUNCTION` and `CURLOPT_WRITEFUNCTION` options are not being reset if a cURL handle error occurs (which throws a `Requests_Exception` and stops execution). The destructor is not called due to lingering instance method callbacks in the two options. Move `CURLOPT_HEADERFUNCTION` and `CURLOPT_WRITEFUNCTION` cleanup before any exceptions can happen.
e127137
to
a154c56
Compare
a154c56
to
dd91131
Compare
81ba36f
to
61b3b14
Compare
Okay, so I have spend some time today trying to create a better/working test for this. Current status can be seen here: https://github.com/WordPress/Requests/tree/319/better-test-attempt-take-two Tentative conclusions:
|
The
CURLOPT_HEADERFUNCTION
andCURLOPT_WRITEFUNCTION
options are notbeing reset if a cURL handle error occurs (which throws a
Requests_Exception
and stops execution). The destructor is not calleddue to lingering instance method callbacks in the two options.
Move
CURLOPT_HEADERFUNCTION
andCURLOPT_WRITEFUNCTION
cleanup beforeany exceptions can happen.