mirror of https://github.com/grpc/grpc-web.git
Internal code sync (#1225)
This commit is contained in:
parent
176e831b07
commit
a1b706ade0
|
@ -134,29 +134,30 @@ class GrpcWebClientReadableStream {
|
||||||
*/
|
*/
|
||||||
this.parser_ = new GrpcWebStreamParser();
|
this.parser_ = new GrpcWebStreamParser();
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
events.listen(this.xhr_, EventType.READY_STATE_CHANGE, function(e) {
|
events.listen(this.xhr_, EventType.READY_STATE_CHANGE, function(e) {
|
||||||
var contentType = self.xhr_.getStreamingResponseHeader('Content-Type');
|
let contentType = self.xhr_.getStreamingResponseHeader('Content-Type');
|
||||||
if (!contentType) return;
|
if (!contentType) return;
|
||||||
contentType = contentType.toLowerCase();
|
contentType = contentType.toLowerCase();
|
||||||
|
|
||||||
|
let byteSource;
|
||||||
if (googString.startsWith(contentType, 'application/grpc-web-text')) {
|
if (googString.startsWith(contentType, 'application/grpc-web-text')) {
|
||||||
// Ensure responseText is not null
|
// Ensure responseText is not null
|
||||||
var responseText = self.xhr_.getResponseText() || "";
|
const responseText = self.xhr_.getResponseText() || '';
|
||||||
var newPos = responseText.length - responseText.length % 4;
|
const newPos = responseText.length - responseText.length % 4;
|
||||||
var newData = responseText.substr(self.pos_, newPos - self.pos_);
|
const newData = responseText.substr(self.pos_, newPos - self.pos_);
|
||||||
if (newData.length == 0) return;
|
if (newData.length == 0) return;
|
||||||
self.pos_ = newPos;
|
self.pos_ = newPos;
|
||||||
var byteSource = googCrypt.decodeStringToUint8Array(newData);
|
byteSource = googCrypt.decodeStringToUint8Array(newData);
|
||||||
} else if (googString.startsWith(contentType, 'application/grpc')) {
|
} else if (googString.startsWith(contentType, 'application/grpc')) {
|
||||||
var byteSource = new Uint8Array(
|
byteSource = new Uint8Array(
|
||||||
/** @type {!ArrayBuffer} */ (self.xhr_.getResponse()));
|
/** @type {!ArrayBuffer} */ (self.xhr_.getResponse()));
|
||||||
} else {
|
} else {
|
||||||
self.handleError_(
|
self.handleError_(
|
||||||
new RpcError(StatusCode.UNKNOWN, 'Unknown Content-type received.'));
|
new RpcError(StatusCode.UNKNOWN, 'Unknown Content-type received.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var messages = null;
|
let messages = null;
|
||||||
try {
|
try {
|
||||||
messages = self.parser_.parse(byteSource);
|
messages = self.parser_.parse(byteSource);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -164,10 +165,10 @@ class GrpcWebClientReadableStream {
|
||||||
new RpcError(StatusCode.UNKNOWN, 'Error in parsing response body'));
|
new RpcError(StatusCode.UNKNOWN, 'Error in parsing response body'));
|
||||||
}
|
}
|
||||||
if (messages) {
|
if (messages) {
|
||||||
var FrameType = GrpcWebStreamParser.FrameType;
|
const FrameType = GrpcWebStreamParser.FrameType;
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (let i = 0; i < messages.length; i++) {
|
||||||
if (FrameType.DATA in messages[i]) {
|
if (FrameType.DATA in messages[i]) {
|
||||||
var data = messages[i][FrameType.DATA];
|
const data = messages[i][FrameType.DATA];
|
||||||
if (data) {
|
if (data) {
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
|
@ -176,7 +177,7 @@ class GrpcWebClientReadableStream {
|
||||||
self.handleError_(new RpcError(
|
self.handleError_(new RpcError(
|
||||||
StatusCode.INTERNAL,
|
StatusCode.INTERNAL,
|
||||||
`Error when deserializing response data; error: ${err}` +
|
`Error when deserializing response data; error: ${err}` +
|
||||||
`, response: ${response}`));
|
`, response: ${response}`));
|
||||||
}
|
}
|
||||||
if (response) {
|
if (response) {
|
||||||
self.sendDataCallbacks_(response);
|
self.sendDataCallbacks_(response);
|
||||||
|
@ -185,15 +186,15 @@ class GrpcWebClientReadableStream {
|
||||||
}
|
}
|
||||||
if (FrameType.TRAILER in messages[i]) {
|
if (FrameType.TRAILER in messages[i]) {
|
||||||
if (messages[i][FrameType.TRAILER].length > 0) {
|
if (messages[i][FrameType.TRAILER].length > 0) {
|
||||||
var trailerString = '';
|
let trailerString = '';
|
||||||
for (var pos = 0; pos < messages[i][FrameType.TRAILER].length;
|
for (let pos = 0; pos < messages[i][FrameType.TRAILER].length;
|
||||||
pos++) {
|
pos++) {
|
||||||
trailerString +=
|
trailerString +=
|
||||||
String.fromCharCode(messages[i][FrameType.TRAILER][pos]);
|
String.fromCharCode(messages[i][FrameType.TRAILER][pos]);
|
||||||
}
|
}
|
||||||
var trailers = self.parseHttp1Headers_(trailerString);
|
const trailers = self.parseHttp1Headers_(trailerString);
|
||||||
var grpcStatusCode = StatusCode.OK;
|
let grpcStatusCode = StatusCode.OK;
|
||||||
var grpcStatusMessage = '';
|
let grpcStatusMessage = '';
|
||||||
if (GRPC_STATUS in trailers) {
|
if (GRPC_STATUS in trailers) {
|
||||||
grpcStatusCode =
|
grpcStatusCode =
|
||||||
/** @type {!StatusCode} */ (Number(trailers[GRPC_STATUS]));
|
/** @type {!StatusCode} */ (Number(trailers[GRPC_STATUS]));
|
||||||
|
@ -212,12 +213,12 @@ class GrpcWebClientReadableStream {
|
||||||
});
|
});
|
||||||
|
|
||||||
events.listen(this.xhr_, EventType.COMPLETE, function(e) {
|
events.listen(this.xhr_, EventType.COMPLETE, function(e) {
|
||||||
var lastErrorCode = self.xhr_.getLastErrorCode();
|
const lastErrorCode = self.xhr_.getLastErrorCode();
|
||||||
var grpcStatusCode = StatusCode.UNKNOWN;
|
let grpcStatusCode = StatusCode.UNKNOWN;
|
||||||
var grpcStatusMessage = '';
|
let grpcStatusMessage = '';
|
||||||
var initialMetadata = /** @type {!Metadata} */ ({});
|
const initialMetadata = /** @type {!Metadata} */ ({});
|
||||||
|
|
||||||
var responseHeaders = self.xhr_.getResponseHeaders();
|
const responseHeaders = self.xhr_.getResponseHeaders();
|
||||||
Object.keys(responseHeaders).forEach((header_) => {
|
Object.keys(responseHeaders).forEach((header_) => {
|
||||||
if (!(EXCLUDED_RESPONSE_HEADERS.includes(header_))) {
|
if (!(EXCLUDED_RESPONSE_HEADERS.includes(header_))) {
|
||||||
initialMetadata[header_] = responseHeaders[header_];
|
initialMetadata[header_] = responseHeaders[header_];
|
||||||
|
@ -226,6 +227,7 @@ class GrpcWebClientReadableStream {
|
||||||
self.sendMetadataCallbacks_(initialMetadata);
|
self.sendMetadataCallbacks_(initialMetadata);
|
||||||
|
|
||||||
// There's an XHR level error
|
// There's an XHR level error
|
||||||
|
let xhrStatusCode = -1;
|
||||||
if (lastErrorCode != ErrorCode.NO_ERROR) {
|
if (lastErrorCode != ErrorCode.NO_ERROR) {
|
||||||
switch (lastErrorCode) {
|
switch (lastErrorCode) {
|
||||||
case ErrorCode.ABORT:
|
case ErrorCode.ABORT:
|
||||||
|
@ -235,7 +237,8 @@ class GrpcWebClientReadableStream {
|
||||||
grpcStatusCode = StatusCode.DEADLINE_EXCEEDED;
|
grpcStatusCode = StatusCode.DEADLINE_EXCEEDED;
|
||||||
break;
|
break;
|
||||||
case ErrorCode.HTTP_ERROR:
|
case ErrorCode.HTTP_ERROR:
|
||||||
grpcStatusCode = StatusCode.fromHttpStatus(self.xhr_.getStatus());
|
xhrStatusCode = self.xhr_.getStatus();
|
||||||
|
grpcStatusCode = StatusCode.fromHttpStatus(xhrStatusCode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
grpcStatusCode = StatusCode.UNAVAILABLE;
|
grpcStatusCode = StatusCode.UNAVAILABLE;
|
||||||
|
@ -243,12 +246,16 @@ class GrpcWebClientReadableStream {
|
||||||
if (grpcStatusCode == StatusCode.ABORTED && self.aborted_) {
|
if (grpcStatusCode == StatusCode.ABORTED && self.aborted_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.handleError_(new RpcError(
|
let errorMessage = ErrorCode.getDebugMessage(lastErrorCode);
|
||||||
grpcStatusCode, ErrorCode.getDebugMessage(lastErrorCode)));
|
if (xhrStatusCode != -1) {
|
||||||
|
errorMessage += ', http status code: ' + xhrStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.handleError_(new RpcError(grpcStatusCode, errorMessage));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var errorEmitted = false;
|
let errorEmitted = false;
|
||||||
|
|
||||||
// Check whethere there are grpc specific response headers
|
// Check whethere there are grpc specific response headers
|
||||||
if (GRPC_STATUS in responseHeaders) {
|
if (GRPC_STATUS in responseHeaders) {
|
||||||
|
@ -348,10 +355,10 @@ class GrpcWebClientReadableStream {
|
||||||
* @return {!Object} The header:value pairs
|
* @return {!Object} The header:value pairs
|
||||||
*/
|
*/
|
||||||
parseHttp1Headers_(str) {
|
parseHttp1Headers_(str) {
|
||||||
var chunks = str.trim().split('\r\n');
|
const chunks = str.trim().split('\r\n');
|
||||||
var headers = {};
|
const headers = {};
|
||||||
for (var i = 0; i < chunks.length; i++) {
|
for (let i = 0; i < chunks.length; i++) {
|
||||||
var pos = chunks[i].indexOf(':');
|
const pos = chunks[i].indexOf(':');
|
||||||
headers[chunks[i].substring(0, pos).trim()] =
|
headers[chunks[i].substring(0, pos).trim()] =
|
||||||
chunks[i].substring(pos + 1).trim();
|
chunks[i].substring(pos + 1).trim();
|
||||||
}
|
}
|
||||||
|
@ -381,7 +388,7 @@ class GrpcWebClientReadableStream {
|
||||||
* @param {!RESPONSE} data The data to send back
|
* @param {!RESPONSE} data The data to send back
|
||||||
*/
|
*/
|
||||||
sendDataCallbacks_(data) {
|
sendDataCallbacks_(data) {
|
||||||
for (var i = 0; i < this.onDataCallbacks_.length; i++) {
|
for (let i = 0; i < this.onDataCallbacks_.length; i++) {
|
||||||
this.onDataCallbacks_[i](data);
|
this.onDataCallbacks_[i](data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,7 +398,7 @@ class GrpcWebClientReadableStream {
|
||||||
* @param {!Status} status The status to send back
|
* @param {!Status} status The status to send back
|
||||||
*/
|
*/
|
||||||
sendStatusCallbacks_(status) {
|
sendStatusCallbacks_(status) {
|
||||||
for (var i = 0; i < this.onStatusCallbacks_.length; i++) {
|
for (let i = 0; i < this.onStatusCallbacks_.length; i++) {
|
||||||
this.onStatusCallbacks_[i](status);
|
this.onStatusCallbacks_[i](status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,7 +408,7 @@ class GrpcWebClientReadableStream {
|
||||||
* @param {!Metadata} metadata The metadata to send back
|
* @param {!Metadata} metadata The metadata to send back
|
||||||
*/
|
*/
|
||||||
sendMetadataCallbacks_(metadata) {
|
sendMetadataCallbacks_(metadata) {
|
||||||
for (var i = 0; i < this.onMetadataCallbacks_.length; i++) {
|
for (let i = 0; i < this.onMetadataCallbacks_.length; i++) {
|
||||||
this.onMetadataCallbacks_[i](metadata);
|
this.onMetadataCallbacks_[i](metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +418,7 @@ class GrpcWebClientReadableStream {
|
||||||
* @param {!RpcError} error The error to send back
|
* @param {!RpcError} error The error to send back
|
||||||
*/
|
*/
|
||||||
sendErrorCallbacks_(error) {
|
sendErrorCallbacks_(error) {
|
||||||
for (var i = 0; i < this.onErrorCallbacks_.length; i++) {
|
for (let i = 0; i < this.onErrorCallbacks_.length; i++) {
|
||||||
this.onErrorCallbacks_[i](error);
|
this.onErrorCallbacks_[i](error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,7 +427,7 @@ class GrpcWebClientReadableStream {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
sendEndCallbacks_() {
|
sendEndCallbacks_() {
|
||||||
for (var i = 0; i < this.onEndCallbacks_.length; i++) {
|
for (let i = 0; i < this.onEndCallbacks_.length; i++) {
|
||||||
this.onEndCallbacks_[i]();
|
this.onEndCallbacks_[i]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ class RpcError extends Error {
|
||||||
*/
|
*/
|
||||||
constructor(code, message, metadata = {}) {
|
constructor(code, message, metadata = {}) {
|
||||||
super(message);
|
super(message);
|
||||||
/** @export {!StatusCode} */
|
/** @type {!StatusCode} */
|
||||||
this.code = code;
|
this.code = code;
|
||||||
/** @export {!Metadata} */
|
/** @type {!Metadata} */
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue