"use strict";/* * Copyright 2019 gRPC authors.
"use strict"; /* * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ Object.defineProperty(exports, "__esModule", { value: true }); const http2 = require("http2"); const constants_1 = require("./constants"); const metadata_1 = require("./metadata"); const stream_decoder_1 = require("./stream-decoder"); const logging = require("./logging"); const constants_2 = require("./constants"); const TRACER_NAME = 'call_stream'; const { HTTP2_HEADER_STATUS, HTTP2_HEADER_CONTENT_TYPE, NGHTTP2_CANCEL, } = http2.constants; function isInterceptingListener(listener) { return (listener.onReceiveMetadata !== undefined && listener.onReceiveMetadata.length === 1); } exports.isInterceptingListener = isInterceptingListener; class InterceptingListenerImpl { constructor(listener, nextListener) { this.listener = listener; this.nextListener = nextListener; this.processingMessage = false; this.pendingStatus = null; } onReceiveMetadata(metadata) { this.listener.onReceiveMetadata(metadata, metadata => { this.nextListener.onReceiveMetadata(metadata); }); } // tslint:disable-next-line no-any onReceiveMessage(message) { /* If this listener processes messages asynchronously, the last message may * be reordered with respect to the status */ this.processingMessage = true; this.listener.onReceiveMessage(message, msg => { this.processingMessage = false; this.nextListener.onReceiveMessage(msg); if (this.pendingStatus) { this.nextListener.onReceiveStatus(this.pendingStatus); } }); } onReceiveStatus(status) { this.listener.onReceiveStatus(status, processedStatus => { if (this.processingMessage) { this.pendingStatus = processedStatus; } else { this.nextListener.onReceiveStatus(processedStatus); } }); } } exports.InterceptingListenerImpl = InterceptingListenerImpl; class Http2CallStream { constructor(methodName, channel, options, filterStackFactory, channelCallCredentials, callNumber) { this.methodName = methodName; this.channel = channel; this.options = options; this.channelCallCredentials = channelCallCredentials; this.callNumber = callNumber; this.http2Stream = null; this.pendingRead = false; this.isWriteFilterPending = false; this.pendingWrite = null; this.pendingWriteCallback = null; this.writesClosed = false; this.decoder = new stream_decoder_1.StreamDecoder(); this.isReadFilterPending = false; this.canPush = false; /** * Indicates that an 'end' event has come from the http2 stream, so there * will be no more data events. */ this.readsClosed = false; this.statusOutput = false; this.unpushedReadMessages = []; this.unfilteredReadMessages = []; // Status code mapped from :status. To be used if grpc-status is not received this.mappedStatusCode = constants_1.Status.UNKNOWN; // This is populated (non-null) if and only if the call has ended this.finalStatus = null; this.subchannel = null; this.listener = null; this.filterStack = filterStackFactory.createFilter(this); this.credentials = channelCallCredentials; this.disconnectListener = () => { this.endCall({ code: constants_1.Status.UNAVAILABLE, details: 'Connection dropped', metadata: new metadata_1.Metadata(), }); }; } outputStatus() { /* Precondition: this.finalStatus !== null */ if (!this.statusOutput) { this.statusOutput = true; const filteredStatus = this.filterStack.receiveTrailers(this.finalStatus); this.listener.onReceiveStatus(filteredStatus); if (this.subchannel) { this.subchannel.callUnref(); this.subchannel.removeDisconnectListener(this.disconnectListener); } } } trace(text) { logging.trace(constants_2.LogVerbosity.DEBUG, TRACER_NAME, '[' + this.callNumber + '] ' + text); } /** * On first call, emits a 'status' event with the given StatusObject. * Subsequent calls are no-ops. * @param status The status of the call. */ endCall(status) { this.destroyHttp2Stream(); /* If the status is OK and a new status comes in (e.g. from a * deserialization failure), that new status takes priority */ if (this.finalStatus === null || this.finalStatus.code === constants_1.Status.OK) { this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); this.finalStatus = status; this.maybeOutputStatus(); } } maybeOutputStatus() { if (this.finalStatus !== null) { /* The combination check of readsClosed and that the two message buffer * arrays are empty checks that there all incoming data has been fully * processed */ if (this.finalStatus.code !== constants_1.Status.OK || (this.readsClosed && this.unpushedReadMessages.length === 0 && this.unfilteredReadMessages.length === 0 && !this.isReadFilterPending)) { this.outputStatus(); } } } push(message) { this.trace('pushing to reader message of length ' + (message instanceof Buffer ? message.length : null)); this.canPush = false; process.nextTick(() => { this.listener.onReceiveMessage(message); this.maybeOutputStatus(); }); } handleFilterError(error) { this.cancelWithStatus(constants_1.Status.INTERNAL, error.message); } handleFilteredRead(message) { /* If we the call has already ended with an error, we don't want to do * anything with this message. Dropping it on the floor is correct * behavior */ if (this.finalStatus !== null && this.finalStatus.code !== constants_1.Status.OK) { this.maybeOutputStatus(); return; } this.isReadFilterPending = false; if (this.canPush) { this.http2Stream.pause(); this.push(message); } else { this.trace('unpushedReadMessages.push message of length ' + message.length); this.unpushedReadMessages.push(message); } if (this.unfilteredReadMessages.length > 0) { /* nextMessage is guaranteed not to be undefined because unfilteredReadMessages is non-empty */ const nextMessage = this.unfilteredReadMessages.shift(); this.filterReceivedMessage(nextMessage); } } filterReceivedMessage(framedMessage) { /* If we the call has already ended with an error, we don't want to do * anything with this message. Dropping it on the floor is correct * behavior */ if (this.finalStatus !== null && this.finalStatus.code !== constants_1.Status.OK) { this.maybeOutputStatus(); return; } this.trace('filterReceivedMessage of length ' + framedMessage.length); this.isReadFilterPending = true; this.filterStack .receiveMessage(Promise.resolve(framedMessage)) .then(this.handleFilteredRead.bind(this), this.handleFilterError.bind(this)); } tryPush(messageBytes) { if (this.isReadFilterPending) { this.trace('unfilteredReadMessages.push message of length ' + (messageBytes && messageBytes.length)); this.unfilteredReadMessages.push(messageBytes); } else { this.filterReceivedMessage(messageBytes); } } handleTrailers(headers) { let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } this.trace('Received server trailers:\n' + headersString); let metadata; try { metadata = metadata_1.Metadata.fromHttp2Headers(headers); } catch (e) { metadata = new metadata_1.Metadata(); } const metadataMap = metadata.getMap(); let code = this.mappedStatusCode; if (code === constants_1.Status.UNKNOWN && typeof metadataMap['grpc-status'] === 'string') { const receivedStatus = Number(metadataMap['grpc-status']); if (receivedStatus in constants_1.Status) { code = receivedStatus; this.trace('received status code ' + receivedStatus + ' from server'); } metadata.remove('grpc-status'); } let details = ''; if (typeof metadataMap['grpc-message'] === 'string') { details = decodeURI(metadataMap['grpc-message']); metadata.remove('grpc-message'); this.trace('received status details string "' + details + '" from server'); } const status = { code, details, metadata }; let finalStatus; try { // Attempt to assign final status. finalStatus = this.filterStack.receiveTrailers(status); } catch (error) { // This is a no-op if the call was already ended when handling headers. this.endCall({ code: constants_1.Status.INTERNAL, details: 'Failed to process received status', metadata: new metadata_1.Metadata(), }); return; } // This is a no-op if the call was already ended when handling headers. this.endCall(finalStatus); } attachHttp2Stream(stream, subchannel) { if (this.finalStatus !== null) { stream.close(NGHTTP2_CANCEL); } else { this.trace('attachHttp2Stream from subchannel ' + subchannel.getAddress()); this.http2Stream = stream; this.subchannel = subchannel; subchannel.addDisconnectListener(this.disconnectListener); subchannel.callRef(); stream.on('response', (headers, flags) => { let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } this.trace('Received server headers:\n' + headersString); switch (headers[':status']) { // TODO(murgatroid99): handle 100 and 101 case 400:
Je! umeipenda hii post?
Ndio Hapana Save post
Rajabu
Tarehe 2024-05-10 14:53:23 Download PDF
Share On
Facebook
or
Whatsapp
Imesomwa mara 127
Sponsored links
👉1 Madrasa kiganjani
👉2 kitabu cha Simulizi
👉3 Kitabu cha Afya
👉4 Kitau cha Fiqh
HADITHI ZA ALIF LELA U LELA (sehemu ya kwanza): KIAPO CHA SULTAN
Soma Zaidi...
Hadithi ya samaki wa Rangi nne
Posti hii inakwenda kukuletea hadithi za alifu lela ulela Soma Zaidi...
HADITHI YA SAMAKI WA RANGI NNE
Download kitabu Hiki Bofya hapa HADITHI YA SAMAKI WA RANGI NNE. Soma Zaidi...
Hadithi ya binti mwenye kufichwa mtoto wa mfalme
Posti hii inakwenda kukuletea hadithi za alifu lela ulela Soma Zaidi...
Kisa Cha mfugaji na mkewe
Posti hii inakwenda kukuletea hadithi za alifu lela ulela Soma Zaidi...
Kisiwa cha uokozi
Posti hii inakwenda kukupa muendelezo wa hadithi za safari saba za Sinbad Soma Zaidi...
MWANZO WA USALITI
Download kitabu Hiki Bofya hapa USALITI UNANZA HAPA Baada ya kukaa pale siku moja nahodha akaamrisha chombo kiondoke pale na kurudi nyumbani. Soma Zaidi...
SAFARI YA KWANZA YA SINBAD
Download kitabu Hiki Bofya hapa SAFARI YA KWANZA YA SINBAD Tambua kuwa baba yangu alikuwa ni mfanya biashara mkubwa sana katika nchi ya baghdad wakati wa utawala wa sultan harun Rashid. Soma Zaidi...
alif lela u lela
Download kitabu Hiki Bofya hapa Kupata mwendelezo wa hadithi hii Download App yetu. Soma Zaidi...
ALIF LELA U LELA: UTANGULIZI
ALIF LELA U LELA. Soma Zaidi...
TONGE LA MWISHO
Download kitabu Hiki Bofya hapa KWISHA KWA CHAKULA Watu waliaanza kumaliza vyakula vyao na wakaanza kufa baada ya siku kadhaa. Soma Zaidi...
Usaliti unaanza hapa
Posti hii inakwenda kukuletea hadithi za alifu lela ulela Soma Zaidi...