stream#Duplex TypeScript Examples
The following examples show how to use
stream#Duplex.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: http-proxy-server.ts From shadowsocks-electron with GNU General Public License v3.0 | 6 votes |
/**
* connect [HTTP CONNECT method for https proxy]
* @author nojsja
* @param {http.IncomingMessage} request [request]
* @param {Duplex} cSocket [cSocket]
* @param {Buffer} head [head]
* @return {void}
*/
private connect = (request: http.IncomingMessage, cSocket: Duplex, head: Buffer) => {
const u = url.parse('http://' + request.url)
console.log('connect: ', request.url);
const { agentConf } = this;
const options = {
command: 'connect',
proxy: agentConf,
target: { host: u.hostname, port: u.port },
};
// connect tcp tunnel between https-client and socks5-client by proxy-server.
// when tcp tunnel established, the tunnel let data-pack pass from https-client to target-server with socks5 proxy.
// the entire process: https-client <--(tcp)--> sockets-client <--(tcp)--> sockets-server <--(tcp)--> https-server
socks.createConnection(options, (error: Error | null, pSocket: Duplex) => {
if (error) {
cSocket.write(`HTTP/${request.httpVersion} 500 Connection error\r\n\r\n`);
return;
}
pSocket.pipe(cSocket);
cSocket.pipe(pSocket);
pSocket.write(head);
cSocket.write(`HTTP/${request.httpVersion} 200 Connection established\r\n\r\n`)
pSocket.resume();
});
}
Example #2
Source File: stream.spec.ts From kassette with MIT License | 5 votes |
describe('stream', () => {
describe('fetchContent', () => {
it('should handle stream-like objects', () => {
class MyStream {
private _onData: (chunk: Buffer) => {};
private _onEnd: () => {};
on(eventName: string, callback: any) {
if (eventName === 'data') {
this._onData = callback;
} else if (eventName === 'end') {
this._onEnd = callback;
}
}
private _pushData(chunk: string) {
this._onData(Buffer.from(chunk));
}
private _end() {
this._onEnd();
}
start() {
this._pushData('hel');
this._pushData('lo');
this._end();
}
}
const stream = new MyStream();
const promise = readAll(stream).then((result) => {
expect(result.toString()).toEqual('hello');
});
stream.start();
return promise;
});
it('should handle Node.js streams', () => {
let content = '';
const stream = new Duplex({
read(size: number) {
this.push(content.slice(0, size));
content = content.slice(size);
if (content === '') {
this.push(null);
}
},
write(chunk: any, _encoding: string, callback: Function) {
content += chunk;
callback();
},
});
const promise = readAll(stream).then((result) => {
expect(result.toString()).toEqual('hello');
});
stream.write('hel');
stream.end('lo');
return promise;
});
});
});
Example #3
Source File: index.ts From discord-ytdl-core with Apache License 2.0 | 5 votes |
arbitraryStream = (
stream: string | Readable | Duplex,
options?: StreamOptions
) => {
if (!stream) {
throw new Error('No stream source provided');
}
options ??= {};
let FFmpegArgs: string[];
if (typeof stream === 'string') {
FFmpegArgs = [
'-reconnect',
'1',
'-reconnect_streamed',
'1',
'-reconnect_delay_max',
'5',
'-i',
stream,
'-analyzeduration',
'0',
'-loglevel',
'0',
'-f',
`${typeof options.fmt === 'string' ? options.fmt : 's16le'}`,
'-ar',
'48000',
'-ac',
'2',
];
} else {
FFmpegArgs = [
'-analyzeduration',
'0',
'-loglevel',
'0',
'-f',
`${typeof options.fmt === 'string' ? options.fmt : 's16le'}`,
'-ar',
'48000',
'-ac',
'2',
];
}
if (!isNaN(options.seek)) {
FFmpegArgs.unshift('-ss', options.seek.toString());
}
if (Array.isArray(options.encoderArgs)) {
FFmpegArgs = FFmpegArgs.concat(options.encoderArgs);
}
let transcoder = new FFmpeg({
args: FFmpegArgs,
});
if (typeof stream !== 'string') {
transcoder = stream.pipe(transcoder);
stream.on('error', () => transcoder.destroy());
}
if (options && !options.opusEncoded) {
transcoder.on('close', () => transcoder.destroy());
return transcoder;
}
const opus = new Opus.Encoder({
rate: 48000,
channels: 2,
frameSize: 960,
});
const outputStream = transcoder.pipe(opus);
outputStream.on('close', () => {
transcoder.destroy();
opus.destroy();
});
return outputStream;
}
Example #4
Source File: context.ts From flatend with MIT License | 4 votes |
export class Context extends Duplex {
_provider: Provider;
_stream: Stream;
_headersWritten = false;
_headers: { [key: string]: string } = {};
headers: { [key: string]: string };
get id(): ID {
return this._provider.id!;
}
constructor(
provider: Provider,
stream: Stream,
headers: { [key: string]: string }
) {
super();
this._provider = provider;
this._stream = stream;
this.headers = headers;
// pipe stream body to context
setImmediate(async () => {
for await (const frame of this._stream.body) {
this.push(frame);
}
this.push(null);
});
// write stream eof when stream writable is closed
setImmediate(async () => {
await util.promisify(finished)(this, { readable: false });
await this._writeHeader();
const payload = new DataPacket(this._stream.id, Buffer.of()).encode();
await this._provider.write(
this._provider.rpc.message(
0,
Buffer.concat([Buffer.of(Opcode.Data), payload])
)
);
});
}
header(key: string, val: string): Context {
this._headers[key] = val;
return this;
}
send(data: string | Buffer | Uint8Array) {
this.write(data);
if (!this.writableEnded) this.end();
}
json(data: any) {
this.header("content-type", "application/json");
this.send(JSON.stringify(data));
}
_read(size: number) {
this._stream.body._read(size);
}
async body(opts?: { limit?: number }): Promise<Buffer> {
const limit = opts?.limit ?? 2 ** 16;
let buf = Buffer.of();
for await (const chunk of this) {
buf = Buffer.concat([buf, chunk]);
if (buf.byteLength > limit) {
throw new Error(
`Exceeded max allowed body size limit of ${limit} byte(s).`
);
}
}
return buf;
}
async _writeHeader() {
if (!this._headersWritten) {
this._headersWritten = true;
const payload = new ServiceResponsePacket(
this._stream.id,
true,
this._headers
).encode();
await this._provider.write(
this._provider.rpc.message(
0,
Buffer.concat([Buffer.of(Opcode.ServiceResponse), payload])
)
);
}
}
_write(
chunk: any,
encoding: BufferEncoding,
callback: (error?: Error | null) => void
) {
const write = async () => {
await this._writeHeader();
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);
for (const chunk of chunkBuffer(buf, STREAM_CHUNK_SIZE)) {
const payload = new DataPacket(this._stream.id, chunk).encode();
await this._provider.write(
this._provider.rpc.message(
0,
Buffer.concat([Buffer.of(Opcode.Data), payload])
)
);
}
};
write()
.then(() => callback())
.catch((error) => callback(error));
}
}