h2non / rocky

Full-featured, middleware-oriented, programmatic HTTP and WebSocket proxy for node.js (deprecated)
MIT License
371 stars 24 forks source link

Weird crash with retry #88

Closed kacperzuk closed 8 years ago

kacperzuk commented 8 years ago

I'm not sure how to describe that, so here's a test case:

const http = require('http')
const proxy = require('rocky')()

proxy
  .get('/*')
  .forward('http://127.0.0.1:3001')
  .retry({})

proxy.listen(3000)

http.createServer(function (req, res) {
  res.writeHead(500)
  res.write("test");
  res.end()
}).listen(3001)

// Test requests
http.get('http://localhost:3000', function (res) {
  console.log('Response from target server:', res.statusCode)
})

I get this error when running it:

_http_outgoing.js:136
      this.outputSize += this._header.length;
                                     ^

TypeError: Cannot read property 'length' of null
    at ServerResponse.OutgoingMessage._send (_http_outgoing.js:136:38)
    at ServerResponse.OutgoingMessage.write (_http_outgoing.js:474:16)
    at IncomingMessage.ondata (_stream_readable.js:529:20)
    at emitOne (events.js:78:13)
    at IncomingMessage.emit (events.js:170:7)
    at IncomingMessage.Readable.read (_stream_readable.js:361:10)
    at flow (_stream_readable.js:744:26)
    at resume_ (_stream_readable.js:724:3)
    at nextTickCallbackWith2Args (node.js:455:9)
    at process._tickCallback (node.js:369:17)

What is interesting, is that it stops crashing if I only remove line res.write("test").

Is there something I'm doing wrong?

h2non commented 8 years ago

Will take a look. Thanks for reporting.

h2non commented 8 years ago

I've fixed an with retry logic. Update rocky to v0.4.10 and try with the following code:

const http = require('http')
const proxy = require('rocky')()

proxy
  .get('/*')
  .forward('http://127.0.0.1:3001')
  .retry({})
  .on('proxy:retry', function (err, req) {
    console.log('Retry request...')
  })

proxy.listen(3000)

var calls = 0
http.createServer(function (req, res) {
  calls += 1
  if (calls === 4) {
    return res.end('success')
  }

  res.writeHead(500)
  res.write('error')
  res.end()
}).listen(3001)

// Test requests
http.get('http://localhost:3000', function (res) {
  console.log('Response from target server:', res.statusCode)
  res.on('data', function (chunk) {
    console.log('Data:', chunk)
  })
})
kacperzuk commented 8 years ago

Everything works ok now, thank you :)