php / php/frankenphp

Concurrent file uploads hang when using HTTPS

Open
#1,074 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Go
Stars
11.3k
Forks
488
Avg merge
4d 10h
Merged PRs (30d)
11

Description

What happened?

I'm experiencing an issue where concurrent file uploads hang indefinitely when querying the site via https.
Below is a super basic demonstration.
It occurs with as few as 20 files depending on the machine and build type.
Increasing the max_requests or the number of threads doesn't seem to help.
It doesn't happen without https, or on a regular apache web server with https.
Most of the time no error is shown in the logs, but I did get a go panic output once, not sure if it's related to this issue though...

Build Type

I tried both the docker version v1.2.5 (dunglas/frankenphp:latest) and the official static build with the same result, in worker mode (with octane) or not.

Operating system

Same problem both on my machine (WSL Ubuntu-22.04 x86_64) in local (PHP 8.3.12), and on a VPS running on Debian 12 (amd64, PHP 8.2.23) with a public domain.

PHP Page code example

<?php
if(isset($_FILES) && count($_FILES) > 0){
    echo json_encode(['status' => 'success']);
    exit;
}
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>


        <input multiple type="file" accept=".pdf"/>
        <button onclick="sendToServer()">Post files to server</button>

        <script>

           async function sendToServer() {
               const files = document.querySelector('input[type="file"]').files;
               const promises = [];
               for (let i = 0; i < files.length; i++) {
                   promises.push(postPromise(files[i]));
               }
               await Promise.all(promises);
               alert('All files uploaded');
           }

            function postPromise(file){
                return new Promise( function(resolve, reject){
                    const fd = new FormData();
                    fd.append('file', file);
                    fetch('savefile', {
                        method: 'POST',
                        body: fd
                    }).then(response => {
                       resolve(response);
                    }).catch(error => {
                       reject({
                           status: error.status,
                            statusText: error.statusText
                        });
                    });
                });
            }
        </script> 
    </body>
 </html>
Build Type

Custom (tell us more in the description)

Worker Mode

No

Operating System

GNU/Linux

CPU Architecture

x86_64

PHP configuration
PHP Version 8.3.11
Relevant log output
panic: error during PHP script execution
goroutine 67 [running, locked to thread]:
github.com/dunglas/frankenphp.go_handle_request()
        /go/src/app/frankenphp.go:496 +0x2dd

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the hang with the provided PHP upload page and about 20 concurrent HTTPS requests, comparing HTTPS with HTTP and Apache HTTPS. Start at the panic location in frankenphp.go:496 and inspect the relevant request path and logs. Done means concurrent uploads complete reliably without hanging or triggering the reported Go panic across the described build modes.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go, php
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.