2010-12-22 5 views
4

ich diesen Proxy-Code aus diesem article und erstellt als HttphandlerWie dekomprimieren HTML-Seiten Client-Seite

public void ProcessRequest(HttpContext context) 
{ 
     string url = context.Request["url"]; 
     string contentType = context.Request["type"]; 

     // no buffering as we want to save memory 
     context.Response.Buffer = false; 

     // beging getting content 
     using (WebClient client = new WebClient()) 
     { 

      // set content type if specified 
      if (!string.IsNullOrEmpty(contentType)) 
      { 
       client.Headers.Add(HttpRequestHeader.ContentType, contentType); 
      } 

      client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); 
      client.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US"); 
      client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows; U; Windows NT 6.0; " + 
       "en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");     
      client.Headers.Add(HttpRequestHeader.Accept, "*/*"); 

      // get that data 
      byte[] data = client.DownloadData(url); 

      if (!context.Response.IsClientConnected) return; 

      // deliver content type, encoding and length as it 
      // is received from the external url 
      context.Response.ContentType = client.ResponseHeaders["Content-Type"]; 

      string contentEncoding = client.ResponseHeaders["Content-Encoding"]; 
      string contentLength = client.ResponseHeaders["Content-Length"]; 

      if (!string.IsNullOrEmpty(contentEncoding)) 
       context.Response.AppendHeader(HttpRequestHeader.ContentEncoding.ToString(), contentEncoding); 

      if (!string.IsNullOrEmpty(contentLength)) 
       context.Response.AppendHeader(HttpRequestHeader.ContentLength.ToString(), contentLength); 


      // transmit the exact bytes downloaded 
      context.Response.BinaryWrite(data); 


    } 
} 

I zugeordnet habe dieses Http-Modul in IIS7 als Managed hanlder und in meine einfache HTML-Seite genommen haben Ich benutze jQuery, um den Proxy aufzurufen und die Ergebnisse in einen iframe zu schreiben.

$(document).ready(function() { 
    $.ajax({ 
     type: "GET", 
     url: "a.RegularProxy", 
     data: { url: 'http://example.org/test.html', type: "text/html" }, 
     dataType: "html", 
     success: function(data) { 
      $("iframe").contents().find('html body').html(data.toString()); 
     }, 
     error: function(XMLHttpRequest, textStatus, errorThrown) { 
      alert(errorThrown); 
     } 
    }); 
}); 

Alles funktioniert gut, wenn die Seite schön und einfach ist, aber wenn die Seite komprimiert (gzip, deflate) Ich brauche einen Weg, um decompress es auf der Client-Seite und nicht innerhalb des Proxy zu finden - Die Funktion des Proxys soll so schnell wie möglich sein.

Antwort

3

Browser führen die Dekomprimierung automatisch aus, basierend auf den HTTP-Headern.

Ich vermute, was passiert ist, dass die WebClient automatisch die Antwort dekomprimiert, wie es vom Upstream-Server erhalten wird. Ihr Code überträgt dann die dekomprimierte Information an den Client, teilt dem Client jedoch mit, dass die Daten komprimiert sind.

Es gibt keine Möglichkeit, direkt zu sagen, WebClient nicht zu dekomprimieren. Sie müssen die abgeleitete Klasse WebClient erstellen und die Methode GetWebRequest überschreiben. In dieser Methode sagen Sie der HttpWebRequest nicht zu dekomprimieren. Es wird wie folgt aussehen:

public class MyWebClient: WebClient 
{ 
    protected override WebRequest GetWebRequest(Uri address) 
    { 
     WebRequest wr = base.GetWebRequest(address); 
     wr.AutomaticDecompression = DecompressionMethods.None; 
     return wr; 
    } 
} 

Dann verwenden Sie die MyWebClient anstelle von WebClient:

using (MyWebClient client = new MyWebClient) 
{ 
    // do your thing here 
} 
+0

Ich bin nicht sicher, ob dies der Fall ist, zu Testzwecken ich einige zusätzliche Code hinzugefügt Führen Sie die Dekomprimierung innerhalb des Proxys durch, indem Sie die Header überprüfen. Die HTML-Seite, die vorher nicht angezeigt wurde, wird jetzt genau so angezeigt, wie sie sollte. Dies lässt mich glauben, dass WebClient die Antwort vor dem Schreiben in das Context-Objekt nicht automatisch dekomprimiert. – Rob

+0

Ich würde empfehlen, ein Testprogramm auf dem Client zu schreiben, mit dem Sie die Rohdaten vom Proxy sehen können. Wenn Sie die automatische Dekomprimierung auf dem Client deaktivieren, können Sie die Daten genau so anzeigen, wie sie übergeben wurden. Nur so können Sie sicher wissen, was passiert. Außerdem würde ich auf dem Proxy vorschlagen, die Bytes, die Sie erhalten, in eine Datei zu schreiben und den Inhalt zu untersuchen. So können Sie sicher wissen, was vor sich geht. –