Perché sto ricevendo un errore "(304) non modificato" su alcuni collegamenti quando utilizzo HTTPWebRequest?

StackOverflow https://stackoverflow.com/questions/2603595

Domanda

Qualche idea per cui su alcuni link a cui provo ad accedere utilizzando HTTPWebRequest, sto ottenendo "il server remoto ha restituito un errore: (304) non modificato." nel codice?

Il codice che sto usando è da Il post di Jeff qui (La pagina sembra essere scomparsa, vedi un Copia dell'archivio presso la macchina Wayback).

Nota che il concetto del codice è un semplice server proxy, quindi sto puntando il mio browser su questo pezzo di codice in esecuzione a livello locale, che ottiene la richiesta dei miei browser, quindi lo proxy creando un nuovo httpwebrequest, come vedrai il codice. Funziona alla grande per la maggior parte dei siti/link, ma per alcuni questo errore emerge. Vedrai un bit chiave nel codice è dove sembra copiare le impostazioni dell'intestazione HTTP dalla richiesta del browser alla sua richiesta al sito e copia gli attributi di intestazione. Non sono sicuro se il problema abbia qualcosa a che fare con il modo in cui imita questo aspetto della richiesta e quindi cosa succede quando il risultato ritorna?

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

Ottengo il problema per esempio da http://en.wikipedia.org/wiki/main_page

Ps. Aggiornamento qui

Non riesco ancora a risolverlo. Fondamentalmente posso identificare 1 link che ha un problema e sembra funzionare bene, 2a volta che ottiene l'errore, terza volta ok, la quarta volta ottiene l'errore, quinta volta ok ecc. Come se ci fosse uno stato non viene cancellato o cancellato qualcosa nel codice. Ho provato a ripulire un po 'il codice usando le istruzioni di tipo "usando" ecc.

Ecco il codice. Se qualcuno può individuare il motivo per cui ogni seconda volta che navighi su 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 ricevo 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();
        }
    }
}

Ed ecco un esempio di quello che vedo: il primo successo è buono, il 2 ° ha un 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.
È stato utile?

Soluzione

Innanzitutto, questo non è un errore. Il 3xx indica un reindirizzamento. I veri errori sono 4xx (Errore client) e 5xx (Errore del server).

Se un cliente ottiene un file 304 Not Modified, quindi è responsabilità del cliente mostrare la risorsa in questione dalla propria cache. In generale, il proxy non dovrebbe preoccuparsi di questo. È solo il messaggero.

Altri suggerimenti

Questo è un comportamento previsto.

Quando si effettua una richiesta HTTP, il server restituisce normalmente il codice 200 OK. Se imposti 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 Gli autori della classe hanno deciso stupidamente Quello 304 dovrebbe essere trattato come un errore e lanciare un'eccezione. Ora devi ripulirli dopo catturando l'eccezione ogni volta che provi a usare If-Modified-Since.

Solo premendo F5 non funziona sempre.

perché?

Perché il tuo ISP è anche memorizzazione nella cache dei dati Web per te.

Soluzione: Forza aggiornamento.

Forza aggiorna il browser premendo CTRL + F5 In Firefox o Chrome per cancellare anche la cache dell'ISP, invece di premere F5

Quindi puoi vedere 200 risposte anziché 304 nel browser F12 Scheda Network Strumenti per sviluppatori.

Un altro trucco è aggiungere un punto interrogativo ? Alla fine della stringa URL della pagina richiesta:

http://localhost:52199/Customers/Create?

Il punto interrogativo assicurerà che il browser aggiorni la richiesta senza memorizzazione nella cache eventuali richieste precedenti.

Inoltre in Visual Studio È possibile impostare il browser predefinito su Cromo in Incognito Modalità Per evitare problemi di cache durante lo sviluppo, aggiungendo Chrome in modalità Incognito come browser predefinito, vedere i passaggi (auto illustrato):

Go to browsers list Select browse with... Click Add... Point to the chrome.exe on your platform, add argument "Incognito" Choose the browser you just added and set as default, then click browse

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

enter image description here

Ho anche sofferto di questo problema alcuni giorni fa. Dopo aver installato questa funzione, l'ho risolta. Se non hai installato questa funzione, quindi installata.

Processo di installazione:

  1. Vai a Android Studio
  2. Strumenti
  3. Android
  4. Manager SDK
  5. Aspetto e comportamento
  6. Android SDK
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top