I can't understand how https.get and https.request works.
There is a small example that shows the problem.
There is a code:
#
# r.js
#
import https from 'https'
async function runGetRequest () {
return new Promise((resolve, reject) => {
const req = https.get({
hostname: 'jsonplaceholder.typicode.com',
method: 'GET',
path: '/todos/1'
}, (resp) => {
console.log(`statusCode: ${resp.statusCode}`)
const data = []
resp.on('data', (chunk) => {
data.push(chunk)
})
resp.on('end', () => {
resolve(Buffer.concat(data).toString())
})
resp.on('error', (err) => {
reject(err)
})
}).on('error', (err) => {
reject(err)
}).on('timeout', (err) => {
reject(err)
req.abort()
}).on('uncaughtException', (err) => {
reject(err)
req.abort()
})
})
}
async function runRequest () {
return new Promise((resolve, reject) => {
const req = https.request({
hostname: 'jsonplaceholder.typicode.com',
method: 'GET',
path: '/todos/1'
}, (resp) => {
console.log(`statusCode: ${resp.statusCode}`)
const data = []
resp.on('data', (chunk) => {
data.push(chunk)
})
resp.on('end', () => {
resolve(Buffer.concat(data).toString())
})
resp.on('error', (err) => {
reject(err)
})
}).on('error', (err) => {
reject(err)
}).on('timeout', (err) => {
reject(err)
req.abort()
}).on('uncaughtException', (err) => {
reject(err)
req.abort()
})
})
}
console.log(await runGetRequest())
console.log(await runRequest())
Which runs like this:
node --harmony-top-level-await --es-module-specifier-resolution=node --inspect r.js
In the first case, https.get is used, and in the second, https.request.
The first one works.
In the second, I get an error:
Error: socket hang up
at connResetException (node:internal/errors:691:14)
at TLSSocket.socketOnEnd (node:_http_client:471:23)
at TLSSocket.emit (node:events:406:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ECONNRESET'
}
node --version
v16.9.1
Where is the error in the code?
Thank you.
The difference is that with https.request we have to send the request explicitly by calling req.end()
async function runRequest () {
return new Promise((resolve, reject) => {
const req = https.request({
hostname: 'jsonplaceholder.typicode.com',
method: 'GET',
path: '/todos/1'
}, (resp) => {
console.log(`statusCode: ${resp.statusCode}`)
const data = []
resp.on('data', (chunk) => {
data.push(chunk)
})
resp.on('end', () => {
resolve(Buffer.concat(data).toString())
})
resp.on('error', (err) => {
reject(err)
})
}).on('error', (err) => {
reject(err)
}).on('timeout', (err) => {
reject(err)
req.abort()
}).on('uncaughtException', (err) => {
reject(err)
req.abort()
})
req.end() // < add this call
})
}
https.get makes that call internally:
https://github.com/nodejs/node/blob/55379eb454622d0a0cac2467532579a7ad44ca25/lib/https.js#L388