1

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.

antonku
  • 7,377
  • 2
  • 15
  • 21
egorovd
  • 23
  • 1
  • 5
  • Did you search for the error (_"Error: socket hang up"_) on SO? There's at least this question with a bunch of possible sources for that error: [NodeJS - What does "socket hang up" actually mean?](https://stackoverflow.com/questions/16995184/nodejs-what-does-socket-hang-up-actually-mean) – Andreas Sep 17 '21 at 08:59
  • Yes, of course I did. And I know what this error means. The question is why such an error occurs in "almost" identical cases. – egorovd Sep 17 '21 at 09:07

1 Answers1

1

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

antonku
  • 7,377
  • 2
  • 15
  • 21