@itwin/core-common
Version:
iTwin.js components common to frontend and backend
113 lines • 5.08 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module RpcInterface
*/
import { BentleyError, Logger } from "@itwin/core-bentley";
import { CommonLoggerCategory } from "../../CommonLoggerCategory";
import { RpcContentType, RpcRequestStatus, WEB_RPC_CONSTANTS } from "../core/RpcConstants";
import { RpcProtocol } from "../core/RpcProtocol";
import { RpcOpenAPIDescription } from "./OpenAPI";
import { WebAppRpcLogging } from "./WebAppRpcLogging";
import { WebAppRpcRequest } from "./WebAppRpcRequest";
/** The HTTP application protocol.
* @internal
*/
export class WebAppRpcProtocol extends RpcProtocol {
preserveStreams = true;
/** Convenience handler for an RPC operation get request for an HTTP server. */
async handleOperationGetRequest(req, res) {
return this.handleOperationPostRequest(req, res);
}
/** Convenience handler for an RPC operation post request for an HTTP server. */
async handleOperationPostRequest(req, res) {
let request;
try {
request = await WebAppRpcRequest.parseRequest(this, req);
}
catch (error) {
const message = BentleyError.getErrorMessage(error);
Logger.logError(CommonLoggerCategory.RpcInterfaceBackend, `Failed to parse request: ${message}`, BentleyError.getErrorMetadata(error));
res.status(400);
res.send(JSON.stringify({ message, isError: true }));
return;
}
const fulfillment = await this.fulfill(request);
await WebAppRpcRequest.sendResponse(this, request, fulfillment, req, res);
}
/** Convenience handler for an OpenAPI description request for an HTTP server. */
handleOpenApiDescriptionRequest(_req, res) {
const description = JSON.stringify(this.openAPIDescription);
res.send(description);
}
/** Converts an HTTP content type value to an RPC content type value. */
static computeContentType(httpType) {
if (!httpType)
return RpcContentType.Unknown;
if (httpType.indexOf(WEB_RPC_CONSTANTS.ANY_TEXT) === 0) {
return RpcContentType.Text;
}
else if (httpType.indexOf(WEB_RPC_CONSTANTS.BINARY) === 0) {
return RpcContentType.Binary;
}
else if (httpType.indexOf(WEB_RPC_CONSTANTS.MULTIPART) === 0) {
return RpcContentType.Multipart;
}
else {
return RpcContentType.Unknown;
}
}
/** An optional prefix for RPC operation URI paths. */
pathPrefix = "";
/** The RPC request class for this protocol. */
requestType = WebAppRpcRequest;
/** Supplies the status corresponding to a protocol-specific code value. */
getStatus(code) {
switch (code) {
case 404: return RpcRequestStatus.NotFound;
case 202: return RpcRequestStatus.Pending;
case 200: return RpcRequestStatus.Resolved;
case 500: return RpcRequestStatus.Rejected;
case 204: return RpcRequestStatus.NoContent;
case 502: return RpcRequestStatus.BadGateway;
case 503: return RpcRequestStatus.ServiceUnavailable;
case 504: return RpcRequestStatus.GatewayTimeout;
case 408: return RpcRequestStatus.RequestTimeout;
case 429: return RpcRequestStatus.TooManyRequests;
default: return RpcRequestStatus.Unknown;
}
}
/** Supplies the protocol-specific code corresponding to a status value. */
getCode(status) {
switch (status) {
case RpcRequestStatus.NotFound: return 404;
case RpcRequestStatus.Pending: return 202;
case RpcRequestStatus.Resolved: return 200;
case RpcRequestStatus.Rejected: return 500;
case RpcRequestStatus.NoContent: return 204;
case RpcRequestStatus.BadGateway: return 502;
case RpcRequestStatus.ServiceUnavailable: return 503;
case RpcRequestStatus.GatewayTimeout: return 504;
case RpcRequestStatus.RequestTimeout: return 408;
case RpcRequestStatus.TooManyRequests: return 429;
default: return 501;
}
}
supportsStatusCategory = true;
/** Whether an HTTP status code indicates a request timeout. */
isTimeout(code) {
return code === 504;
}
/** An OpenAPI-compatible description of this protocol.
* @internal
*/
get openAPIDescription() { return new RpcOpenAPIDescription(this); }
/** Constructs an HTTP protocol. */
constructor(configuration) {
super(configuration);
this.events.addListener(async (event, object) => WebAppRpcLogging.logProtocolEvent(event, object));
}
}
//# sourceMappingURL=WebAppRpcProtocol.js.map