28

Qualche idea sul perché su alcuni collegamenti a cui provo ad accedere usando HttpWebRequest mi viene restituito "Il server remoto ha restituito un errore: (304) Non modificato." nel codice?Perché ottengo l'errore "(304) Non modificato" su alcuni collegamenti quando si utilizza HttpWebRequest?

Il codice che sto usando è da Jeff's post here (la pagina sembra essere scomparsa, vedere archive copy at the Wayback Machine).

Nota il concetto del codice è un semplice server proxy, quindi sto puntando il mio browser su questo pezzo di codice localmente in esecuzione, che ottiene la richiesta del mio browser, e poi lo inoltra creando una nuova HttpWebRequest, come tu Vedremo nel codice. Funziona alla grande per la maggior parte dei siti/link, ma per alcuni questo errore si presenta. Vedrete un bit di chiave nel codice è dove sembra copiare le impostazioni dell'intestazione http dalla richiesta del browser alla sua richiesta al sito, e copia negli attributi dell'intestazione. Non sei sicuro se il problema riguardi il modo in cui simula questo aspetto della richiesta e cosa succede quando il risultato torna?

case "If-Modified-Since": 
    request.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]); 
    break; 

ottengo la questione per esempio da http://en.wikipedia.org/wiki/Main_Page

PS. AGGIORNA QUI

Ancora non riesco a risolvere questo problema. Fondamentalmente posso identificare 1 link che ha un problema, e sembra funzionare bene, 2a volta si ottiene l'errore, 3a volta OK, 4a volta ottiene l'errore, 5a volta OK ecc. Come se ci fosse uno stato che non viene cancellato o qualcosa nel codice. Ho provato a ripulire il codice un po 'usando "using" dichiarazioni di tipo ecc.

Ecco il codice. Se qualcuno può individuare il motivo per cui ogni volta che cerco un link come http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (a partire dalla seconda volta, non il primo) tramite questo codice proxy ottengo l'errore che mi piacerebbe sentire.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Proxy p = new Proxy(8080); 

     Thread proxythread = new Thread(new ThreadStart(p.Start)); 
     proxythread.Start(); 

     Console.WriteLine("Proxy Started. Press Any Key To Stop..."); 
     Console.ReadKey(); 

     p.Stop(); 
    } 
} 

public class Proxy 
{ 
    private HttpListener _listener; 
    private int _port; 

    public Proxy(int port) 
    { 
     int defaultport = 8080; 

     // Setup Thread Pool 
     System.Threading.ThreadPool.SetMaxThreads(50, 1000); 
     System.Threading.ThreadPool.SetMinThreads(50, 50); 

     // Sanitize Port Number 
     if (port < 1024 || port > 65535) 
      port = defaultport; 

     // Create HttpListener Prefix 
     string prefix = string.Format("http://*:{0}/", port); 
     _port = port; 

     // Create HttpListener 
     _listener = new HttpListener(); 
     _listener.Prefixes.Add(prefix); 
    } 

    public void Start() 
    { 
     _listener.Start(); 

     while (true) 
     { 
      HttpListenerContext request = null; 

      try 
      { 
       request = _listener.GetContext(); 

       // Statistics (by Greg) 
       int availThreads = -1; 
       int compPortThreads = -1; 
       ThreadPool.GetAvailableThreads(out availThreads, out compPortThreads); 
       log("INFO", request.Request.Url.ToString(), "START - [" + availThreads + "]"); 

       ThreadPool.QueueUserWorkItem(ProcessRequest, request); 
      } 
      catch (HttpListenerException ex) 
      { 
       log("ERROR", "NA", "INFO: HttpListenerException - " + ex.Message); 
       break; 
      } 
      catch (InvalidOperationException ex) 
      { 
       log("ERROR", "NA", "INFO: InvalidOperationException - " + ex.Message); 
       break; 
      } 
     } 
    } 

    public void Stop() 
    { 
     _listener.Stop(); 
    } 

    private void log(string sev, string uri, string message) 
    { 
     Console.Out.WriteLine(Process.GetCurrentProcess().Id + " - " + sev + " (" + uri + "): " + message); 
    } 

    private void ProcessRequest(object _listenerContext) 
    { 
     #region local variables 
     HttpWebRequest psRequest;     // Request to send to remote web server 
     HttpWebResponse psResponse;     // Response from remote web server   
     List<byte> requestBody = new List<byte>(); // Byte array to hold the request's body 
     List<byte> responseBody = new List<byte>(); // Byte array to hold the response's body 
     byte[] buffer; 
     string uri = ""; 
     #endregion 

     var listenerContext = (HttpListenerContext)_listenerContext; 
     uri = listenerContext.Request.Url.ToString().Replace(string.Format(":{0}", _port), ""); 

     // Create Interent Request 
     HttpWebRequest internetRequest = (HttpWebRequest)WebRequest.Create(uri); 
     #region Build Request Up 
     internetRequest.Method = listenerContext.Request.HttpMethod; 
     internetRequest.ProtocolVersion = listenerContext.Request.ProtocolVersion; 
     internetRequest.UserAgent = listenerContext.Request.UserAgent; 
     foreach (string key in listenerContext.Request.Headers.AllKeys) 
     { 
      try 
      { 
       switch (key) 
       { 
        case "Proxy-Connection": 
        case "Connection": 
         internetRequest.KeepAlive = (listenerContext.Request.Headers[key].ToLower() == "keep-alive") ? true : false; 
         break; 

        case "Content-Length": 
         internetRequest.ContentLength = listenerContext.Request.ContentLength64; 
         break; 

        case "Content-Type": 
         internetRequest.ContentType = listenerContext.Request.ContentType; 
         break; 

        case "Accept": 
         internetRequest.Accept = listenerContext.Request.Headers[key]; 
         break; 

        case "Host": 
         break; 

        case "Referer": 
         internetRequest.Referer = listenerContext.Request.Headers[key]; 
         break; 

        case "If-Modified-Since": 
         internetRequest.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]); 
         break; 

        default: 
         internetRequest.Headers.Add(key, listenerContext.Request.Headers[key]); 
         break; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Error settup up psRequest object. Error = " + ex.Message + "\n" + ex.StackTrace); 
      } 
     } 
     #endregion 

     #region Copy content into request 
     buffer = new byte[1024]; 
     using (Stream instream = listenerContext.Request.InputStream) 
     { 
      int incount = instream.Read(buffer, 0, buffer.Length); 
      while (incount > 0) 
      { 
       internetRequest.GetRequestStream().Write(buffer, 0, incount); 
       incount = instream.Read(buffer, 0, buffer.Length); 
      } 
     } 
     #endregion 

     // Get Internet Response 
     HttpWebResponse internetResponse = null; 
     try 
     { 
      using (internetResponse = (HttpWebResponse)internetRequest.GetResponse()) 
      { 
       #region Configure Local Response Header Keys 
       foreach (string key in internetResponse.Headers.Keys) 
       { 
        try 
        { 
         switch (key) 
         { 
          case "Transfer-Encoding": 
           listenerContext.Response.SendChunked = (internetResponse.Headers[key].ToLower() == "chunked") ? true : false; 
           break; 

          case "Content-Length": 
           listenerContext.Response.ContentLength64 = internetResponse.ContentLength; 
           break; 

          case "Content-Type": 
           listenerContext.Response.ContentType = internetResponse.Headers[key]; 
           break; 

          case "Keep-Alive": 
           listenerContext.Response.KeepAlive = true; 
           break; 

          default: 
           listenerContext.Response.Headers.Add(key, internetResponse.Headers[key]); 
           break; 
         } 
        } 
        catch (Exception ex) 
        { 
         log("ERROR", uri, "Error settup up listenerContext.Response objects. Error = " + ex.Message + "\n" + ex.StackTrace); 
        } 
       } 
       #endregion 

       try 
       { 
        // Transfer the body data from Internet Response to Internal Response 
        buffer = new byte[1024]; 
        using (Stream inputStream = internetResponse.GetResponseStream()) 
        { 
         int outcount = inputStream.Read(buffer, 0, buffer.Length); 
         while (outcount > 0) 
         { 
          listenerContext.Response.OutputStream.Write(buffer, 0, outcount); 
          outcount = inputStream.Read(buffer, 0, buffer.Length); 
         } 
        } 
       } 
       catch (Exception ex) 
       { 
        log("ERROR", uri, "Could not obtain response from URI: " + ex.Message); 
       } 
       finally 
       { 
        listenerContext.Response.OutputStream.Close(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      //if (ex is InvalidOperationException || 
      // ex is ProtocolViolationException || 
      // ex is WebException) 
      //{ 
      // log(uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message); 
      // listenerContext.Response.Close(); 
      // return; 
      //} 
      //else { throw; } 

      log("ERROR", uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message); 
      listenerContext.Response.Close(); 
     } 
    } 
} 

E qui è un esempio di quello che vedo - primo colpo è buono, 2 ° ha errore ...

Proxy Started. Press Any Key To Stop... 
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50] 
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50] 
2080 - ERROR (http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css): Could not successfully get response: System.Net.WebException - The remote server returned an error: (304) Not Modified. 
+0

possibile duplicato di [HttpWebRequest.GetResponse lancia WebException su HTTP 304] (http://stackoverflow.com/questions/1366848/httpwebrequest-getresponse-throws-webexception-on-http-304) – Sebastian

risposta

66

In primo luogo, questo non è un errore. Il 3xx denota un reindirizzamento. Gli errori reali sono 4xx (errore del client) e 5xx (errore del server).

Se un client riceve un 304 Not Modified, è responsabilità del client visualizzare la risorsa in questione dalla propria cache. In generale, il proxy non dovrebbe preoccuparsi di questo. È solo il messaggero.

+1

grazie - così stai dicendo quindi, quello che dovrei fare è catturare l'eccezione ancora (proprio nel momento in cui sto facendo la richiesta), ma poi controllare per vedere cosa c'è nell'eccezione e se è un 304 allora continua semplicemente? – Greg

+2

No - se hai inviato una risposta if-modified-since o if-none implica che hai una copia locale (cache) - il server ti sta insegnando a usare quella copia. – symcbean

+1

OK: dovevo solo assicurarmi di aver restituito lo stesso codice di stato nella richiesta locale e questo sembra funzionare. Vedi http://stackoverflow.com/questions/2611264/httplistener-how-do-i-send-a-webexception-http-304-not-modified-error-back-to per maggiori dettagli sul codice – Greg

12

Questo comportamento è previsto.

Quando si effettua una richiesta HTTP, il server normalmente restituisce il codice 200 OK. Se si imposta If-Modified-Since, il server può restituire 304 Not modified (e la risposta non avrà il contenuto). Questo dovrebbe essere il tuo segnale che la pagina non è stata modificata.

Il authors of the class have foolishly decided che 304 deve essere considerato come un errore e generare un'eccezione. Ora devi ripulirlo dopo aver individuato l'eccezione ogni volta che provi a usare If-Modified-Since.

0

Penso che tu non abbia installato queste funzionalità. vedi sotto nella foto.

enter image description here

ho anche sofferto di questo problema qualche giorno fa. Dopo aver installato questa funzione, l'ho risolto. Se non è stata installata questa funzione, installarla.

processo d'installazione:

  1. andare a Android Studio
  2. Strumenti
  3. Android
  4. SDK Direttore
  5. Aspetto & Comportamento
  6. Android SDK
+1

No .. questa non è una risposta –

3

pagine Clearing cache nel browser possono essere raggiunti in Firefox o Chrome premendo CTRL + F5 invece di premere F5

È quindi possibile vedere 200 risposta invece di 304 nel browser F12 strumenti di sviluppo scheda di rete.

Problemi correlati