wake-up-neo.com

Warum erhalte ich bei einigen Links die Fehlermeldung "(304) Not Modified", wenn ich HttpWebRequest verwende?

Irgendwelche Ideen, warum bei einigen Links, auf die ich versuche, mit HttpWebRequest zuzugreifen, "Der Remoteserver hat einen Fehler zurückgegeben: (304) Nicht geändert." im Code?

Der Code, den ich verwende, stammt aus Jeffs Beitrag hier (die Seite scheint verschwunden zu sein, siehe Archivkopie auf der Wayback-Maschine ).

Beachten Sie, dass das Konzept des Codes ein einfacher Proxyserver ist. Daher weise ich meinen Browser auf diesen lokal ausgeführten Code, der meine Browseranforderung erhält, und leite ihn durch Erstellen eines neuen HTTP-Web-Requests weiter, wie Sie in sehen werden der Code. Es funktioniert gut für die meisten Sites/Links, aber für einige tritt dieser Fehler auf. In dem Code wird ein Schlüsselbit angezeigt, in dem die Einstellungen für den HTTP-Header von der Browseranforderung auf die Anforderung an die Site kopiert und in die Headerattribute kopiert werden. Sie sind sich nicht sicher, ob das Problem damit zusammenhängt, wie es diesen Aspekt der Anforderung nachahmt, und was passiert dann, wenn das Ergebnis zurückkommt?

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

Ich bekomme das Problem zum Beispiel von http://en.wikipedia.org/wiki/Main_Page

PS. UPDATE HIER

Kann das immer noch nicht klären. Grundsätzlich kann ich 1 Link identifizieren, der ein Problem hat, und es scheint gut zu funktionieren, 2. Mal wird der Fehler angezeigt, 3. Mal OK, 4. Mal wird der Fehler angezeigt, 5. Mal OK usw. Als ob es einen Status gibt, der nicht gelöscht wird, oder etwas im Code. Ich habe versucht, den Code mit Anweisungen vom Typ "using" usw. ein wenig aufzuräumen.

Hier ist der Code. Wenn jemand erkennen kann, warum ich jedes zweite Mal zu einem Link wie http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (beginnend mit dem 2. Mal, nicht das erste Mal) Über diesen Proxy-Code erhalte ich den Fehler, den ich gerne hören würde.

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();
        }
    }
}

Und hier ist ein Beispiel für das, was ich sehe - der erste Treffer ist gut, der zweite hat einen Fehler ...

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.
42
Greg

Erstens ist dies kein Fehler. Das 3xx bezeichnet eine Umleitung. Die wirklichen Fehler sind 4xx (Clientfehler) und 5xx (Serverfehler).

Wenn ein Kunde ein 304 Not Modified , dann liegt es in der Verantwortung des Kunden, die betreffende Ressource aus seinem eigenen Cache anzuzeigen. Im Allgemeinen sollte sich der Proxy darüber keine Gedanken machen. Es ist nur der Bote.

82
BalusC

Dies ist beabsichtigtes Verhalten.

Wenn Sie eine HTTP-Anfrage stellen, gibt der Server normalerweise den Code 200 OK Zurück. Wenn Sie If-Modified-Since Einstellen, gibt der Server möglicherweise 304 Not modified Zurück (und die Antwort enthält keinen Inhalt). Dies sollte Ihr Hinweis darauf sein, dass die Seite nicht geändert wurde.

Die Autoren der Klasse haben dummerweise entschieden dass 304 Als Fehler behandelt und eine Ausnahme ausgelöst werden soll. Jetzt müssen Sie sie bereinigen, indem Sie bei jedem Versuch, If-Modified-Since Zu verwenden, die Ausnahme abfangen.

19
Superbest

Einfach drücken F5 funktioniert nicht immer.

warum?

Weil Ihr ISP auch Webdaten für Sie zwischenspeichert.

Lösung: Aktualisierung erzwingen.

Erzwinge die Aktualisierung deines Browsers durch Drücken von CTRL + F5 in Firefox oder Chrome, um auch den ISP-Cache zu löschen, anstatt nur zu drücken F5

Sie können dann 200 Antworten anstelle von 304 im Browser sehen F12 Registerkarte Netzwerk der Entwicklertools.

Ein weiterer Trick besteht darin, am Ende der URL-Zeichenfolge der angeforderten Seite ein Fragezeichen ? Hinzuzufügen:

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

Das Fragezeichen stellt sicher, dass der Browser die Anfrage aktualisiert, ohne vorherige Anfragen zwischenzuspeichern.

Zusätzlich können Sie in Visual Studio den Standardbrowser auf Chrome in Inkognito-Modus Um Cache-Probleme beim Entwickeln zu vermeiden, indem Sie Chrome im Inkognito-Modus als Standardbrowser hinzufügen, gehen Sie wie folgt vor (selbst illustriert):

Go to browsers listSelect 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

14
Ashraf Abusada