-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Description
I did this
I'm trying to receive Server-Sent Events using libcurl. I've found CURLOPT_CONNECT_ONLY option which
can be set to '2' and if HTTP or WebSocket are used, libcurl performs the request and reads all response headers before handing over control to the application
but curl_easy_perform()
call blocks while connection alive.
For demonstration, I have attached a simple server and client applications.
demo.zip
The server (Kotlin) sends 5 messages every 3 seconds and terminates the connection.
sse {
repeat(5) {
delay(3.seconds)
send(LocalTime.now().toString())
}
}
The client (C) connects to the server, exchange HTTP headers, report the execution time and should exit without waiting events.
CURL *curl = curl_easy_init();
if (!curl)
goto cleanup;
if (curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080"))
goto cleanup;
if (curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L))
goto cleanup;
time_t start_time = time(NULL);
if (curl_easy_perform(curl))
goto cleanup;
time_t end_time = time(NULL);
double duration = difftime(end_time, start_time);
printf("perform takes %.2f seconds\n", duration);
but outputs
perform takes 15.00 seconds
How-to build & run server:
cd server
gradle build
cd build/distributions
tar -xf server.tar
./server/bin/server
curl -v http://localhost:8080
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8080...
* Connected to localhost (::1) port 8080
* using HTTP/1.x
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.12.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: text/event-stream
< Cache-Control: no-store
< Connection: keep-alive
< X-Accel-Buffering: no
< Transfer-Encoding: chunked
<
data: 22:22:18.489580323
data: 22:22:21.490710433
data: 22:22:24.491684059
data: 22:22:27.492930039
data: 22:22:30.494157034
* Connection #0 to host localhost left intact
I expected the following
No response
curl/libcurl version
curl 8.12.1 (x86_64-pc-linux-gnu) libcurl/8.12.1 OpenSSL/3.4.1 zlib/1.3.1 brotli/1.1.0 zstd/1.5.6 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1 nghttp2/1.64.0 librtmp/2.3 OpenLDAP/2.6.9
Release-Date: 2025-02-13, security patched: 8.12.1-3ubuntu1
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
operating system
Linux lpc 6.14.0-15-generic #15-Ubuntu SMP PREEMPT_DYNAMIC Sun Apr 6 15:05:05 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux