Search code examples
javascriptnode.jsserverhttp-posthttp-status-codes

How to handle client POST body request flow using Expect: 100-continue header?


I am an impatient learner

I'm looking for information on how to control data flow between client and server in this way:

what I want is, the client sends a POST request, together with an Expect: 100-continue header, then the server processes the headers and validates session information, if everything is ok the server sends the response status code 100 and finally the client sends the body of the request.

my doubts are not about the validation of the headers but about how to regulate the dataflow of the client request POST body to server, if validation result is not the expected reject request and respond client request error status

if is there any way to do this, how to do it correctly? I don't speak english natively apologies for any mistake thanks for any help.


Solution

  • Here an example with node 12:

    // server.js
    const http = require('http')
    
    // This is executed only when the client send a request without the `Expect` header or when we run `server.emit('request', req, res)`
    const server = http.createServer((req, res) => {
      console.log('Handler')
    
      var received = 0
      req.on('data', (chunk) => { received += chunk.length })
      req.on('end', () => {
        res.writeHead(200, { 'Content-Type': 'text/plain' })
        res.write('Received ' + received)
        res.end()
      })
    })
    
    // this is emitted whenever the client send the `Expect` header
    server.on('checkContinue', (req, res) => {
      console.log('checkContinue')
      // do validation
      if (Math.random() <= 0.4) { // lucky
        res.writeHead(400, { 'Content-Type': 'text/plain' })
        res.end('oooops')
      } else {
        res.writeContinue()
        server.emit('request', req, res)
      }
    })
    
    server.listen(3000, '127.0.0.1', () => {
      const address = server.address().address
      const port = server.address().port
      console.log(`Started http://${address}:${port}`)
    })
    
    

    The client

    // client.js
    var http = require('http')
    
    var options = {
      host: 'localhost',
      port: 3000,
      path: '/',
      method: 'POST',
      headers: { Expect: '100-continue' }
    }
    
    const req = http.request(options, (response) => {
      var str = ''
      response.on('data', function (chunk) {
        str += chunk
      })
    
      response.on('end', function () {
        console.log('End: ' + str)
      })
    })
    
    // event received when the server executes `res.writeContinue()`
    req.on('continue', function () {
      console.log('continue')
      req.write('hello'.repeat(10000))
      req.end()
    })