apocas / docker-modem

Docker Remote API network stack driver.
Apache License 2.0
234 stars 112 forks source link

Add the ability to demux a buffer #129

Open Mrono opened 3 years ago

Mrono commented 3 years ago

Currently the docker api returns a multiplexed buffer for log files when follow=false. As it is not a stream the current function of demuxStream doesn't function with it. This is an idea I had in mind for lib/modem.js along side demuxStream

Modem.prototype.demuxBuffer = function(buffer) {
  return new Promise((res, rej) => {
    var nextDataType = null;
    var nextDataLength = null;
    var output = {
      stdout: [],
      stderr: []
    }
    function processData() {
      if (!nextDataType) {
        if (buffer.length >= 8) {
          var header = bufferSlice(8);
          nextDataType = header.readUInt8(0);
          nextDataLength = header.readUInt32BE(4);
          // It's possible we got a "data" that contains multiple messages
          // Process the next one
          processData();
        }
      } else {
        if (buffer.length >= nextDataLength) {
          var content = bufferSlice(nextDataLength);
          if (nextDataType === 1) {
            output.stdout.push(content);
          } else {
            output.stderr.push(content);
          }
          nextDataType = null;
          // It's possible we got a "data" that contains multiple messages
          // Process the next one
          processData();

          // Done processing, send data
          if (buffer.length == 0) {
            res(output);
          }
        }
      }
    }

    function bufferSlice(end) {
      var out = buffer.slice(0, end);
      buffer = Buffer.from(buffer.slice(end, buffer.length));
      return out;
    }

    processData();
  });
}