Changing a node.js stream in the ondata event

I am trying to edit a node.js http stream before sending it to the parser. I have implemented the following code

//catch any connection event to this server
server.on('secureConnection', function (stream) {
  //create a new buffer to hold what we are receiving in this stream
  var receiveBuffer = new Buffer(0);
  //store a link to the original ondata function so we can call it and restore it
  originalOnDataFunction = stream.ondata;
  //declare a new ondata function for this stream
  stream.ondata = function (d, start, end) {
    //record what we have received 
    receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]);
    //if what we have received is greater than 4 (i.e. we have at least got a GET request)
    //then make changes
    if (receiveBuffer.length >= 4) {
      //reset the streams ondata function to the original
      //this is all we want to edit for this connection
      stream.ondata = originalOnDataFunction;
      //if the first 11 characters of the buffer are 'MKCALENDAR ' then make a change
      if (receiveBuffer.toString('ascii', 0, 11) === 'MKCALENDAR ') {
        //I change this to MKCOL /MKCALENDAR<rest of buffer> as this will work with the node.js http parser
        //and then I can check on the other side for a MKCOL method with /MKCALENDAR as the start of the url and 
        //know that it was a MKCALENDAR method
        var rewrittenBuffer = Buffer.concat([new Buffer('MKCOL /MKCALENDAR', 'ascii'), receiveBuffer.slice(11)]);
        //now call the original ondata function with this new buffer
        stream.ondata.apply(this, [rewrittenBuffer, 0, rewrittenBuffer.length]);
      } else {
        //no change needed just call the original ondata function with this buffer
        stream.ondata.apply(this, [receiveBuffer, 0, receiveBuffer.length]);
      }
    }
  }
});

which I got from an answer here Overriding Node.js HTTP parser

The above code seems to work about 95% of the time. However, it keeps dropping requests that then just timeout. I cannot see how or where it is dropping them. Can anyone help.

Thanks,

Mark

Note the on secureConnection is coming from a node.js https.createServer( call

Are you sure you want

if (receiveBuffer.length >= 4)

If the first buffer is a partial MKCALENDAR with at least the first four bytes, the code above won't do the translation to MKCOL.

Jonathan the first packet in seems to be the all the headers so this line works fine. I did get it working and the problem seemed to be with the .apply statement not always working. The following works fine:

//catch any secure connection event to this server
server.on('secureConnection', function (stream) {
  //create a new buffer to hold what we are receiving in this stream
  var receiveBuffer = new Buffer(0);
  //store a link to the original ondata function so we can call it and restore it
  stream._ondataOld = stream.ondata;
  stream.ondata = function(d,start,end){
    receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]);
    //if what we have received is greater than 4 (i.e. we have at least got a GET request)
    //then make changes
    if (receiveBuffer.length >= 4) {
      //reset the streams ondata function to the original
      //this is all we want to edit for this connection
      stream.ondata = stream._ondataOld;
      //if the first 11 characters of the buffer are 'MKCALENDAR ' then make a change
      if (receiveBuffer.toString('ascii', 0, 11) === 'MKCALENDAR ') {
        //I change this to MKCOL /MKCALENDAR<rest of buffer> as this will work with the node.js http parser
        //and then I can check on the other side for a MKCOL method with /MKCALENDAR as the start of the url and
        //know that it was a MKCALENDAR method
        //this facilitates MKCALENDAR calls on the CALDAV server
        var rewrittenBuffer = Buffer.concat([new Buffer('MKCOL /MKCALENDAR', 'ascii'), receiveBuffer.slice(11)]);
        //console.log(rewrittenBuffer.toString('ascii',0,rewrittenBuffer.length));
        //console.log(rewrittenBuffer.toString('ascii'));
        //now call the original ondata function with this new buffer
        stream.ondata(rewrittenBuffer,0,rewrittenBuffer.length);
      } else {
        //no change needed just call the original ondata function with this buffer
        stream.ondata(d,start,end);
      }
    } else {
      stream.ondata(d,start,end);
    }
  }
});