@@ -7,6 +7,7 @@ import { ERRORS, isRenderableError } from '@internal/errors'
77import { Storage } from '@storage/storage'
88import { Uploader , validateMimeType } from '@storage/uploader'
99import { UploadId } from '@storage/protocols/tus'
10+ import type { ServerRequest as Request } from 'srvx'
1011
1112import { getConfig } from '../../../config'
1213
@@ -15,6 +16,19 @@ const reExtractFileID = /([^/]+)\/?$/
1516
1617export const SIGNED_URL_SUFFIX = '/sign'
1718
19+ /**
20+ * Validates that the request object exists and returns it
21+ * @throws {Error } If the request object is missing
22+ */
23+ function getNodeRequest ( rawReq : Request ) : MultiPartRequest {
24+ const req = rawReq . node ?. req as MultiPartRequest
25+
26+ if ( ! req ) {
27+ throw ERRORS . InternalError ( undefined , 'Request object is missing' )
28+ }
29+
30+ return req
31+ }
1832export type MultiPartRequest = http . IncomingMessage & {
1933 log : BaseLogger
2034 upload : {
@@ -30,14 +44,20 @@ export type MultiPartRequest = http.IncomingMessage & {
3044/**
3145 * Runs on every TUS incoming request
3246 */
33- export async function onIncomingRequest (
34- rawReq : http . IncomingMessage ,
35- res : http . ServerResponse ,
36- id : string
37- ) {
38- const req = rawReq as MultiPartRequest
47+ export async function onIncomingRequest ( rawReq : Request , id : string ) {
48+ const req = getNodeRequest ( rawReq )
49+ const res = rawReq . node ?. res as http . ServerResponse
50+
51+ if ( ! res ) {
52+ throw ERRORS . InternalError ( undefined , 'Response object is missing' )
53+ }
54+
55+ if ( ! res ) {
56+ throw ERRORS . InternalError ( undefined , 'Response object is missing' )
57+ }
3958
4059 res . on ( 'finish' , ( ) => {
60+ console . log ( 'Tus request finished' )
4161 req . upload . db . dispose ( ) . catch ( ( e ) => {
4262 req . log . error ( { error : e } , 'Error disposing db connection' )
4363 } )
@@ -88,9 +108,15 @@ export async function onIncomingRequest(
88108 * Generate URL for TUS upload, it encodes the uploadID to base64url
89109 */
90110export function generateUrl (
91- req : http . IncomingMessage ,
111+ rawReq : Request ,
92112 { proto, host, path, id } : { proto : string ; host : string ; path : string ; id : string }
93113) {
114+ const req = getNodeRequest ( rawReq )
115+
116+ if ( ! req . url ) {
117+ throw ERRORS . InvalidParameter ( 'url' )
118+ }
119+
94120 if ( ! req . url ) {
95121 throw ERRORS . InvalidParameter ( 'url' )
96122 }
@@ -127,8 +153,9 @@ export function generateUrl(
127153/**
128154 * Extract the uploadId from the request and decodes it from base64url
129155 */
130- export function getFileIdFromRequest ( rawRwq : http . IncomingMessage ) {
131- const req = rawRwq as MultiPartRequest
156+ export function getFileIdFromRequest ( rawReq : Request ) {
157+ const req = getNodeRequest ( rawReq )
158+
132159 const match = reExtractFileID . exec ( req . url as string )
133160
134161 if ( ! match || tusPath . includes ( match [ 1 ] ) ) {
@@ -145,11 +172,12 @@ export function getFileIdFromRequest(rawRwq: http.IncomingMessage) {
145172 *
146173 * /tenant-id/bucket-name/object-name/version
147174 */
148- export function namingFunction (
149- rawReq : http . IncomingMessage ,
150- metadata ?: Record < string , string | null >
151- ) {
152- const req = rawReq as MultiPartRequest
175+ export function namingFunction ( rawReq : Request , metadata ?: Record < string , string | null > ) {
176+ const req = getNodeRequest ( rawReq )
177+
178+ if ( ! req . url ) {
179+ throw new Error ( 'no url set' )
180+ }
153181
154182 if ( ! req . url ) {
155183 throw new Error ( 'no url set' )
@@ -177,13 +205,13 @@ export function namingFunction(
177205 * Runs before the upload URL is created
178206 */
179207export async function onCreate (
180- rawReq : http . IncomingMessage ,
181- res : http . ServerResponse ,
208+ rawReq : Request ,
182209 upload : Upload
183- ) : Promise < { res : http . ServerResponse ; metadata ?: Upload [ 'metadata' ] } > {
210+ ) : Promise < { metadata ?: Upload [ 'metadata' ] } > {
184211 const uploadID = UploadId . fromString ( upload . id )
185212
186- const req = rawReq as MultiPartRequest
213+ const req = getNodeRequest ( rawReq )
214+
187215 const storage = req . upload . storage
188216
189217 const bucket = await storage
@@ -204,18 +232,15 @@ export async function onCreate(
204232 validateMimeType ( metadata . contentType , bucket . allowed_mime_types )
205233 }
206234
207- return { res , metadata }
235+ return { metadata }
208236}
209237
210238/**
211239 * Runs when the upload to the underline store is completed
212240 */
213- export async function onUploadFinish (
214- rawReq : http . IncomingMessage ,
215- res : http . ServerResponse ,
216- upload : Upload
217- ) {
218- const req = rawReq as MultiPartRequest
241+ export async function onUploadFinish ( rawReq : Request , upload : Upload ) {
242+ const req = getNodeRequest ( rawReq )
243+
219244 const resourceId = UploadId . fromString ( upload . id )
220245
221246 try {
@@ -255,9 +280,11 @@ export async function onUploadFinish(
255280 userMetadata : customMd ,
256281 } )
257282
258- res . setHeader ( 'Tus-Complete' , '1' )
259-
260- return res
283+ return {
284+ headers : {
285+ 'Tus-Complete' : '1' ,
286+ } ,
287+ }
261288 } catch ( e ) {
262289 if ( isRenderableError ( e ) ) {
263290 ; ( e as any ) . status_code = parseInt ( e . render ( ) . statusCode , 10 )
@@ -272,11 +299,9 @@ type TusError = { status_code: number; body: string }
272299/**
273300 * Runs when there is an error on the TUS upload
274301 */
275- export function onResponseError (
276- req : http . IncomingMessage ,
277- _ : http . ServerResponse ,
278- e : TusError | Error
279- ) {
302+ export function onResponseError ( rawReq : Request , e : TusError | Error ) {
303+ const req = getNodeRequest ( rawReq )
304+
280305 if ( e instanceof Error ) {
281306 ; ( req as any ) . executionError = e
282307 } else {
0 commit comments