Skip to content

Commit 518dc80

Browse files
authored
Reuse azure logger and move endpoint setting into options (#18359)
1 parent f2a1e38 commit 518dc80

15 files changed

+140
-117
lines changed

sdk/web-pubsub/web-pubsub-express/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"sideEffects": false,
5858
"dependencies": {
5959
"tslib": "^2.2.0",
60+
"@azure/logger": "^1.0.0",
6061
"cloudevents": "^4.0.0"
6162
},
6263
"devDependencies": {

sdk/web-pubsub/web-pubsub-express/review/web-pubsub-express.api.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface ConnectRequest {
3232
claims?: Record<string, string[]>;
3333
clientCertificates?: Certificate[];
3434
context: ConnectionContext;
35+
headers?: Record<string, string[]>;
3536
queries?: Record<string, string[]>;
3637
subprotocols?: string[];
3738
}
@@ -77,22 +78,21 @@ export interface UserEventResponseHandler {
7778

7879
// @public
7980
export class WebPubSubEventHandler {
80-
constructor(hub: string, allowedEndpoints: string[], options?: WebPubSubEventHandlerOptions);
81+
constructor(hub: string, options?: WebPubSubEventHandlerOptions);
8182
getMiddleware(): express.RequestHandler;
8283
readonly path: string;
8384
}
8485

8586
// @public
8687
export interface WebPubSubEventHandlerOptions {
87-
dumpRequest?: boolean;
88+
allowedEndpoints?: string[];
8889
handleConnect?: (connectRequest: ConnectRequest, connectResponse: ConnectResponseHandler) => void;
8990
handleUserEvent?: (userEventRequest: UserEventRequest, userEventResponse: UserEventResponseHandler) => void;
9091
onConnected?: (connectedRequest: ConnectedRequest) => void;
9192
onDisconnected?: (disconnectedRequest: DisconnectedRequest) => void;
9293
path?: string;
9394
}
9495

95-
9696
// (No @packageDocumentation comment for this package)
9797

9898
```

sdk/web-pubsub/web-pubsub-express/samples-dev/server.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
99
import express from "express";
1010

11-
const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.com"], {
12-
dumpRequest: false,
11+
const handler = new WebPubSubEventHandler("chat", {
1312
handleConnect(req, res) {
1413
console.log(req);
1514
// You can set the state for the connection, it lasts throughout the lifetime of the connection
@@ -27,7 +26,8 @@ const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.
2726
// You can also set the state here
2827
res.setState("calledTime", calledTime);
2928
res.success("Hello", "text");
30-
}
29+
},
30+
allowedEndpoints: ["https://xxx.webpubsub.azure.com"]
3131
});
3232

3333
const app = express();

sdk/web-pubsub/web-pubsub-express/samples/v1/javascript/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/web-pubsub/web-pubsub-express",
2424
"dependencies": {
2525
"@azure/web-pubsub-express": "next",
26-
"dotenv": "latest"
26+
"dotenv": "latest",
27+
"express": "^4.17.1"
2728
}
2829
}

sdk/web-pubsub/web-pubsub-express/samples/v1/javascript/server.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
const { WebPubSubEventHandler } = require("@azure/web-pubsub-express");
99
const express = require("express");
1010

11-
const handler = new WebPubSubEventHandler("chat", ["https://xxx.webpubsub.azure.com"], {
12-
dumpRequest: false,
11+
const handler = new WebPubSubEventHandler("chat", {
12+
path: "/api/webpubsub",
1313
handleConnect(req, res) {
1414
console.log(req);
1515
res.success();

sdk/web-pubsub/web-pubsub-express/src/cloudEventsDispatcher.ts

+26-24
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import { HTTP, CloudEvent } from "cloudevents";
55
import { IncomingMessage, ServerResponse } from "http";
66
import { URL } from "url";
7-
7+
import { logger } from "./logger";
88
import * as utils from "./utils";
99

1010
import {
@@ -14,9 +14,9 @@ import {
1414
DisconnectedRequest,
1515
ConnectedRequest,
1616
ConnectionContext,
17-
WebPubSubEventHandlerOptions,
1817
ConnectResponseHandler,
19-
UserEventResponseHandler
18+
UserEventResponseHandler,
19+
WebPubSubEventHandlerOptions
2020
} from "./cloudEventsProtocols";
2121

2222
enum EventType {
@@ -137,24 +137,27 @@ function tryGetWebPubSubEvent(req: IncomingMessage): EventType | undefined {
137137
}
138138
}
139139

140+
function isWebPubSubRequest(req: IncomingMessage): boolean {
141+
return utils.getHttpHeader(req, "ce-awpsversion") !== undefined;
142+
}
143+
140144
/**
141145
* @internal
142146
*/
143147
export class CloudEventsDispatcher {
144-
private readonly _dumpRequest: boolean;
145-
private readonly _allowedOrigins: string[];
146-
constructor(
147-
private hub: string,
148-
allowedEndpoints: string[],
149-
private eventHandler?: WebPubSubEventHandlerOptions
150-
) {
151-
this._dumpRequest = eventHandler?.dumpRequest ?? false;
152-
this._allowedOrigins = allowedEndpoints.map((endpoint) =>
153-
endpoint === "*" ? "*" : new URL(endpoint).host
154-
);
148+
private readonly _allowedOrigins = ["*"];
149+
constructor(private hub: string, private eventHandler?: WebPubSubEventHandlerOptions) {
150+
if (eventHandler?.allowedEndpoints !== undefined) {
151+
this._allowedOrigins = eventHandler.allowedEndpoints.map((endpoint) =>
152+
endpoint === "*" ? "*" : new URL(endpoint).host
153+
);
154+
}
155155
}
156156

157-
public processValidateRequest(req: IncomingMessage, res: ServerResponse): boolean {
157+
public handlePreflight(req: IncomingMessage, res: ServerResponse): boolean {
158+
if (!isWebPubSubRequest(req)) {
159+
return false;
160+
}
158161
if (req.headers["webhook-request-origin"]) {
159162
res.setHeader("WebHook-Allowed-Origin", this._allowedOrigins);
160163
res.end();
@@ -164,10 +167,11 @@ export class CloudEventsDispatcher {
164167
}
165168
}
166169

167-
public async processRequest(
168-
request: IncomingMessage,
169-
response: ServerResponse
170-
): Promise<boolean> {
170+
public async handleRequest(request: IncomingMessage, response: ServerResponse): Promise<boolean> {
171+
if (!isWebPubSubRequest(request)) {
172+
return false;
173+
}
174+
171175
// check if it is a valid WebPubSub cloud events
172176
const origin = utils.getHttpHeader(request, "webhook-request-origin");
173177
if (origin === undefined) {
@@ -213,16 +217,14 @@ export class CloudEventsDispatcher {
213217
}
214218
break;
215219
default:
216-
console.warn(`Unknown EventType ${eventType}`);
220+
logger.warning(`Unknown EventType ${eventType}`);
217221
return false;
218222
}
219223

220224
const eventRequest = await utils.convertHttpToEvent(request);
221225
const receivedEvent = HTTP.toEvent(eventRequest);
222226

223-
if (this._dumpRequest) {
224-
console.log(receivedEvent);
225-
}
227+
logger.verbose(receivedEvent);
226228

227229
switch (eventType) {
228230
case EventType.Connect: {
@@ -277,7 +279,7 @@ export class CloudEventsDispatcher {
277279
return true;
278280
}
279281
default:
280-
console.warn(`Unknown EventType ${eventType}`);
282+
logger.warning(`Unknown EventType ${eventType}`);
281283
return false;
282284
}
283285
}

sdk/web-pubsub/web-pubsub-express/src/cloudEventsProtocols.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ export interface ConnectRequest {
7373
* The queries that the client WebSocket connection has when it connects.
7474
*/
7575
queries?: Record<string, string[]>;
76+
/**
77+
* The headers that the client WebSocket connection has when it connects.
78+
*/
79+
headers?: Record<string, string[]>;
7680
/**
7781
* The subprotocols that the client WebSocket connection uses to do handshake.
7882
*/
@@ -208,11 +212,6 @@ export interface WebPubSubEventHandlerOptions {
208212
*/
209213
path?: string;
210214

211-
/**
212-
* Configures if you'd like to dump the incoming HTTP request.
213-
*/
214-
dumpRequest?: boolean;
215-
216215
/**
217216
* Handle 'connect' event, the service waits for the response to proceed.
218217
*/
@@ -236,4 +235,9 @@ export interface WebPubSubEventHandlerOptions {
236235
* Event triggers for "disconnected" unblocking event. This is an unblocking event and the service does not wait for the response.
237236
*/
238237
onDisconnected?: (disconnectedRequest: DisconnectedRequest) => void;
238+
239+
/**
240+
* If not specified, by default allow all the endpoints, otherwise only allow specified endpoints
241+
*/
242+
allowedEndpoints?: string[];
239243
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
import { createClientLogger } from "@azure/logger";
5+
6+
/**
7+
* The \@azure/logger configuration for this package.
8+
*
9+
* @internal
10+
*/
11+
export const logger = createClientLogger("web-pubsub-express");

sdk/web-pubsub/web-pubsub-express/src/webPubSubEventHandler.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class WebPubSubEventHandler {
2525
* import express from "express";
2626
* import { WebPubSubEventHandler } from "@azure/web-pubsub-express";
2727
* const endpoint = "https://xxxx.webpubsubdev.azure.com"
28-
* const handler = new WebPubSubEventHandler('chat', [ endpoint ] {
28+
* const handler = new WebPubSubEventHandler('chat', {
2929
* handleConnect: (req, res) => {
3030
* console.log(JSON.stringify(req));
3131
* return {};
@@ -37,22 +37,18 @@ export class WebPubSubEventHandler {
3737
* console.log(JSON.stringify(req));
3838
* res.success("Hey " + req.data, req.dataType);
3939
* };
40+
* allowedEndpoints: [ endpoint ]
4041
* },
4142
* });
4243
* ```
4344
*
4445
* @param hub - The name of the hub to listen to
45-
* @param allowedEndpoints - The allowed endpoints for the incoming CloudEvents request
4646
* @param options - Options to configure the event handler
4747
*/
48-
constructor(
49-
private hub: string,
50-
allowedEndpoints: string[],
51-
options?: WebPubSubEventHandlerOptions
52-
) {
48+
constructor(private hub: string, options?: WebPubSubEventHandlerOptions) {
5349
const path = (options?.path ?? `/api/webpubsub/hubs/${hub}/`).toLowerCase();
5450
this.path = path.endsWith("/") ? path : path + "/";
55-
this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, allowedEndpoints, options);
51+
this._cloudEventsHandler = new CloudEventsDispatcher(this.hub, options);
5652
}
5753

5854
/**
@@ -71,12 +67,12 @@ export class WebPubSubEventHandler {
7167
requestUrl = requestUrl.endsWith("/") ? requestUrl : requestUrl + "/";
7268
if (requestUrl.startsWith(this.path)) {
7369
if (req.method === "OPTIONS") {
74-
if (this._cloudEventsHandler.processValidateRequest(req, res)) {
70+
if (this._cloudEventsHandler.handlePreflight(req, res)) {
7571
return;
7672
}
7773
} else if (req.method === "POST") {
7874
try {
79-
if (await this._cloudEventsHandler.processRequest(req, res)) {
75+
if (await this._cloudEventsHandler.handleRequest(req, res)) {
8076
return;
8177
}
8278
} catch (err) {

0 commit comments

Comments
 (0)