Sfondo
La mia applicazione Web vive su un server centralizzato nella "rete" del prodotto e fornisce i mezzi per gestire / configurare vari dispositivi distribuiti. Il server registra anche varie statistiche che arrivano da ciascun dispositivo, memorizzandole su disco in /var/log/
. La GUI Web consente agli utenti di scaricare tali registri.
Ha anche la possibilità di scaricarli in vari formati diversi, il che richiede una traduzione / conversione al volo. Questa conversione richiede un po 'di tempo (diciamo nell'ordine di trenta secondi) e genera file di dimensioni nella regione di 300 MB.
Tutto questo va bene e un utente può accettare che il download di un file convertito richiederà un po 'di tempo. Ma ho architettato me stesso in un angolo in termini di quanto effettivamente posso effettivamente consegnare questi file.
Ai fini di questa domanda, non esplorerò le soluzioni AJAX / JavaScript / Java / Flash / multi-step / multi-pagina. Supponiamo che, dal punto di vista dell'agente utente, il download sia una semplice richiesta HTTP GET a uno script CGI facendo clic su un elemento <a>
, e nient'altro.
Problema
La mia applicazione web è vagamente architettonica MVC in modo tale che il controller scelto per soddisfare l'azione richiesta (diciamo, in questo caso: l'azione "dispositivi" del controller "getConvertedLog") esegue la sua logica di business e imposta vari flag che descrivono come deve essere composta la risposta HTTP. Solo dopo che il controller ha terminato il suo lavoro verrà composta la risposta HTTP, con le intestazioni di risposta generate e il corpo in streaming da, in questo caso, un file temporaneo su disco.
Il primo problema è che il controller esegue (o almeno invoca) la conversione del file, impiega del tempo per essere eseguito. Di conseguenza, le intestazioni HTTP non vengono generate (per non dire trasferite) per trenta secondi circa. Non solo ciò comporta trenta secondi di letteralmente nulla che accade nel browser (almeno dalla mia esperienza in Chrome) ma mette anche l'intera richiesta ad alto rischio di un errore HTTP 504 Timeout gateway dall'intervenire router.
Potrei mescolare il mio codice un po 'in modo che alcune intestazioni di risposta HTTP possano essere trasferite al browser prima la conversione abbia inizio, per fornire almeno un'indicazione che qualcosa sta accadendo (e, si spera, allontanare il Timeout del gateway ). Ma prima che la conversione sia completa, non ho modo di sapere quanti byte comprenderanno il risultato. Pertanto, non posso inviare un'intestazione Content-Length
significativa, quindi l'utente-agente non può mostrare l'avanzamento all'utente. E per un file da 300 MB non lo ritengo accettabile.
Il secondo problema con questo è che, se c'è un errore durante la conversione, il codice di risposta HTTP dovrebbe essere significativo. Quindi non posso aver inviato un Status
in queste ipotetiche intestazioni di pre-conversione.
Domanda
Cosa faresti qui? Quello che è il minimo che devo fare indica agli user-agent e ai proxy che la richiesta è stata accettata e una risposta sta arrivando (anche se lentamente), prima il successo o l'insuccesso e la dimensione della risposta è stata determinata ?
Suppongo che sarebbe l'ideale se fosse legale e funzionale inviare un set di intestazioni molto piccolo, ad esempio:
Status: 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="thefile.zip"
... quindi seguilo con le restanti intestazioni ( Set-Cookie
, Cache-Control
, Content-Length
e così via), alcune sostituendo potenzialmente quelle precedenti (come una modifica in Status
) e, infine, il corpo della risposta .
Spero che il modulo CGI di Apache traduca e riordini alcune intestazioni (ad esempio Status: 200
finisce nella prima riga della risposta come HTTP/1.1 200 OK
) può aiutare qui. In che modo potrebbe l'elaborazione HTTP 102 in elaborazione qui?
( Aggiornamento: "Almeno un CGI-Header deve essere fornito, ma nessuna intestazione CGI può essere ripetuta con lo stesso nome-campo." [ CGI 1.1, §9.2 ]. Rats.)