node-libcurl
node-libcurl copied to clipboard
Curl Easy segmentation fault with requests to external site
Curl Easy segmentation fault with requests to external site
Thank you for this library :). Please let me know if any other information would help.
Describe the bug
I get a segmentation fault when I try to send a request using Curl Easy to an external site such as
- https//www.google.com.au
There is no issue with localhost/127.0.0.1.
I discovered this when trying to send requests using sync-request-curl in the specific environment with the following inside a Dockerfile:
FROM php:8.1.8-fpm-alpine
RUN apk add --update npm=7.17.0-r0 --repository=http://dl-cdn.alpinelinux.org/alpine/v3.14/main
It seems to work with no issues locally and with other base images, e.g. node:18-alpine
.
This was just an environment that was configured at my workplace.
To Reproduce
Code that causes segfault (click to view)
import { Curl, Easy } from 'node-libcurl';
/*
* Simplified from [sync-request-curl](https://github.com/nktnet1/sync-request-curl)
*/
const request = (method: string, url: string) => {
const curl = new Easy();
curl.setOpt(Curl.option.CUSTOMREQUEST, method);
curl.setOpt(Curl.option.URL, url);
curl.perform();
const statusCode = curl.getInfo('RESPONSE_CODE').data as number;
curl.close();
return { statusCode };
};
const localUrl = 'http://localhost:3000';
console.log(`Sending GET request to '${localUrl}' (should get 200)`)
const response = request('GET', localUrl);
console.log('Status Code:', response.statusCode);
console.log();
const externalUrl = 'https://www.google.com'
console.log(`Sending GET request to '${externalUrl}' (gets SEGFAULT)`)
const segfault = request('GET', externalUrl);
console.log('Status Code:', segfault.statusCode);
Docker image here. Full repository here.
Have the local server running on one terminal
$ npm start
Then in another terminal run src/request.ts
with
$ npm test
> test
> ts-node src/request
Sending GET request to 'http://localhost:3000' (should get 200)
Status Code: 200
Sending GET request to 'https://www.google.com' (gets SEGFAULT)
Segmentation fault
Version information
Node Libcurl Version
3.0.0
Curl Version:
7.83.1
node -e "console.log(require('node-libcurl').Curl.getVersionInfoString())" (click to view)
$ node -e "console.log(require('node-libcurl').Curl.getVersionInfoString())"
Version: libcurl/7.86.0 OpenSSL/not available zlib/1.2.12 brotli/1.0.9 zstd/1.4.9 libidn2/2.1.1 libssh2/1.10.0 nghttp2/1.47.0
Protocols: dict, file, ftp, ftps, gopher, gophers, http, https, imap, imaps, ldap, ldaps, mqtt, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
Features: AsynchDNS, Debug, TrackMemory, IDN, IPv6, Largefile, NTLM, NTLM_WB, SSL, libz, brotli, TLS-SRP, HTTP2, UnixSockets, HTTPS-proxy, alt-svc
Operating System
Alpine Linux v3.16 x86_64
neofetch output (click to view)
$ neofetch --backend off
root@2a8a6f86b13b
-----------------
OS: Alpine Linux v3.16 x86_64
Host: KVM/QEMU (Standard PC (Q35 + ICH9, 2009) pc-q35-8.0)
Kernel: 5.15.49-linuxkit-pr
Uptime: 7 hours, 32 mins
Packages: 43 (apk)
Shell: ash
CPU: 11th Gen Intel i7-11370H (4) @ 2.995GHz
Memory: 1000MiB / 3774MiB
Node.js Version:
18.9.1
npm version output (click to view)
$ npm version
{
npm: '7.17.0',
node: '18.9.1',
v8: '10.2.154.15-node.12',
uv: '1.44.1',
zlib: '1.2.12',
brotli: '1.0.9',
ares: '1.18.1',
modules: '108',
nghttp2: '1.47.0',
napi: '8',
llhttp: '6.0.10',
openssl: '1.1.1q',
cldr: '41.0',
icu: '71.1',
tz: '2022a',
unicode: '14.0'
}
Additional Context
This may be related to #198.
Same here. Using this package (whether through curly
or new Curl()
) works on a local URL, but causes a Segmentation fault
on an external URL. I'm running Node using docker-compose.
Hey, thanks for the detailed reproduction steps! Right now I am not finding time to look into this, I know it is usually not feasible, but if possible try using a non-alpine image to see if the issue persists.
If this can help people about this issue, this is related to openssl version in alpine (3.19 and lower) after analysis deeper the issue (I have the same in my usecase) with segfault handler trapping, I can see this kind of trace
[pc=0x00007f7011cd8d60, sp=0x00007ffe961f1d00] in killpg+0x40
[pc=0x00007f70101ac2a3, sp=0x00007ffe961f2290] in SSL_get_peer_certificate+0x13
[pc=0x00007f7010329027, sp=0x00007ffe961f22a0] in curl_easy_option_next+0x5b17
[pc=0x00007f701032cfee, sp=0x00007ffe961f2cc0] in curl_easy_option_next+0x9ade
[pc=0x00007f701032dff1, sp=0x00007ffe961f2d20] in curl_easy_option_next+0xaae1
[pc=0x00007f70102ec142, sp=0x00007ffe961f2d50] in curl_getenv+0x2ae2
[pc=0x00007f701030303d, sp=0x00007ffe961f2d70] in curl_multi_cleanup+0x74d
[pc=0x00007f7010304522, sp=0x00007ffe961f2de0] in curl_multi_perform+0x312
[pc=0x00007f70103046a4, sp=0x00007ffe961f2f00] in curl_multi_socket_action+0x24
[pc=0x00007f7010383efe, sp=0x00007ffe961f2f20] in NodeLibcurl::Multi::OnSocket(uv_poll_s*, int, int)+0xee
[pc=0x00000000018971bb, sp=0x00007ffe961f3000] in uv__io_poll+0x4db
[pc=0x0000000001883517, sp=0x00007ffe961f6d70] in uv_run+0x187
I switch to debian 12 image (standard or slim) for testing and this work correctly (without segfault)