Skip to content

Commit

Permalink
@tus/server: add lastPath arg to getFileIdFromRequest (#626)
Browse files Browse the repository at this point in the history
* @tus/server: add `lastPath` arg to `getFileIdFromRequest`

* Changeset
  • Loading branch information
Murderlon authored Jun 12, 2024
1 parent 117e1b2 commit ea2bf07
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-kiwis-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tus/server': minor
---

Add `lastPath` argument to `getFileIdFromRequest` to simplify a common use case.
30 changes: 15 additions & 15 deletions packages/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,11 @@ Checkout the example how to

#### `options.getFileIdFromRequest`

Control how the Upload-ID is extracted from the request (`(req) => string | void`) By
default, it expects everything in the path after the last `/` to be the upload id.
Control how the Upload-ID is extracted from the request
(`(req, lastPath) => string | void`)

By default, it expects everything in the path after the last `/` to be the upload id.
`lastPath` is everything after the last `/`.

Checkout the example how to
[store files in custom nested directories](#example-store-files-in-custom-nested-directories).
Expand Down Expand Up @@ -157,7 +160,8 @@ This can be used to implement validation of upload metadata or add headers.
#### `options.onUploadFinish`

`onUploadFinish` will be invoked after an upload is completed but before a response is
returned to the client (`(req, res, upload) => Promise<{ res: http.ServerResponse, status_code?: number, headers?: Record<string, string | number>, body?: string }>`).
returned to the client
(`(req, res, upload) => Promise<{ res: http.ServerResponse, status_code?: number, headers?: Record<string, string | number>, body?: string }>`).

- You can optionally return `status_code`, `headers` and `body` to modify the response.
Note that the tus specification does not allow sending response body nor status code
Expand Down Expand Up @@ -254,8 +258,9 @@ Called every [`postReceiveInterval`](#optionspostreceiveinterval) milliseconds f
upload while it‘s being written to the store.
This means you are not guaranteed to get (all) events for an upload. For instance if
`postReceiveInterval` is set to 1000ms and an PATCH request takes 500ms, no event is emitted.
If the PATCH request takes 2500ms, you would get the offset at 2000ms, but not at 2500ms.
`postReceiveInterval` is set to 1000ms and an PATCH request takes 500ms, no event is
emitted. If the PATCH request takes 2500ms, you would get the offset at 2000ms, but not at
2500ms.
Use `POST_FINISH` if you need to know when an upload is done.
Expand Down Expand Up @@ -543,18 +548,13 @@ const server = new Server({
id = Buffer.from(id, 'utf-8').toString('base64url')
return `${proto}://${host}${path}/${id}`
},
getFileIdFromRequest(req) {
const reExtractFileID = /([^/]+)\/?$/
const match = reExtractFileID.exec(req.url as string)

if (!match || path.includes(match[1])) {
return
}

return Buffer.from(match[1], 'base64url').toString('utf-8')
getFileIdFromRequest(req, lastPath) {
// lastPath is everything after the last `/`
// If your custom URL is different, this might be undefined
// and you need to extract the ID yourself
return Buffer.from(lastPath, 'base64url').toString('utf-8')
},
})

```
### Example: use with Nginx
Expand Down
6 changes: 4 additions & 2 deletions packages/server/src/handlers/BaseHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ export class BaseHandler extends EventEmitter {
}

getFileIdFromRequest(req: http.IncomingMessage) {
const match = reExtractFileID.exec(req.url as string)

if (this.options.getFileIdFromRequest) {
return this.options.getFileIdFromRequest(req)
const lastPath = match ? decodeURIComponent(match[1]) : undefined
return this.options.getFileIdFromRequest(req, lastPath)
}
const match = reExtractFileID.exec(req.url as string)

if (!match || this.options.path.includes(match[1])) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type ServerOptions = {
* Control how the Upload-ID is extracted from the request.
* @param req - The incoming HTTP request.
*/
getFileIdFromRequest?: (req: http.IncomingMessage) => string | void
getFileIdFromRequest?: (req: http.IncomingMessage, lastPath?: string) => string | void

/**
* Control how you want to name files.
Expand Down
9 changes: 3 additions & 6 deletions packages/server/test/Server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,12 @@ describe('Server', () => {
id = Buffer.from(id, 'utf-8').toString('base64url')
return `${proto}://${host}${path}/${id}`
},
getFileIdFromRequest(req) {
const reExtractFileID = /([^/]+)\/?$/
const match = reExtractFileID.exec(req.url as string)

if (!match || route.includes(match[1])) {
getFileIdFromRequest(req, lastPath) {
if (!lastPath) {
return
}

return Buffer.from(match[1], 'base64url').toString('utf-8')
return Buffer.from(lastPath, 'base64url').toString('utf-8')
},
})
const length = Buffer.byteLength('test', 'utf8').toString()
Expand Down

0 comments on commit ea2bf07

Please sign in to comment.