@azure/web-pubsub-express 1.0.0-beta.1 → 1.0.1-alpha.20211215.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/README.md +123 -30
- package/dist/index.js +310 -242
- package/dist/index.js.map +1 -1
- package/dist-esm/samples-dev/server.js +9 -4
- package/dist-esm/samples-dev/server.js.map +1 -1
- package/dist-esm/src/cloudEventsDispatcher.js +225 -232
- package/dist-esm/src/cloudEventsDispatcher.js.map +1 -1
- package/dist-esm/src/cloudEventsProtocols.js.map +1 -1
- package/dist-esm/src/logger.js +10 -0
- package/dist-esm/src/logger.js.map +1 -0
- package/dist-esm/src/utils.js +68 -0
- package/dist-esm/src/utils.js.map +1 -0
- package/dist-esm/src/webPubSubEventHandler.js +11 -12
- package/dist-esm/src/webPubSubEventHandler.js.map +1 -1
- package/dist-esm/test/connect.spec.js +131 -81
- package/dist-esm/test/connect.spec.js.map +1 -1
- package/dist-esm/test/connected.spec.js +43 -53
- package/dist-esm/test/connected.spec.js.map +1 -1
- package/dist-esm/test/ctor.spec.js +9 -3
- package/dist-esm/test/ctor.spec.js.map +1 -1
- package/dist-esm/test/disconnected.spec.js +43 -53
- package/dist-esm/test/disconnected.spec.js.map +1 -1
- package/dist-esm/test/user.spec.js +121 -115
- package/dist-esm/test/user.spec.js.map +1 -1
- package/dist-esm/test/validate.spec.js +26 -10
- package/dist-esm/test/validate.spec.js.map +1 -1
- package/package.json +18 -38
- package/types/web-pubsub-express.d.ts +36 -16
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/cloudEventsDispatcher.ts","../src/webPubSubEventHandler.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { CloudEvent, Message, HTTP } from \"cloudevents\";\nimport { IncomingMessage, ServerResponse } from \"http\";\nimport { URL } from \"url\";\nimport {\n ConnectRequest,\n ConnectResponse,\n UserEventRequest,\n DisconnectedRequest,\n ConnectedRequest,\n ConnectionContext,\n WebPubSubEventHandlerOptions\n} from \"./cloudEventsProtocols\";\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _dumpRequest: boolean;\n private readonly _allowedOrigins: string[];\n constructor(\n private hub: string,\n allowedEndpoints: string[],\n private eventHandler?: WebPubSubEventHandlerOptions\n ) {\n this._dumpRequest = eventHandler?.dumpRequest ?? false;\n this._allowedOrigins = allowedEndpoints.map((endpoint) =>\n endpoint === \"*\" ? \"*\" : new URL(endpoint).host\n );\n }\n\n public processValidateRequest(req: IncomingMessage, res: ServerResponse): boolean {\n if (req.headers[\"webhook-request-origin\"]) {\n res.setHeader(\"WebHook-Allowed-Origin\", this._allowedOrigins);\n res.end();\n return true;\n } else {\n return false;\n }\n }\n\n public async processRequest(\n request: IncomingMessage,\n response: ServerResponse\n ): Promise<boolean> {\n // check if it is a valid WebPubSub cloud events\n const origin = this.getSingleHeader(request, \"webhook-request-origin\");\n if (origin === undefined) {\n return false;\n }\n\n const eventType = this.tryGetWebPubSubEvent(request);\n if (eventType === undefined) {\n return false;\n }\n\n // check if hub matches\n if (request.headers[\"ce-hub\"] !== this.hub) {\n return false;\n }\n\n // No need to read body if handler is not specified\n switch (eventType) {\n case EventType.Connect:\n if (!this.eventHandler?.handleConnect) {\n response.statusCode = 401;\n response.end(\"Connect event handler is not configured.\");\n return true;\n }\n break;\n case EventType.Connected:\n if (!this.eventHandler?.onConnected) {\n response.end();\n return true;\n }\n break;\n case EventType.Disconnected:\n if (!this.eventHandler?.onDisconnected) {\n response.end();\n return true;\n }\n break;\n case EventType.UserEvent:\n if (!this.eventHandler?.handleUserEvent) {\n response.end();\n return true;\n }\n break;\n default:\n console.warn(`Unknown EventType ${eventType}`);\n return false;\n }\n\n const eventRequest = await this.convertHttpToEvent(request);\n const receivedEvent = HTTP.toEvent(eventRequest);\n\n if (this._dumpRequest) {\n console.log(receivedEvent);\n }\n\n switch (eventType) {\n case EventType.Connect: {\n const connectRequest = receivedEvent.data as ConnectRequest;\n connectRequest.context = this.GetContext(receivedEvent, origin);\n this.eventHandler.handleConnect!(connectRequest, {\n success(res?: ConnectResponse): void {\n response.statusCode = 200;\n if (res === undefined) {\n response.end();\n } else {\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(res));\n }\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n });\n return true;\n }\n case EventType.Connected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const connectedRequest = receivedEvent.data as ConnectedRequest;\n connectedRequest.context = this.GetContext(receivedEvent, origin);\n this.eventHandler.onConnected!(connectedRequest);\n return true;\n }\n case EventType.Disconnected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const disconnectedRequest = receivedEvent.data as DisconnectedRequest;\n disconnectedRequest.context = this.GetContext(receivedEvent, origin);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n let userRequest: UserEventRequest;\n if (receivedEvent.data_base64 !== undefined) {\n userRequest = {\n context: this.GetContext(receivedEvent, origin),\n data: Buffer.from(receivedEvent.data_base64, \"base64\"),\n dataType: \"binary\"\n };\n } else if (receivedEvent.data !== undefined) {\n userRequest = {\n context: this.GetContext(receivedEvent, origin),\n data: receivedEvent.data as string,\n dataType: receivedEvent.datacontenttype?.startsWith(\"application/json;\")\n ? \"json\"\n : \"text\"\n };\n } else {\n throw new Error(\"Unexpected data.\");\n }\n\n this.eventHandler.handleUserEvent!(userRequest, {\n success(data?: string | ArrayBuffer, dataType?: \"binary\" | \"text\" | \"json\"): void {\n response.statusCode = 200;\n switch (dataType) {\n case \"json\":\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n break;\n case \"text\":\n response.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n break;\n default:\n response.setHeader(\"Content-Type\", \"application/octet-stream\");\n break;\n }\n response.end(data ?? \"\");\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n });\n return true;\n }\n default:\n console.warn(`Unknown EventType ${eventType}`);\n return false;\n }\n }\n\n private tryGetWebPubSubEvent(req: IncomingMessage): EventType | undefined {\n // check ce-type to see if it is a valid WebPubSub CloudEvent request\n const prefix = \"azure.webpubsub.\";\n const connect = \"azure.webpubsub.sys.connect\";\n const connected = \"azure.webpubsub.sys.connected\";\n const disconnectd = \"azure.webpubsub.sys.disconnected\";\n const userPrefix = \"azure.webpubsub.user.\";\n const type = this.getSingleHeader(req, \"ce-type\");\n if (!type?.startsWith(prefix)) {\n return undefined;\n }\n if (type.startsWith(userPrefix)) {\n return EventType.UserEvent;\n }\n switch (type) {\n case connect:\n return EventType.Connect;\n case connected:\n return EventType.Connected;\n case disconnectd:\n return EventType.Disconnected;\n default:\n return undefined;\n }\n }\n\n private getSingleHeader(req: IncomingMessage, key: string): string | undefined {\n const value = req.headers[key];\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n return value[0];\n }\n\n private GetContext(ce: CloudEvent, origin: string): ConnectionContext {\n const context = {\n signature: ce[\"signature\"] as string,\n userId: ce[\"userid\"] as string,\n hub: ce[\"hub\"] as string,\n connectionId: ce[\"connectionid\"] as string,\n eventName: ce[\"eventname\"] as string,\n origin: origin\n };\n\n // TODO: validation\n return context;\n }\n\n private async convertHttpToEvent(request: IncomingMessage): Promise<Message> {\n const normalized: Message = {\n headers: {},\n body: \"\"\n };\n if (request.headers) {\n for (const key in request.headers) {\n if (Object.prototype.hasOwnProperty.call(request.headers, key)) {\n const element = request.headers[key];\n if (element === undefined) {\n continue;\n }\n if (typeof element === \"string\") {\n normalized.headers[key] = element;\n } else {\n normalized.headers[key] = element.join(\",\");\n }\n }\n }\n }\n\n normalized.body = await this.readRequestBody(request);\n return normalized;\n }\n\n private readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise(function(resolve, reject) {\n const chunks: any = [];\n req.on(\"data\", function(chunk) {\n chunks.push(chunk);\n });\n req.on(\"end\", function() {\n const buffer = Buffer.concat(chunks);\n resolve(buffer.toString());\n });\n // reject on request error\n req.on(\"error\", function(err) {\n // This is not a \"Second reject\", just a different sort of failure\n reject(err);\n });\n });\n }\n}\n\nenum EventType {\n Connect,\n Connected,\n Disconnected,\n UserEvent\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport express from \"express-serve-static-core\";\n\nimport { CloudEventsDispatcher } from \"./cloudEventsDispatcher\";\nimport { WebPubSubEventHandlerOptions } from \"./cloudEventsProtocols\";\n\n/**\n * The handler to handle incoming CloudEvents messages\n */\nexport class WebPubSubEventHandler {\n /**\n * The path this CloudEvents handler listens to\n */\n public readonly path: string;\n\n private _cloudEventsHandler: CloudEventsDispatcher;\n\n /**\n * Creates an instance of a WebPubSubEventHandler for handling incoming CloudEvents messages.\n *\n * Example usage:\n * ```ts\n * import express from \"express\";\n * import { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\n * const endpoint = \"https://xxxx.webpubsubdev.azure.com\"\n * const handler = new WebPubSubEventHandler('chat', [ endpoint ] {\n * handleConnect: (req, res) => {\n * console.log(JSON.stringify(req));\n * return {};\n * },\n * onConnected: req => {\n * console.log(JSON.stringify(req));\n * },\n * handleUserEvent: (req, res) => {\n * console.log(JSON.stringify(req));\n * res.success(\"Hey \" + req.data, req.dataType);\n * };\n * },\n * });\n * ```\n *\n * @param hub The name of the hub to listen to\n * @param allowedEndpoints The allowed endpoints for the incoming CloudEvents request\n * @param options Options to configure the event handler\n */\n constructor(\n private hub: string,\n allowedEndpoints: string[],\n options?: WebPubSubEventHandlerOptions\n ) {\n const path = (options?.path ?? `/api/webpubsub/hubs/${hub}/`).toLowerCase();\n this.path = path.endsWith(\"/\") ? path : path + \"/\";\n this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, allowedEndpoints, options);\n }\n\n /**\n * Get the middleware to process the CloudEvents requests\n */\n public getMiddleware(): express.RequestHandler {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ): Promise<void> => {\n // Request originalUrl can contain query while baseUrl + path not\n let requestUrl = (req.baseUrl + req.path).toLowerCase();\n\n // normalize the Url\n requestUrl = requestUrl.endsWith(\"/\") ? requestUrl : requestUrl + \"/\";\n if (requestUrl === this.path) {\n if (req.method === \"OPTIONS\") {\n if (this._cloudEventsHandler.processValidateRequest(req, res)) {\n return;\n }\n } else if (req.method === \"POST\") {\n try {\n if (await this._cloudEventsHandler.processRequest(req, res)) {\n return;\n }\n } catch (err) {\n next(err);\n return;\n }\n }\n }\n\n next();\n };\n }\n}\n"],"names":["URL","HTTP"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/logger.ts","../src/utils.ts","../src/cloudEventsDispatcher.ts","../src/webPubSubEventHandler.ts"],"sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createClientLogger } from \"@azure/logger\";\n\n/**\n * The \\@azure/logger configuration for this package.\n *\n * @internal\n */\nexport const logger = createClientLogger(\"web-pubsub-express\");\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { IncomingMessage } from \"http\";\nimport { Message } from \"cloudevents\";\n\nfunction isJsonObject(obj: any): boolean {\n return obj && typeof obj === \"object\" && !Array.isArray(obj);\n}\n\nexport function toBase64JsonString(obj: Record<string, any>): string {\n return Buffer.from(JSON.stringify(obj)).toString(\"base64\");\n}\n\nexport function fromBase64JsonString(base64String: string): Record<string, any> {\n if (base64String === undefined) {\n return {};\n }\n\n try {\n const buf = Buffer.from(base64String, \"base64\").toString();\n const parsed = JSON.parse(buf);\n return isJsonObject(parsed) ? parsed : {};\n } catch (e) {\n console.warn(\"Unexpected state format:\" + e);\n return {};\n }\n}\n\nexport function getHttpHeader(req: IncomingMessage, key: string): string | undefined {\n const value = req.headers[key];\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n return value[0];\n}\n\nexport async function convertHttpToEvent(request: IncomingMessage): Promise<Message> {\n const normalized: Message = {\n headers: {},\n body: \"\"\n };\n if (request.headers) {\n for (const key in request.headers) {\n if (Object.prototype.hasOwnProperty.call(request.headers, key)) {\n const element = request.headers[key];\n if (element !== undefined) {\n normalized.headers[key.toLowerCase()] = element;\n }\n }\n }\n }\n\n normalized.body = await readRequestBody(request);\n return normalized;\n}\n\nexport function readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise(function(resolve, reject) {\n const chunks: any = [];\n req.on(\"data\", function(chunk) {\n chunks.push(chunk);\n });\n req.on(\"end\", function() {\n const buffer = Buffer.concat(chunks);\n resolve(buffer.toString());\n });\n // reject on request error\n req.on(\"error\", function(err) {\n // This is not a \"Second reject\", just a different sort of failure\n reject(err);\n });\n });\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { HTTP, CloudEvent } from \"cloudevents\";\nimport { IncomingMessage, ServerResponse } from \"http\";\nimport { URL } from \"url\";\nimport { logger } from \"./logger\";\nimport * as utils from \"./utils\";\n\nimport {\n ConnectRequest,\n ConnectResponse,\n UserEventRequest,\n DisconnectedRequest,\n ConnectedRequest,\n ConnectionContext,\n ConnectResponseHandler,\n UserEventResponseHandler,\n WebPubSubEventHandlerOptions\n} from \"./cloudEventsProtocols\";\n\nenum EventType {\n Connect,\n Connected,\n Disconnected,\n UserEvent\n}\n\nfunction getConnectResponseHandler(\n connectRequest: ConnectRequest,\n response: ServerResponse\n): ConnectResponseHandler {\n const states: Record<string, any> = connectRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n states[name] = value;\n modified = true;\n },\n success(res?: ConnectResponse): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n if (res === undefined) {\n response.end();\n } else {\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n response.end(JSON.stringify(res));\n }\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n };\n\n return handler;\n}\n\nfunction getUserEventResponseHandler(\n userRequest: UserEventRequest,\n response: ServerResponse\n): UserEventResponseHandler {\n const states: Record<string, any> = userRequest.context.states;\n let modified = false;\n const handler = {\n setState(name: string, value: unknown): void {\n modified = true;\n states[name] = value;\n },\n success(data?: string | ArrayBuffer, dataType?: \"binary\" | \"text\" | \"json\"): void {\n response.statusCode = 200;\n if (modified) {\n response.setHeader(\"ce-connectionState\", utils.toBase64JsonString(states));\n }\n\n switch (dataType) {\n case \"json\":\n response.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n break;\n case \"text\":\n response.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n break;\n default:\n response.setHeader(\"Content-Type\", \"application/octet-stream\");\n break;\n }\n response.end(data ?? \"\");\n },\n fail(code: 400 | 401 | 500, detail?: string): void {\n response.statusCode = code;\n response.end(detail ?? \"\");\n }\n };\n return handler;\n}\n\nfunction getContext(ce: CloudEvent, origin: string): ConnectionContext {\n const context = {\n signature: ce[\"signature\"] as string,\n userId: ce[\"userid\"] as string,\n hub: ce[\"hub\"] as string,\n connectionId: ce[\"connectionid\"] as string,\n eventName: ce[\"eventname\"] as string,\n origin: origin,\n states: utils.fromBase64JsonString(ce[\"connectionstate\"] as string)\n };\n\n // TODO: validation\n return context;\n}\n\nfunction tryGetWebPubSubEvent(req: IncomingMessage): EventType | undefined {\n // check ce-type to see if it is a valid WebPubSub CloudEvent request\n const prefix = \"azure.webpubsub.\";\n const connect = \"azure.webpubsub.sys.connect\";\n const connected = \"azure.webpubsub.sys.connected\";\n const disconnectd = \"azure.webpubsub.sys.disconnected\";\n const userPrefix = \"azure.webpubsub.user.\";\n const type = utils.getHttpHeader(req, \"ce-type\");\n if (!type?.startsWith(prefix)) {\n return undefined;\n }\n if (type.startsWith(userPrefix)) {\n return EventType.UserEvent;\n }\n switch (type) {\n case connect:\n return EventType.Connect;\n case connected:\n return EventType.Connected;\n case disconnectd:\n return EventType.Disconnected;\n default:\n return undefined;\n }\n}\n\nfunction isWebPubSubRequest(req: IncomingMessage): boolean {\n return utils.getHttpHeader(req, \"ce-awpsversion\") !== undefined;\n}\n\n/**\n * @internal\n */\nexport class CloudEventsDispatcher {\n private readonly _allowAll: boolean = true;\n private readonly _allowedOrigins: Array<string> = [];\n constructor(private hub: string, private eventHandler?: WebPubSubEventHandlerOptions) {\n if (Array.isArray(eventHandler)) {\n throw new Error(\"Unexpected WebPubSubEventHandlerOptions\");\n }\n if (eventHandler?.allowedEndpoints !== undefined) {\n this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) =>\n new URL(endpoint).host.toLowerCase()\n );\n this._allowAll = false;\n }\n }\n\n public handlePreflight(req: IncomingMessage, res: ServerResponse): boolean {\n if (!isWebPubSubRequest(req)) {\n return false;\n }\n const origin = utils.getHttpHeader(req, \"webhook-request-origin\")?.toLowerCase();\n\n if (origin === undefined) {\n logger.warning(\"Expecting webhook-request-origin header.\");\n res.statusCode = 400;\n } else if (this._allowAll || this._allowedOrigins.indexOf(origin!) > -1) {\n res.setHeader(\"WebHook-Allowed-Origin\", origin!);\n } else {\n logger.warning(\"Origin does not match the allowed origins: \" + this._allowedOrigins);\n res.statusCode = 400;\n }\n\n res.end();\n return true;\n }\n\n public async handleRequest(request: IncomingMessage, response: ServerResponse): Promise<boolean> {\n if (!isWebPubSubRequest(request)) {\n return false;\n }\n\n // check if it is a valid WebPubSub cloud events\n const origin = utils.getHttpHeader(request, \"webhook-request-origin\");\n if (origin === undefined) {\n return false;\n }\n\n const eventType = tryGetWebPubSubEvent(request);\n if (eventType === undefined) {\n return false;\n }\n\n // check if hub matches\n const hub = utils.getHttpHeader(request, \"ce-hub\");\n if (hub !== this.hub) {\n return false;\n }\n\n // No need to read body if handler is not specified\n switch (eventType) {\n case EventType.Connect:\n if (!this.eventHandler?.handleConnect) {\n response.end();\n return true;\n }\n break;\n case EventType.Connected:\n if (!this.eventHandler?.onConnected) {\n response.end();\n return true;\n }\n break;\n case EventType.Disconnected:\n if (!this.eventHandler?.onDisconnected) {\n response.end();\n return true;\n }\n break;\n case EventType.UserEvent:\n if (!this.eventHandler?.handleUserEvent) {\n response.end();\n return true;\n }\n break;\n default:\n logger.warning(`Unknown EventType ${eventType}`);\n return false;\n }\n\n const eventRequest = await utils.convertHttpToEvent(request);\n const receivedEvent = HTTP.toEvent(eventRequest);\n\n logger.verbose(receivedEvent);\n\n switch (eventType) {\n case EventType.Connect: {\n const connectRequest = receivedEvent.data as ConnectRequest;\n connectRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.handleConnect!(\n connectRequest,\n getConnectResponseHandler(connectRequest, response)\n );\n return true;\n }\n case EventType.Connected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const connectedRequest = receivedEvent.data as ConnectedRequest;\n connectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onConnected!(connectedRequest);\n return true;\n }\n case EventType.Disconnected: {\n // for unblocking events, we responds to the service as early as possible\n response.end();\n const disconnectedRequest = receivedEvent.data as DisconnectedRequest;\n disconnectedRequest.context = getContext(receivedEvent, origin);\n this.eventHandler.onDisconnected!(disconnectedRequest);\n return true;\n }\n case EventType.UserEvent: {\n let userRequest: UserEventRequest;\n if (receivedEvent.data_base64 !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: Buffer.from(receivedEvent.data_base64, \"base64\"),\n dataType: \"binary\"\n };\n } else if (receivedEvent.data !== undefined) {\n userRequest = {\n context: getContext(receivedEvent, origin),\n data: receivedEvent.data as string,\n dataType: receivedEvent.datacontenttype?.startsWith(\"application/json;\")\n ? \"json\"\n : \"text\"\n };\n } else {\n throw new Error(\"Unexpected data.\");\n }\n\n this.eventHandler.handleUserEvent!(\n userRequest,\n getUserEventResponseHandler(userRequest, response)\n );\n return true;\n }\n default:\n logger.warning(`Unknown EventType ${eventType}`);\n return false;\n }\n }\n}\n","// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport express from \"express-serve-static-core\";\n\nimport { CloudEventsDispatcher } from \"./cloudEventsDispatcher\";\nimport { WebPubSubEventHandlerOptions } from \"./cloudEventsProtocols\";\n\n/**\n * The handler to handle incoming CloudEvents messages\n */\nexport class WebPubSubEventHandler {\n /**\n * The path this CloudEvents handler listens to\n */\n public readonly path: string;\n\n private _cloudEventsHandler: CloudEventsDispatcher;\n\n /**\n * Creates an instance of a WebPubSubEventHandler for handling incoming CloudEvents messages.\n *\n * Example usage:\n * ```ts\n * import express from \"express\";\n * import { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\n * const endpoint = \"https://xxxx.webpubsubdev.azure.com\"\n * const handler = new WebPubSubEventHandler('chat', {\n * handleConnect: (req, res) => {\n * console.log(JSON.stringify(req));\n * return {};\n * },\n * onConnected: req => {\n * console.log(JSON.stringify(req));\n * },\n * handleUserEvent: (req, res) => {\n * console.log(JSON.stringify(req));\n * res.success(\"Hey \" + req.data, req.dataType);\n * };\n * allowedEndpoints: [ endpoint ]\n * },\n * });\n * ```\n *\n * @param hub - The name of the hub to listen to\n * @param options - Options to configure the event handler\n */\n constructor(private hub: string, options?: WebPubSubEventHandlerOptions) {\n const path = (options?.path ?? `/api/webpubsub/hubs/${hub}/`).toLowerCase();\n this.path = path.endsWith(\"/\") ? path : path + \"/\";\n this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, options);\n }\n\n /**\n * Get the middleware to process the CloudEvents requests\n */\n public getMiddleware(): express.RequestHandler {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ): Promise<void> => {\n // Request originalUrl can contain query while baseUrl + path not\n let requestUrl = (req.baseUrl + req.path).toLowerCase();\n\n // normalize the Url\n requestUrl = requestUrl.endsWith(\"/\") ? requestUrl : requestUrl + \"/\";\n if (requestUrl.startsWith(this.path)) {\n if (req.method === \"OPTIONS\") {\n if (this._cloudEventsHandler.handlePreflight(req, res)) {\n return;\n }\n } else if (req.method === \"POST\") {\n try {\n if (await this._cloudEventsHandler.handleRequest(req, res)) {\n return;\n }\n } catch (err) {\n next(err);\n return;\n }\n }\n }\n\n next();\n };\n }\n}\n"],"names":["createClientLogger","utils.toBase64JsonString","utils.fromBase64JsonString","utils.getHttpHeader","URL","utils.convertHttpToEvent","HTTP"],"mappings":"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"}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
|
|
7
7
|
import express from "express";
|
|
8
|
-
const handler = new WebPubSubEventHandler("chat",
|
|
9
|
-
dumpRequest: false,
|
|
8
|
+
const handler = new WebPubSubEventHandler("chat", {
|
|
10
9
|
handleConnect(req, res) {
|
|
11
10
|
console.log(req);
|
|
11
|
+
// You can set the state for the connection, it lasts throughout the lifetime of the connection
|
|
12
|
+
res.setState("calledTime", 1);
|
|
12
13
|
res.success();
|
|
13
14
|
// or fail
|
|
14
15
|
// res.fail(401);
|
|
@@ -17,9 +18,13 @@ const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.
|
|
|
17
18
|
console.log(connectedRequest);
|
|
18
19
|
},
|
|
19
20
|
handleUserEvent(req, res) {
|
|
20
|
-
|
|
21
|
+
var calledTime = req.context.states.calledTime++;
|
|
22
|
+
console.log(calledTime);
|
|
23
|
+
// You can also set the state here
|
|
24
|
+
res.setState("calledTime", calledTime);
|
|
21
25
|
res.success("Hello", "text");
|
|
22
|
-
}
|
|
26
|
+
},
|
|
27
|
+
allowedEndpoints: ["https://xxx.webpubsub.azure.com"]
|
|
23
28
|
});
|
|
24
29
|
const app = express();
|
|
25
30
|
app.use(handler.getMiddleware());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../samples-dev/server.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../samples-dev/server.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,MAAM,EAAE;IAChD,aAAa,CAAC,GAAG,EAAE,GAAG;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,+FAA+F;QAC/F,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAC9B,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,UAAU;QACV,iBAAiB;IACnB,CAAC;IACD,WAAW,CAAC,gBAAgB;QAC1B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IACD,eAAe,CAAC,GAAG,EAAE,GAAG;QACtB,IAAI,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,kCAAkC;QAClC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACvC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,gBAAgB,EAAE,CAAC,iCAAiC,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AAEjC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CACpB,OAAO,CAAC,GAAG,CAAC,0DAA0D,OAAO,CAAC,IAAI,EAAE,CAAC,CACtF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * @summary Demonstrates handling Web PubSub CloudEvents with Express\n */\n\nimport { WebPubSubEventHandler } from \"@azure/web-pubsub-express\";\nimport express from \"express\";\n\nconst handler = new WebPubSubEventHandler(\"chat\", {\n handleConnect(req, res) {\n console.log(req);\n // You can set the state for the connection, it lasts throughout the lifetime of the connection\n res.setState(\"calledTime\", 1);\n res.success();\n // or fail\n // res.fail(401);\n },\n onConnected(connectedRequest) {\n console.log(connectedRequest);\n },\n handleUserEvent(req, res) {\n var calledTime = req.context.states.calledTime++;\n console.log(calledTime);\n // You can also set the state here\n res.setState(\"calledTime\", calledTime);\n res.success(\"Hello\", \"text\");\n },\n allowedEndpoints: [\"https://xxx.webpubsub.azure.com\"]\n});\n\nconst app = express();\n\napp.use(handler.getMiddleware());\n\napp.listen(3000, () =>\n console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)\n);\n"]}
|
|
@@ -1,265 +1,258 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT license.
|
|
3
|
-
import { __awaiter } from "tslib";
|
|
4
3
|
import { HTTP } from "cloudevents";
|
|
5
4
|
import { URL } from "url";
|
|
5
|
+
import { logger } from "./logger";
|
|
6
|
+
import * as utils from "./utils";
|
|
7
|
+
var EventType;
|
|
8
|
+
(function (EventType) {
|
|
9
|
+
EventType[EventType["Connect"] = 0] = "Connect";
|
|
10
|
+
EventType[EventType["Connected"] = 1] = "Connected";
|
|
11
|
+
EventType[EventType["Disconnected"] = 2] = "Disconnected";
|
|
12
|
+
EventType[EventType["UserEvent"] = 3] = "UserEvent";
|
|
13
|
+
})(EventType || (EventType = {}));
|
|
14
|
+
function getConnectResponseHandler(connectRequest, response) {
|
|
15
|
+
const states = connectRequest.context.states;
|
|
16
|
+
let modified = false;
|
|
17
|
+
const handler = {
|
|
18
|
+
setState(name, value) {
|
|
19
|
+
states[name] = value;
|
|
20
|
+
modified = true;
|
|
21
|
+
},
|
|
22
|
+
success(res) {
|
|
23
|
+
response.statusCode = 200;
|
|
24
|
+
if (modified) {
|
|
25
|
+
response.setHeader("ce-connectionState", utils.toBase64JsonString(states));
|
|
26
|
+
}
|
|
27
|
+
if (res === undefined) {
|
|
28
|
+
response.end();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
response.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
32
|
+
response.end(JSON.stringify(res));
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
fail(code, detail) {
|
|
36
|
+
response.statusCode = code;
|
|
37
|
+
response.end(detail !== null && detail !== void 0 ? detail : "");
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return handler;
|
|
41
|
+
}
|
|
42
|
+
function getUserEventResponseHandler(userRequest, response) {
|
|
43
|
+
const states = userRequest.context.states;
|
|
44
|
+
let modified = false;
|
|
45
|
+
const handler = {
|
|
46
|
+
setState(name, value) {
|
|
47
|
+
modified = true;
|
|
48
|
+
states[name] = value;
|
|
49
|
+
},
|
|
50
|
+
success(data, dataType) {
|
|
51
|
+
response.statusCode = 200;
|
|
52
|
+
if (modified) {
|
|
53
|
+
response.setHeader("ce-connectionState", utils.toBase64JsonString(states));
|
|
54
|
+
}
|
|
55
|
+
switch (dataType) {
|
|
56
|
+
case "json":
|
|
57
|
+
response.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
58
|
+
break;
|
|
59
|
+
case "text":
|
|
60
|
+
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
response.setHeader("Content-Type", "application/octet-stream");
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
response.end(data !== null && data !== void 0 ? data : "");
|
|
67
|
+
},
|
|
68
|
+
fail(code, detail) {
|
|
69
|
+
response.statusCode = code;
|
|
70
|
+
response.end(detail !== null && detail !== void 0 ? detail : "");
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return handler;
|
|
74
|
+
}
|
|
75
|
+
function getContext(ce, origin) {
|
|
76
|
+
const context = {
|
|
77
|
+
signature: ce["signature"],
|
|
78
|
+
userId: ce["userid"],
|
|
79
|
+
hub: ce["hub"],
|
|
80
|
+
connectionId: ce["connectionid"],
|
|
81
|
+
eventName: ce["eventname"],
|
|
82
|
+
origin: origin,
|
|
83
|
+
states: utils.fromBase64JsonString(ce["connectionstate"])
|
|
84
|
+
};
|
|
85
|
+
// TODO: validation
|
|
86
|
+
return context;
|
|
87
|
+
}
|
|
88
|
+
function tryGetWebPubSubEvent(req) {
|
|
89
|
+
// check ce-type to see if it is a valid WebPubSub CloudEvent request
|
|
90
|
+
const prefix = "azure.webpubsub.";
|
|
91
|
+
const connect = "azure.webpubsub.sys.connect";
|
|
92
|
+
const connected = "azure.webpubsub.sys.connected";
|
|
93
|
+
const disconnectd = "azure.webpubsub.sys.disconnected";
|
|
94
|
+
const userPrefix = "azure.webpubsub.user.";
|
|
95
|
+
const type = utils.getHttpHeader(req, "ce-type");
|
|
96
|
+
if (!(type === null || type === void 0 ? void 0 : type.startsWith(prefix))) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
if (type.startsWith(userPrefix)) {
|
|
100
|
+
return EventType.UserEvent;
|
|
101
|
+
}
|
|
102
|
+
switch (type) {
|
|
103
|
+
case connect:
|
|
104
|
+
return EventType.Connect;
|
|
105
|
+
case connected:
|
|
106
|
+
return EventType.Connected;
|
|
107
|
+
case disconnectd:
|
|
108
|
+
return EventType.Disconnected;
|
|
109
|
+
default:
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function isWebPubSubRequest(req) {
|
|
114
|
+
return utils.getHttpHeader(req, "ce-awpsversion") !== undefined;
|
|
115
|
+
}
|
|
6
116
|
/**
|
|
7
117
|
* @internal
|
|
8
118
|
*/
|
|
9
119
|
export class CloudEventsDispatcher {
|
|
10
|
-
constructor(hub,
|
|
11
|
-
var _a;
|
|
120
|
+
constructor(hub, eventHandler) {
|
|
12
121
|
this.hub = hub;
|
|
13
122
|
this.eventHandler = eventHandler;
|
|
14
|
-
this.
|
|
15
|
-
this._allowedOrigins =
|
|
123
|
+
this._allowAll = true;
|
|
124
|
+
this._allowedOrigins = [];
|
|
125
|
+
if (Array.isArray(eventHandler)) {
|
|
126
|
+
throw new Error("Unexpected WebPubSubEventHandlerOptions");
|
|
127
|
+
}
|
|
128
|
+
if ((eventHandler === null || eventHandler === void 0 ? void 0 : eventHandler.allowedEndpoints) !== undefined) {
|
|
129
|
+
this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) => new URL(endpoint).host.toLowerCase());
|
|
130
|
+
this._allowAll = false;
|
|
131
|
+
}
|
|
16
132
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
133
|
+
handlePreflight(req, res) {
|
|
134
|
+
var _a;
|
|
135
|
+
if (!isWebPubSubRequest(req)) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
const origin = (_a = utils.getHttpHeader(req, "webhook-request-origin")) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
139
|
+
if (origin === undefined) {
|
|
140
|
+
logger.warning("Expecting webhook-request-origin header.");
|
|
141
|
+
res.statusCode = 400;
|
|
142
|
+
}
|
|
143
|
+
else if (this._allowAll || this._allowedOrigins.indexOf(origin) > -1) {
|
|
144
|
+
res.setHeader("WebHook-Allowed-Origin", origin);
|
|
22
145
|
}
|
|
23
146
|
else {
|
|
24
|
-
|
|
147
|
+
logger.warning("Origin does not match the allowed origins: " + this._allowedOrigins);
|
|
148
|
+
res.statusCode = 400;
|
|
25
149
|
}
|
|
150
|
+
res.end();
|
|
151
|
+
return true;
|
|
26
152
|
}
|
|
27
|
-
|
|
153
|
+
async handleRequest(request, response) {
|
|
28
154
|
var _a, _b, _c, _d, _e;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
break;
|
|
52
|
-
case EventType.Connected:
|
|
53
|
-
if (!((_b = this.eventHandler) === null || _b === void 0 ? void 0 : _b.onConnected)) {
|
|
54
|
-
response.end();
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
break;
|
|
58
|
-
case EventType.Disconnected:
|
|
59
|
-
if (!((_c = this.eventHandler) === null || _c === void 0 ? void 0 : _c.onDisconnected)) {
|
|
60
|
-
response.end();
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
break;
|
|
64
|
-
case EventType.UserEvent:
|
|
65
|
-
if (!((_d = this.eventHandler) === null || _d === void 0 ? void 0 : _d.handleUserEvent)) {
|
|
66
|
-
response.end();
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
default:
|
|
71
|
-
console.warn(`Unknown EventType ${eventType}`);
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
const eventRequest = yield this.convertHttpToEvent(request);
|
|
75
|
-
const receivedEvent = HTTP.toEvent(eventRequest);
|
|
76
|
-
if (this._dumpRequest) {
|
|
77
|
-
console.log(receivedEvent);
|
|
78
|
-
}
|
|
79
|
-
switch (eventType) {
|
|
80
|
-
case EventType.Connect: {
|
|
81
|
-
const connectRequest = receivedEvent.data;
|
|
82
|
-
connectRequest.context = this.GetContext(receivedEvent, origin);
|
|
83
|
-
this.eventHandler.handleConnect(connectRequest, {
|
|
84
|
-
success(res) {
|
|
85
|
-
response.statusCode = 200;
|
|
86
|
-
if (res === undefined) {
|
|
87
|
-
response.end();
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
response.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
91
|
-
response.end(JSON.stringify(res));
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
fail(code, detail) {
|
|
95
|
-
response.statusCode = code;
|
|
96
|
-
response.end(detail !== null && detail !== void 0 ? detail : "");
|
|
97
|
-
}
|
|
98
|
-
});
|
|
155
|
+
if (!isWebPubSubRequest(request)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
// check if it is a valid WebPubSub cloud events
|
|
159
|
+
const origin = utils.getHttpHeader(request, "webhook-request-origin");
|
|
160
|
+
if (origin === undefined) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const eventType = tryGetWebPubSubEvent(request);
|
|
164
|
+
if (eventType === undefined) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
// check if hub matches
|
|
168
|
+
const hub = utils.getHttpHeader(request, "ce-hub");
|
|
169
|
+
if (hub !== this.hub) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
// No need to read body if handler is not specified
|
|
173
|
+
switch (eventType) {
|
|
174
|
+
case EventType.Connect:
|
|
175
|
+
if (!((_a = this.eventHandler) === null || _a === void 0 ? void 0 : _a.handleConnect)) {
|
|
176
|
+
response.end();
|
|
99
177
|
return true;
|
|
100
178
|
}
|
|
101
|
-
|
|
102
|
-
|
|
179
|
+
break;
|
|
180
|
+
case EventType.Connected:
|
|
181
|
+
if (!((_b = this.eventHandler) === null || _b === void 0 ? void 0 : _b.onConnected)) {
|
|
103
182
|
response.end();
|
|
104
|
-
const connectedRequest = receivedEvent.data;
|
|
105
|
-
connectedRequest.context = this.GetContext(receivedEvent, origin);
|
|
106
|
-
this.eventHandler.onConnected(connectedRequest);
|
|
107
183
|
return true;
|
|
108
184
|
}
|
|
109
|
-
|
|
110
|
-
|
|
185
|
+
break;
|
|
186
|
+
case EventType.Disconnected:
|
|
187
|
+
if (!((_c = this.eventHandler) === null || _c === void 0 ? void 0 : _c.onDisconnected)) {
|
|
111
188
|
response.end();
|
|
112
|
-
const disconnectedRequest = receivedEvent.data;
|
|
113
|
-
disconnectedRequest.context = this.GetContext(receivedEvent, origin);
|
|
114
|
-
this.eventHandler.onDisconnected(disconnectedRequest);
|
|
115
189
|
return true;
|
|
116
190
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
context: this.GetContext(receivedEvent, origin),
|
|
122
|
-
data: Buffer.from(receivedEvent.data_base64, "base64"),
|
|
123
|
-
dataType: "binary"
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
else if (receivedEvent.data !== undefined) {
|
|
127
|
-
userRequest = {
|
|
128
|
-
context: this.GetContext(receivedEvent, origin),
|
|
129
|
-
data: receivedEvent.data,
|
|
130
|
-
dataType: ((_e = receivedEvent.datacontenttype) === null || _e === void 0 ? void 0 : _e.startsWith("application/json;"))
|
|
131
|
-
? "json"
|
|
132
|
-
: "text"
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
throw new Error("Unexpected data.");
|
|
137
|
-
}
|
|
138
|
-
this.eventHandler.handleUserEvent(userRequest, {
|
|
139
|
-
success(data, dataType) {
|
|
140
|
-
response.statusCode = 200;
|
|
141
|
-
switch (dataType) {
|
|
142
|
-
case "json":
|
|
143
|
-
response.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
144
|
-
break;
|
|
145
|
-
case "text":
|
|
146
|
-
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
147
|
-
break;
|
|
148
|
-
default:
|
|
149
|
-
response.setHeader("Content-Type", "application/octet-stream");
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
response.end(data !== null && data !== void 0 ? data : "");
|
|
153
|
-
},
|
|
154
|
-
fail(code, detail) {
|
|
155
|
-
response.statusCode = code;
|
|
156
|
-
response.end(detail !== null && detail !== void 0 ? detail : "");
|
|
157
|
-
}
|
|
158
|
-
});
|
|
191
|
+
break;
|
|
192
|
+
case EventType.UserEvent:
|
|
193
|
+
if (!((_d = this.eventHandler) === null || _d === void 0 ? void 0 : _d.handleUserEvent)) {
|
|
194
|
+
response.end();
|
|
159
195
|
return true;
|
|
160
196
|
}
|
|
161
|
-
|
|
162
|
-
console.warn(`Unknown EventType ${eventType}`);
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
tryGetWebPubSubEvent(req) {
|
|
168
|
-
// check ce-type to see if it is a valid WebPubSub CloudEvent request
|
|
169
|
-
const prefix = "azure.webpubsub.";
|
|
170
|
-
const connect = "azure.webpubsub.sys.connect";
|
|
171
|
-
const connected = "azure.webpubsub.sys.connected";
|
|
172
|
-
const disconnectd = "azure.webpubsub.sys.disconnected";
|
|
173
|
-
const userPrefix = "azure.webpubsub.user.";
|
|
174
|
-
const type = this.getSingleHeader(req, "ce-type");
|
|
175
|
-
if (!(type === null || type === void 0 ? void 0 : type.startsWith(prefix))) {
|
|
176
|
-
return undefined;
|
|
177
|
-
}
|
|
178
|
-
if (type.startsWith(userPrefix)) {
|
|
179
|
-
return EventType.UserEvent;
|
|
180
|
-
}
|
|
181
|
-
switch (type) {
|
|
182
|
-
case connect:
|
|
183
|
-
return EventType.Connect;
|
|
184
|
-
case connected:
|
|
185
|
-
return EventType.Connected;
|
|
186
|
-
case disconnectd:
|
|
187
|
-
return EventType.Disconnected;
|
|
197
|
+
break;
|
|
188
198
|
default:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
getSingleHeader(req, key) {
|
|
193
|
-
const value = req.headers[key];
|
|
194
|
-
if (value === undefined) {
|
|
195
|
-
return undefined;
|
|
196
|
-
}
|
|
197
|
-
if (typeof value === "string") {
|
|
198
|
-
return value;
|
|
199
|
+
logger.warning(`Unknown EventType ${eventType}`);
|
|
200
|
+
return false;
|
|
199
201
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
202
|
+
const eventRequest = await utils.convertHttpToEvent(request);
|
|
203
|
+
const receivedEvent = HTTP.toEvent(eventRequest);
|
|
204
|
+
logger.verbose(receivedEvent);
|
|
205
|
+
switch (eventType) {
|
|
206
|
+
case EventType.Connect: {
|
|
207
|
+
const connectRequest = receivedEvent.data;
|
|
208
|
+
connectRequest.context = getContext(receivedEvent, origin);
|
|
209
|
+
this.eventHandler.handleConnect(connectRequest, getConnectResponseHandler(connectRequest, response));
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
case EventType.Connected: {
|
|
213
|
+
// for unblocking events, we responds to the service as early as possible
|
|
214
|
+
response.end();
|
|
215
|
+
const connectedRequest = receivedEvent.data;
|
|
216
|
+
connectedRequest.context = getContext(receivedEvent, origin);
|
|
217
|
+
this.eventHandler.onConnected(connectedRequest);
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
case EventType.Disconnected: {
|
|
221
|
+
// for unblocking events, we responds to the service as early as possible
|
|
222
|
+
response.end();
|
|
223
|
+
const disconnectedRequest = receivedEvent.data;
|
|
224
|
+
disconnectedRequest.context = getContext(receivedEvent, origin);
|
|
225
|
+
this.eventHandler.onDisconnected(disconnectedRequest);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
case EventType.UserEvent: {
|
|
229
|
+
let userRequest;
|
|
230
|
+
if (receivedEvent.data_base64 !== undefined) {
|
|
231
|
+
userRequest = {
|
|
232
|
+
context: getContext(receivedEvent, origin),
|
|
233
|
+
data: Buffer.from(receivedEvent.data_base64, "base64"),
|
|
234
|
+
dataType: "binary"
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
else if (receivedEvent.data !== undefined) {
|
|
238
|
+
userRequest = {
|
|
239
|
+
context: getContext(receivedEvent, origin),
|
|
240
|
+
data: receivedEvent.data,
|
|
241
|
+
dataType: ((_e = receivedEvent.datacontenttype) === null || _e === void 0 ? void 0 : _e.startsWith("application/json;"))
|
|
242
|
+
? "json"
|
|
243
|
+
: "text"
|
|
244
|
+
};
|
|
234
245
|
}
|
|
246
|
+
else {
|
|
247
|
+
throw new Error("Unexpected data.");
|
|
248
|
+
}
|
|
249
|
+
this.eventHandler.handleUserEvent(userRequest, getUserEventResponseHandler(userRequest, response));
|
|
250
|
+
return true;
|
|
235
251
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
readRequestBody(req) {
|
|
241
|
-
return new Promise(function (resolve, reject) {
|
|
242
|
-
const chunks = [];
|
|
243
|
-
req.on("data", function (chunk) {
|
|
244
|
-
chunks.push(chunk);
|
|
245
|
-
});
|
|
246
|
-
req.on("end", function () {
|
|
247
|
-
const buffer = Buffer.concat(chunks);
|
|
248
|
-
resolve(buffer.toString());
|
|
249
|
-
});
|
|
250
|
-
// reject on request error
|
|
251
|
-
req.on("error", function (err) {
|
|
252
|
-
// This is not a "Second reject", just a different sort of failure
|
|
253
|
-
reject(err);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
252
|
+
default:
|
|
253
|
+
logger.warning(`Unknown EventType ${eventType}`);
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
var EventType;
|
|
259
|
-
(function (EventType) {
|
|
260
|
-
EventType[EventType["Connect"] = 0] = "Connect";
|
|
261
|
-
EventType[EventType["Connected"] = 1] = "Connected";
|
|
262
|
-
EventType[EventType["Disconnected"] = 2] = "Disconnected";
|
|
263
|
-
EventType[EventType["UserEvent"] = 3] = "UserEvent";
|
|
264
|
-
})(EventType || (EventType = {}));
|
|
265
258
|
//# sourceMappingURL=cloudEventsDispatcher.js.map
|