@@ -300,15 +300,60 @@ export default class Component {
300300
301301 this . backendRequest . promise . then ( async ( response ) => {
302302 const backendResponse = new BackendResponse ( response ) ;
303- const html = await backendResponse . getBody ( ) ;
304303
305304 // clear sent files inputs
306305 for ( const input of Object . values ( this . pendingFiles ) ) {
307306 input . value = '' ;
308307 }
309308
310- // if the response does not contain a component, render as an error
311309 const headers = backendResponse . response . headers ;
310+ if ( headers . get ( 'X-Live-Download' ) ) {
311+ if (
312+ ! (
313+ headers . get ( 'Content-Disposition' ) ?. includes ( 'attachment' ) ||
314+ headers . get ( 'Content-Disposition' ) ?. includes ( 'inline' )
315+ ) ||
316+ ! headers . get ( 'Content-Disposition' ) ?. includes ( 'filename=' )
317+ ) {
318+ throw new Error ( 'Invalid LiveDownload response' ) ;
319+ }
320+
321+ const fileSize = Number . parseInt ( headers . get ( 'Content-Length' ) || '0' ) ;
322+ if ( fileSize > 10000000 ) {
323+ throw new Error ( 'File is too large to download (10MB limit)' ) ;
324+ }
325+
326+ const fileName = headers . get ( 'Content-Disposition' ) ?. split ( 'filename=' ) [ 1 ] ;
327+ if ( ! fileName ) {
328+ throw new Error ( 'No filename found in Content-Disposition header' ) ;
329+ }
330+
331+ const blob = await backendResponse . getBlob ( ) ;
332+ const link = Object . assign ( window . document . createElement ( 'a' ) , {
333+ target : '_blank' ,
334+ style : 'display: none' ,
335+ href : window . URL . createObjectURL ( blob ) ,
336+ download : fileName ,
337+ } ) ;
338+ this . element . appendChild ( link ) ;
339+ link . click ( ) ;
340+ this . element . removeChild ( link ) ;
341+
342+ this . backendRequest = null ;
343+ thisPromiseResolve ( backendResponse ) ;
344+
345+ // do we already have another request pending?
346+ if ( this . isRequestPending ) {
347+ this . isRequestPending = false ;
348+ this . performRequest ( ) ;
349+ }
350+
351+ return response ;
352+ }
353+
354+ const html = await backendResponse . getBody ( ) ;
355+
356+ // if the response does not contain a component, render as an error
312357 if (
313358 ! headers . get ( 'Content-Type' ) ?. includes ( 'application/vnd.live-component+html' ) &&
314359 ! headers . get ( 'X-Live-Redirect' )
0 commit comments