Skip to content

[bug][v6.0] Can not possible process "big" (>1Mb) files to HTTP Server with single_tread #5676

@mrVrAlex

Description

@mrVrAlex

To reproduce use script:

$http = new Swoole\Http\Server('0.0.0.0', 9501, SWOOLE_PROCESS);
$http->set([
               'single_thread' => true, // Need true with SWOOLE_PROCESS + PHP ZTS
               'worker_num'    => 1,
               'dispatch_mode' => 10,
               'package_max_length' => 134217728, // 128Mb
]);
$http->on('Request', function ($request, $response) {
    var_dump($request->files);
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end('<h1>Hello, Swoole. #' . rand(1000, 9999) . '</h1>');
});
$http->start();

Then make request like this with file bigger then 1Mb (I think any bigger then 65Kb because it seams it chunk size):

curl -X 'POST'   'http://localhost:9501/'   -H 'accept: application/json'  -H 'Content-Type: multipart/form-data'   -F 'file=@too-big-file.csv;type=text/csv'

And you see in console warning:

[2025-01-26 21:23:24 #4040616.0]        WARNING ReactorEpoll::add(): failed to add events[fd=6#0, type=3, events=1024], Error: File exists[17]

Request will end by curl timeout (so swoole never return response)
And then when stop server (kill PID) you can see:

[2025-01-26 21:24:41 *4040618.0]        WARNING Server::call_worker_stop_callback() (ERRNO 9103): unprocessed data in the worker process buffer

I tried it on many env - reproducable anywhere (PHP ZTS and not, iouring and not).
With 'single_thread' => false - all works as expected.

PHP 8.4.3 (cli) (built: Jan 19 2025 14:20:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.3, Copyright (c), by Zend Technologies
Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 6.0.0
Built => Dec 17 2024 05:36:57
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.0.13 30 Jan 2024
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
c-ares => 1.27.0
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
coroutine_pgsql => enabled
coroutine_sqlite => enabled
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608

In tracing mode see:

Server::accept_connection(:168): [Master] Accept new connection. maxfd=9|minfd=9|reactor_id=0|conn=12
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   ReactorEpoll::add(:107): add events[fd=12#0, type=0, events=512]
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Timer::select(:204): timer msec=103205, round=156
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65536/65536 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Port_onRead_http(:507): content-length=1096625, keep-alive=0, chunked=0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 94848/1032016 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 363904/937168 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 196608/573264 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv -1/376656 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Timer::select(:204): timer msec=103206, round=157
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65536/376656 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65536/311120 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65483/245584 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 53/180101 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65536/180048 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 65536/114512 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Socket::recv(:734): recv 48975/48976 bytes, errno=11
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Server::dispatch_task(:871): dispatch task, size=1097551 bytes
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Server::dispatch_task(:879): session_id=14, len=1097551, qb=1097551
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     WARNING ReactorEpoll::add(): failed to add events[fd=7#0, type=3, events=1024], Error: File exists[17]
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=1|size=40|chunk_len=0|chunk=0x77bcb3a6f100
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=1|size=65464|chunk_len=40|chunk=0x77bcb3a6f100
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=2|size=40|chunk_len=0|chunk=0x77bcb3a6f1f0
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=2|size=65464|chunk_len=40|chunk=0x77bcb3a6f1f0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=3|size=40|chunk_len=0|chunk=0x77bcb3a6f2b0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=3|size=65464|chunk_len=40|chunk=0x77bcb3a6f2b0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=4|size=40|chunk_len=0|chunk=0x77bcb3a6efe0
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=4|size=65464|chunk_len=40|chunk=0x77bcb3a6efe0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=5|size=40|chunk_len=0|chunk=0x77bcb3a6f0a0
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   MessageBus::read(:130): append msgid=27, buffer=0x77bcadf5a800, n=65504
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   Timer::select(:204): timer msec=1361, round=10317
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=5|size=65464|chunk_len=40|chunk=0x77bcb3a6f0a0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=6|size=40|chunk_len=0|chunk=0x77bcb3a6f220
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=6|size=65464|chunk_len=40|chunk=0x77bcb3a6f220
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=7|size=40|chunk_len=0|chunk=0x77bcb3a6efb0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=7|size=65464|chunk_len=40|chunk=0x77bcb3a6efb0
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=65464
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=8|size=40|chunk_len=0|chunk=0x77bcb3a6f160
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=8|size=65464|chunk_len=40|chunk=0x77bcb3a6f160
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   MessageBus::write(:258): finish, type=0|len=50127
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=9|size=40|chunk_len=0|chunk=0x77bcb3a6ef80
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Buffer::append(:128): chunk_n=9|size=50127|chunk_len=40|chunk=0x77bcb3a6ef80

I think what problem somewhere in MessageBus & Buffer, because when file is small then after Server::dispatch_task I see accept event and received http request:

application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Server::dispatch_task(:879): session_id=13, len=1118, qb=1118
application-1  | [2025-01-25 22:29:16 #7.0]     TRACE   Timer::select(:204): timer msec=103193, round=153
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   Server::worker_accept_event(:132): [Worker] session_id=13, len=1118, qb=0
application-1  | [2025-01-25 22:29:16 *13.0]    TRACE   php_swoole_http_server_onReceive(:87): http request from 13 with 1118 bytes: <<EOF

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions