| 446 | } |
| 447 | |
| 448 | public attachApp(app /*: TemplatedApp */, opts: Partial<ServerOptions> = {}) { |
| 449 | // merge the options passed to the Socket.IO server |
| 450 | Object.assign(opts, this.opts); |
| 451 | // set engine.io path to `/socket.io` |
| 452 | opts.path = opts.path || this._path; |
| 453 | |
| 454 | // initialize engine |
| 455 | debug("creating uWebSockets.js-based engine with opts %j", opts); |
| 456 | const engine = new uServer(opts); |
| 457 | |
| 458 | engine.attach(app, opts); |
| 459 | |
| 460 | // bind to engine events |
| 461 | this.bind(engine); |
| 462 | |
| 463 | if (this._serveClient) { |
| 464 | // attach static file serving |
| 465 | app.get(`${this._path}/*`, (res, req) => { |
| 466 | if (!this.clientPathRegex.test(req.getUrl())) { |
| 467 | req.setYield(true); |
| 468 | return; |
| 469 | } |
| 470 | |
| 471 | const filename = req |
| 472 | .getUrl() |
| 473 | .replace(this._path, "") |
| 474 | .replace(/\?.*$/, "") |
| 475 | .replace(/^\//, ""); |
| 476 | const isMap = dotMapRegex.test(filename); |
| 477 | const type = isMap ? "map" : "source"; |
| 478 | |
| 479 | // Per the standard, ETags must be quoted: |
| 480 | // https://tools.ietf.org/html/rfc7232#section-2.3 |
| 481 | const expectedEtag = '"' + clientVersion + '"'; |
| 482 | const weakEtag = "W/" + expectedEtag; |
| 483 | |
| 484 | const etag = req.getHeader("if-none-match"); |
| 485 | if (etag) { |
| 486 | if (expectedEtag === etag || weakEtag === etag) { |
| 487 | debug("serve client %s 304", type); |
| 488 | res.writeStatus("304 Not Modified"); |
| 489 | res.end(); |
| 490 | return; |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | debug("serve client %s", type); |
| 495 | |
| 496 | res.writeHeader("cache-control", "public, max-age=0"); |
| 497 | res.writeHeader( |
| 498 | "content-type", |
| 499 | "application/" + (isMap ? "json" : "javascript") + "; charset=utf-8" |
| 500 | ); |
| 501 | res.writeHeader("etag", expectedEtag); |
| 502 | |
| 503 | const filepath = path.join(__dirname, "../client-dist/", filename); |
| 504 | serveFile(res, filepath); |
| 505 | }); |