var Serializer = require('./framer').Serializer; var Deserializer = require('./framer').Deserializer; var Compressor = require('./compressor').Compressor; var Decompressor = require('./compressor').Decompressor; var Connection = require('./connection').Connection; var Duplex = require('stream').Duplex; var Transform = require('stream').Transform;
exports.Endpoint = Endpoint;
// The Endpoint class // ==================
// Public API // ----------
// - **new Endpoint(log, role, settings, filters)**: create a new Endpoint. // // - `log`: bunyan logger of the parent // - `role`: 'CLIENT' or 'SERVER' // - `settings`: initial HTTP/2 settings // - `filters`: a map of functions that filter the traffic between components (for debugging or // intentional failure injection). // // Filter functions get three arguments: // 1. `frame`: the current frame // 2. `forward(frame)`: function that can be used to forward a frame to the next component // 3. `done()`: callback to signal the end of the filter process // // Valid filter names and their position in the stack: // - `beforeSerialization`: after compression, before serialization // - `beforeCompression`: after multiplexing, before compression // - `afterDeserialization`: after deserialization, before decompression // - `afterDecompression`: after decompression, before multiplexing // // * **Event: 'stream' (Stream)**: 'stream' event forwarded from the underlying Connection // // * **Event: 'error' (type)**: signals an error // // * **createStream(): Stream**: initiate a new stream (forwarded to the underlying Connection) // // * **close([error])**: close the connection with an error code
// Constructor // -----------
// The process of initialization: function Endpoint(log, role, settings, filters) {
Duplex.call(this);
// * First part of the handshake process: sending and receiving the client connection header // prelude. assert((role === 'CLIENT') || role === 'SERVER'); if (role === 'CLIENT') { this._writePrelude();
} else { this._readPrelude();
}
// * Initialization of component. This includes the second part of the handshake process: // sending the first SETTINGS frame. This is done by the connection class right after // initialization. this._initializeDataFlow(role, settings, filters || {});
// * Initialization of management code. this._initializeManagement();
var CLIENT_PRELUDE = Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n');
// Writing the client header is simple and synchronous.
Endpoint.prototype._writePrelude = function _writePrelude() { this._log.debug('Sending the client connection header prelude.'); this.push(CLIENT_PRELUDE);
};
// The asynchronous process of reading the client header:
Endpoint.prototype._readPrelude = function _readPrelude() { // * progress in the header is tracker using a `cursor` var cursor = 0;
// * `_write` is temporarily replaced by the comparator function this._write = function _temporalWrite(chunk, encoding, done) { // * which compares the stored header with the current `chunk` byte by byte and emits the // 'error' event if there's a byte that doesn't match var offset = cursor; while(cursor < CLIENT_PRELUDE.length && (cursor - offset) < chunk.length) { if (CLIENT_PRELUDE[cursor] !== chunk[cursor - offset]) { this._log.fatal({ cursor: cursor, offset: offset, chunk: chunk }, 'Client connection header prelude does not match.'); this._error('handshake', 'PROTOCOL_ERROR'); return;
}
cursor += 1;
}
// * if the whole header is over, and there were no error then restore the original `_write` // and call it with the remaining part of the current chunk if (cursor === CLIENT_PRELUDE.length) { this._log.debug('Successfully received the client connection header prelude.'); deletethis._write;
chunk = chunk.slice(cursor - offset); this._write(chunk, encoding, done);
}
};
};
this._serializer = new Serializer(this._log); this._deserializer = new Deserializer(this._log); this._compressor = new Compressor(this._log, compressorRole); this._decompressor = new Decompressor(this._log, decompressorRole); this._connection = new Connection(this._log, firstStreamId, settings);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.