@@ -25,16 +25,21 @@ const callHandler = async () => {
2525 return mod . default
2626}
2727
28- const fakeEvent = ( ) =>
28+ const fakeEvent = ( headers : Record < string , string > = { } ) =>
2929 ( {
30- node : { req : { method : "POST" , headers : { "content-type" : "multipart/form-data" } } } ,
30+ node : { req : { method : "POST" , headers : { "content-type" : "multipart/form-data" , ... headers } } } ,
3131 context : { } ,
3232 } ) as unknown as Parameters < Awaited < ReturnType < typeof callHandler > > > [ 0 ]
3333
3434const mockMultipart = ( parts : Array < { name : string ; filename ?: string ; type ?: string ; data : Buffer } > ) => {
3535 vi . doMock ( "h3" , async ( importOriginal ) => {
3636 const actual = await importOriginal < typeof import ( "h3" ) > ( )
37- return { ...actual , readMultipartFormData : async ( ) => parts }
37+ return {
38+ ...actual ,
39+ readMultipartFormData : async ( ) => parts ,
40+ getRequestHeader : ( event : { node : { req : { headers : Record < string , string > } } } , name : string ) =>
41+ event . node . req . headers [ name . toLowerCase ( ) ] ,
42+ }
3843 } )
3944}
4045
@@ -139,6 +144,28 @@ describe("direct handler", () => {
139144 await expect ( handler ( fakeEvent ( ) ) ) . rejects . toMatchObject ( { statusCode : 500 } )
140145 } )
141146
147+ it ( "rejects with 413 when Content-Length exceeds maxBodySize, before authorize/read" , async ( ) => {
148+ const storage = stubStorage ( )
149+ const authorize = vi . fn ( async ( ) => ( { } ) )
150+ userConfig = { storage, authorize, maxBodySize : 100 }
151+
152+ mockMultipart ( [ { name : "file" , filename : "big.bin" , type : "application/octet-stream" , data : Buffer . from ( "x" ) } ] )
153+ const handler = await callHandler ( )
154+ await expect ( handler ( fakeEvent ( { "content-length" : "500" } ) ) ) . rejects . toMatchObject ( { statusCode : 413 } )
155+ expect ( authorize ) . not . toHaveBeenCalled ( )
156+ expect ( storage . put ) . not . toHaveBeenCalled ( )
157+ } )
158+
159+ it ( "passes when Content-Length is within maxBodySize" , async ( ) => {
160+ const storage = stubStorage ( )
161+ userConfig = { storage, maxBodySize : 1000 }
162+
163+ mockMultipart ( [ { name : "file" , filename : "small.png" , type : "image/png" , data : Buffer . from ( "pix" ) } ] )
164+ const handler = await callHandler ( )
165+ const result = await handler ( fakeEvent ( { "content-length" : "50" } ) )
166+ expect ( result . fileId ) . toMatch ( / ^ u p l o a d s \/ / )
167+ } )
168+
142169 it ( "falls back to uploads/{fileId} when adapter has no resolveKey" , async ( ) => {
143170 const storage : StorageAdapter & { put : ReturnType < typeof vi . fn > } = {
144171 id : "stub" ,
0 commit comments