2010-02-01 16 views
9

Ecco il programma di installazione:Protezione Download di grandi dimensioni con C# e IIS 7

  • 1 server Web che esegue un C# app a cui i miei utenti (memorizzati in un database MySQL su detti server) autenticare.

  • 1 file server con software in esecuzione TBD. In passato ho usato lighttpd e mod_secdownload per proteggere i file sui file server, e ha funzionato bene (ish).

Mi chiedo se c'è un modo per farlo utilizzando una combinazione di IIS e C# .Net. Tutti i miei altri server stanno eseguendo quella combinazione e semplificheranno un po 'le cose se potessi fare lo stesso per i file server. Il kicker è, i file che sono ospitati sono grandi. Ho visto esempi di persone che utilizzano una piccola app per creare un oggetto FileStream, leggere il file e creare manualmente la risposta HTTP. Funziona, ma dal momento che sto lavorando con i file con dimensioni di oltre 500 MB, è lento come diamine. E potenzialmente avrò 300 utenti che colpiscono la scatola in una sola volta, richiedendo i file. Non va bene.

Quindi, qualcuno vede un modo per aggirare questo? Sto cercando di creare un sistema più trasparente e, se tutti i miei server eseguono lo stesso software/hardware, renderà la mia vita molto più semplice. Grazie in anticipo per ogni consiglio che dai!

+0

È il vostro C# app ASP.NET * Webforms * o * * MVC? –

+0

L'app che gli utenti utilizzano per autenticare è un'applicazione Web C# .Net 3.5. –

risposta

6

Sai cosa? L'articolo KB è cacca. Ecco la mia raccomandazione ufficiale:

public void StreamFile(string filePath) 
{ 
    string fileName = Path.GetFileName(filePath); 

    using (var fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
     var contentLength = fStream.Length; 

     if (Request.UserAgent.Contains("MSIE")) 
     { 
      Response.AddHeader("Content-Transfer-Encoding", "binary"); 
     } 

     Response.ContentType = "application/octet-stream"; 
     Response.AddHeader("Content-Length", contentLength.ToString()); 

     // Even though "Content-Disposition" should have an upper-case "d", as per http://www.ietf.org/rfc/rfc2183.txt 
     // IE fails to recognize this if the "d" is upper-cased. 
     Response.AddHeader("Content-disposition", "attachment; filename=" + fileName); 

     var buffer = new byte[8192]; 

     while (Response.IsClientConnected) 
     { 
      var count = fStream.Read(buffer, 0, buffer.Length); 
      if (count == 0) 
      { 
       break; 
      } 

      Response.OutputStream.Write(buffer, 0, count); 
      Response.Flush(); 
     } 
    } 

    Response.Close(); 
} 
+0

Dopo aver dato un tentativo, mi sembra che carichi ancora il file in memoria. Almeno, stavo finendo le eccezioni di memoria quando l'ho provato su un file da 1,5 GB, e mi sono stancato di aspettare il download su uno da 450MB. Lo sto facendo su una macchina di prova, non sul file server, quindi la quantità di memoria con cui devo lavorare è inferiore. I miei server di file hanno una tonn di ram (24 GB credo) ma mi piacerebbe una soluzione che non richiede molto sforzo sul processore o memoria. Lighttpd lo fa usando il mod_secdownload e le regole di riscrittura degli URL, che è veloce ed economico su cicli/memoria. –

+0

@john: il modo in cui leggo il codice in Reflector, nessuno dei metodi MS per la scrittura di file utilizza effettivamente buffer di piccole dimensioni. Sembrano tutti allocare un singolo buffer per l'intero file. Alcuni di questi sono abbastanza difficili da individuare, quindi forse mi manca qualcosa. – Ray

+1

@Sheep Slapper: http://support.microsoft.com/kb/812406 – user7116

1

This thread ha la mia soluzione per mantenere l'utilizzo della memoria verso il basso mentre gli utenti stanno scaricando i file. Probabilmente vuoi un buffer più grande di quello che uso il mio campione.

+0

Dopo aver letto quel thread e l'articolo di supporto Microsoft nella risposta sopra, sono diretto in quella direzione per una soluzione temporanea. È meglio che ci siano meno applicazioni coinvolte nel processo, ma non è così trasparente in quello che sta succedendo. Ora devo solo sviluppare una piccola app per implementarla e creare la mia versione di mod_secdownload poiché l'app che convalida i miei utenti non si trova sui file server! Grazie per le informazioni! –

0

Sebbene questo non sia direttamente applicabile poiché si utilizza MySql ma è qualcosa da considerare (potrebbe anche essere disponibile gratuitamente utilizzando SQL Server 2008 Express). Sql Server 2008 offre il supporto Filestream che consente di accedere ai file come se fossero memorizzati direttamente nel database ma risiedano effettivamente su un server dei file. Quindi le informazioni sugli altri post possono aiutarti a ottenerle all'utente.

FILESTREAM Storage in SQL Server 2008

Problemi correlati