Skip to content

Commit a128e97

Browse files
authored
@tus/server: use srvx for req/res conversion (#749)
1 parent a5feda0 commit a128e97

File tree

9 files changed

+152
-261
lines changed

9 files changed

+152
-261
lines changed

.changeset/green-ducks-return.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tus/server": minor
3+
---
4+
5+
Use srvx for convert Node.js req/res to Request/Response. This also comes with a performance boost. When using `server.handle()` in a Node.js environment, you can now access the orignal req/res via `req.node.req`/`req.node.res`.

package-lock.json

Lines changed: 36 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
33
"private": true,
4+
"type": "module",
45
"workspaces": [
56
"packages/*",
67
"test"

packages/server/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ observability.
202202
The main server request handler invoked on every request.
203203
Use this to integrate into your existing Node.js server.
204204

205+
This handler converts `http.IncomingMessage`/`http.ServerResponse` to `Request`/`Response`.
206+
You can still access the Node.js versions via `req.node.req`/`req.node.res` in the hooks.
207+
205208
#### `server.handleWeb(req: Request)`
206209

207210
The main server request handler invoked on every request.

packages/server/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424
"@tus/utils": "^0.6.0",
2525
"debug": "^4.3.4",
2626
"lodash.throttle": "^4.1.1",
27-
"set-cookie-parser": "^2.7.1"
27+
"set-cookie-parser": "^2.7.1",
28+
"srvx": "^0.2.7"
2829
},
2930
"devDependencies": {
3031
"@types/debug": "^4.1.12",
3132
"@types/lodash.throttle": "^4.1.9",
3233
"@types/mocha": "^10.0.6",
33-
"@types/set-cookie-parser": "^2.4.10",
3434
"@types/node": "^22.13.7",
35+
"@types/set-cookie-parser": "^2.4.10",
3536
"@types/sinon": "^17.0.3",
3637
"@types/supertest": "^2.0.16",
3738
"mocha": "^11.0.1",

packages/server/src/server.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import http from 'node:http'
22
import {EventEmitter} from 'node:events'
33

4+
import type {ServerRequest} from 'srvx/types'
5+
import {toNodeHandler} from 'srvx/node'
46
import debug from 'debug'
57
import {EVENTS, ERRORS, EXPOSED_HEADERS, REQUEST_METHODS, TUS_RESUMABLE} from '@tus/utils'
68
import type {DataStore, Upload, CancellationContext} from '@tus/utils'
79

8-
import {BaseHandler} from './handlers/BaseHandler.js'
910
import {GetHandler} from './handlers/GetHandler.js'
1011
import {HeadHandler} from './handlers/HeadHandler.js'
1112
import {OptionsHandler} from './handlers/OptionsHandler.js'
@@ -15,7 +16,6 @@ import {DeleteHandler} from './handlers/DeleteHandler.js'
1516
import {validateHeader} from './validators/HeaderValidator.js'
1617
import type {ServerOptions, RouteHandler, WithOptional} from './types.js'
1718
import {MemoryLocker} from './lockers/index.js'
18-
import {getRequest, setResponse} from './web.js'
1919

2020
type Handlers = {
2121
GET: InstanceType<typeof GetHandler>
@@ -27,10 +27,10 @@ type Handlers = {
2727
}
2828

2929
interface TusEvents {
30-
[EVENTS.POST_CREATE]: (req: Request, upload: Upload, url: string) => void
31-
[EVENTS.POST_RECEIVE]: (req: Request, upload: Upload) => void
32-
[EVENTS.POST_FINISH]: (req: Request, res: Response, upload: Upload) => void
33-
[EVENTS.POST_TERMINATE]: (req: Request, res: Response, id: string) => void
30+
[EVENTS.POST_CREATE]: (req: ServerRequest, upload: Upload, url: string) => void
31+
[EVENTS.POST_RECEIVE]: (req: ServerRequest, upload: Upload) => void
32+
[EVENTS.POST_FINISH]: (req: ServerRequest, res: Response, upload: Upload) => void
33+
[EVENTS.POST_TERMINATE]: (req: ServerRequest, res: Response, id: string) => void
3434
}
3535

3636
type on = EventEmitter['on']
@@ -119,19 +119,11 @@ export class Server extends EventEmitter {
119119
}
120120

121121
get(path: string, handler: RouteHandler) {
122-
this.handlers.GET.registerPath(this.options.path + path, handler)
122+
this.handlers.GET.registerPath(path, handler)
123123
}
124124

125125
async handle(req: http.IncomingMessage, res: http.ServerResponse) {
126-
const {proto, host} = BaseHandler.extractHostAndProto(
127-
// @ts-expect-error it's fine
128-
new Headers(req.headers),
129-
this.options.respectForwardedHeaders
130-
)
131-
const base = `${proto}://${host}${this.options.path}`
132-
const webReq = await getRequest({request: req, base})
133-
const webRes = await this.handler(webReq)
134-
return setResponse(res, webRes)
126+
return toNodeHandler(this.handler.bind(this))(req, res)
135127
}
136128

137129
async handleWeb(req: Request) {
@@ -142,6 +134,19 @@ export class Server extends EventEmitter {
142134
const context = this.createContext()
143135
const headers = new Headers()
144136

137+
// @ts-expect-error temporary until https://github.com/unjs/srvx/issues/44 is fixed
138+
req.headers.get = (key: string) => {
139+
for (const [k, v] of req.headers.entries()) {
140+
if (k === key) {
141+
if (v === '') {
142+
return null
143+
}
144+
return v
145+
}
146+
}
147+
return null
148+
}
149+
145150
const onError = async (error: {
146151
status_code?: number
147152
body?: string
@@ -164,7 +169,7 @@ export class Server extends EventEmitter {
164169
if (req.method === 'GET') {
165170
const handler = this.handlers.GET
166171
const res = await handler.send(req, context, headers).catch(onError)
167-
context.abort
172+
context.abort()
168173
return res
169174
}
170175

0 commit comments

Comments
 (0)