(
req: Request,
socket: stream.Duplex,
head: Buffer,
)
| 413 | } |
| 414 | |
| 415 | protected async handleWebSocketUnsafe( |
| 416 | req: Request, |
| 417 | socket: stream.Duplex, |
| 418 | head: Buffer, |
| 419 | ) { |
| 420 | const request = req as http.IncomingMessage; |
| 421 | request.url = moveTokenToHeader(request); |
| 422 | |
| 423 | this.logger.trace( |
| 424 | `Handling inbound WebSocket request on "${request.url || ''}"`, |
| 425 | ); |
| 426 | const proceed = await this.hooks.before({ head, req, socket }); |
| 427 | req.parsed = convertPathToURL(request.url || '', this.config); |
| 428 | shimLegacyRequests(req.parsed); |
| 429 | |
| 430 | if (!proceed) return; |
| 431 | |
| 432 | req.queryParams = queryParamsToObject(req.parsed.searchParams); |
| 433 | |
| 434 | const route = await this.router.getRouteForWebSocketRequest(req); |
| 435 | |
| 436 | if (route) { |
| 437 | this.logger.trace( |
| 438 | `Found matching WebSocket route handler "${route.path}"`, |
| 439 | ); |
| 440 | |
| 441 | if (route.before && !(await route.before(req, socket, head))) { |
| 442 | return; |
| 443 | } |
| 444 | |
| 445 | if (route?.auth) { |
| 446 | this.logger.trace( |
| 447 | `Authorizing WebSocket request to "${req.parsed.href}"`, |
| 448 | ); |
| 449 | const isPermitted = await this.token.isAuthorized(req, route); |
| 450 | |
| 451 | if (!isPermitted) { |
| 452 | return this.onWebsocketUnauthorized(req, socket); |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | if (route.querySchema) { |
| 457 | this.logger.trace(`Validating route query-params with QUERY schema`); |
| 458 | try { |
| 459 | const schema = compileSchema(route.querySchema); |
| 460 | const valid = schema.validate(req.queryParams); |
| 461 | |
| 462 | if (valid.error) { |
| 463 | const errorDetails = valid.error.details |
| 464 | .map( |
| 465 | ({ |
| 466 | message, |
| 467 | context, |
| 468 | }: { |
| 469 | context?: { message: string }; |
| 470 | message: string; |
| 471 | }) => context?.message || message, |
| 472 | ) |
no test coverage detected