php / php-src

The PHP Interpreter
https://www.php.net
Other
38.02k stars 7.73k forks source link

PHP 8.1.28 curl_exec crash with no error on first request after second request is made (fast F5) #14308

Closed thundor closed 2 months ago

thundor commented 4 months ago

Description

The curl_exec crashes (maybe is aborted) on a first request after another (almost instantaneous) request has been done. The following code must be ran twice in the same browser window.

SO: this script must be ran TWICE fast

$url = 'https://url-to-a-big-file';
$hash = md5(microtime(true));
register_shutdown_function(function() use ($hash){
    file_put_contents(DIR_LOGS . 'testlock.log', $hash . ' - ' . __LINE__ . print_r(error_get_last(),true) . PHP_EOL, FILE_APPEND);
});

// here i have some database checks, i'll just use sleep
sleep(1);

$ch = curl_init($url);
file_put_contents(DIR_LOGS . 'testlock.log', ' - ' . $hash . ' ' . __LINE__ . PHP_EOL, FILE_APPEND);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FILE, $fp);
file_put_contents(DIR_LOGS . 'testlock.log', ' - ' . $hash . ' ' . __LINE__ . PHP_EOL, FILE_APPEND);
curl_exec($ch);
file_put_contents(DIR_LOGS . 'testlock.log', ' - ' . $hash . ' ' . __LINE__ . PHP_EOL, FILE_APPEND); // NOT REACHED! No error
<?php

Resulted in this output:

the DIR_LOGS . 'testlock.log' contains both $hash-es with no errors reported. 
The first hash does not contain the last file_put_contents.

But I expected this output instead:

The first request should have been completed successfully 
or
the DIR_LOGS . 'testlock.log' should contain a fatal error of some kind.

PHP Version

PHP 8.1.28

Operating System

No response

nielsdos commented 4 months ago

I'm having trouble to replicate this. I don't think there's a crash here, and I don't think curl is to blame. I think the two requests are trying to append to the same file at the same time. This is bound to cause problems. You can validate whether this is the case by creating a file with the hash as the filename. If two files exists, one for each request, you know that the curl code did finish and it was a race condition between writing to the same file. If only one file exists, there's a bug in PHP.

thundor commented 4 months ago

I added the file_put_contents just to identify the stopping point. I tried to minimize the code as the relevancy as much as I could. In my script, the second request i don't allow it to make the curl request. My log shows:

2024-05-23 19:26:34 c052862e3b0a79bf2e85584d87fe328b 2
 c052862e3b0a79bf2e85584d87fe328b - 3544
 - 3447
 - 479
 - 488
 - 490
 - 495
 - 502
 - 518
 - 523
 - 526
 - 528
 - 535
2024-05-23 19:26:34 - 3510 
2024-05-23 19:26:34 1ecfa999f2e74111e326ec0c771de847 0
DONE
2024-05-23 19:26:34 - 3510 

c052862e3b0a79bf2e85584d87fe328b and 1ecfa999f2e74111e326ec0c771de847 are the hashes for the 2 requests On first access i lock the request in the database so it is not allowed to perform a second time until unlocked. 2024-05-23 19:26:34 c052862e3b0a79bf2e85584d87fe328b 2 (2 means number of affected rows in the database and allows to make the curl request functionality) 2024-05-23 19:26:34 1ecfa999f2e74111e326ec0c771de847 0 (0 means number of affected rows in the database and stops the functionality)

535 is the line containing the file_put_contents before curl_exec 3510 is the line in the register_shutdown_function function

I am open to suggestions on how to demonstrate this further if necessary

thundor commented 4 months ago

I attached a tested script and its output. curl_problem.zip

nielsdos commented 4 months ago

Thanks for the standalone reproducer!

I'm not seeing curl crashes on my end. If I press F5 fast twice then the first request still completes and I see both lines 127 & 129 in the output log. I tried this multiple times but no dice.

What version of libcurl are you using and which SAPI (e.g. fpm, apache, ...) are using?

thundor commented 4 months ago

Attached php_info for the server where i am still able to reproduce: PHP 8.1.28 - phpinfo().zip

Informative only: Please note that on OTHER server i was also UNABLE to reproduce. Attaching php_info for this server where all is working fine: PHP 8.1.2-1ubuntu2.17 - phpinfo().zip

nielsdos commented 4 months ago

I don't really have a clue unfortunately. I can see the curl and openssl versions are different though, so I wonder if that's related to the issue somehow... It wouldn't be the first time that a user experiences an upstream library issue.

cmb69 commented 2 months ago

Hmm, maybe that is a LiteSpeed API or server issue? Anyhow, if nobody can reproduce this with any of the actively supported PHP versions, that would be a WONTFIX.

github-actions[bot] commented 2 months ago

No feedback was provided. The issue is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so. Thank you.