Pregunta

¿Alguna idea de por qué en algunos enlaces a los que intento acceder mediante HttpWebRequest aparece "El servidor remoto devolvió un error:(304) No modificado." en el código?

El código que estoy usando es de La publicación de Jeff aquí. (la página parece haber desaparecido, ver una copia de archivo en Wayback Machine).

Tenga en cuenta que el concepto del código es un servidor proxy simple, por lo que apunto mi navegador a este fragmento de código que se ejecuta localmente, que recibe la solicitud de mi navegador y luego lo activa creando un nuevo HttpWebRequest, como verá en el código.Funciona muy bien para la mayoría de los sitios/enlaces, pero en algunos aparece este error.Verá que un bit clave en el código es donde parece copiar la configuración del encabezado http de la solicitud del navegador a su solicitud al sitio, y se copia en los atributos del encabezado.¿No está seguro de si el problema tiene algo que ver con cómo imita este aspecto de la solicitud y luego qué sucede cuando llega el resultado?

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

Recibo el problema, por ejemplo, de http://en.wikipedia.org/wiki/Main_Page

PD.ACTUALIZAR AQUÍ

Todavía no puedo resolver esto.Básicamente, puedo identificar 1 enlace que tiene un problema y parece funcionar bien, la segunda vez aparece el error, la tercera vez está bien, la cuarta vez aparece el error, la quinta vez está bien, etc.Como si hubiera algún estado que no se borra o algo en el código.Intenté limpiar un poco el código usando declaraciones de tipo "usando", etc.

Aquí está el código.Si alguien puede entender por qué cada segunda vez que busco un enlace como http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (a partir de la segunda vez, no la primera) a través de este código proxy aparece el error que me encantaría escuchar.

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

Y aquí hay un ejemplo de lo que veo: el primer golpe es bueno, el segundo tiene error...

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.
¿Fue útil?

Solución

Primero, esto no es un error.El 3xx denota una redirección.Los verdaderos errores son 4xx (error del cliente) y 5xx (Error del Servidor).

Si un cliente obtiene un 304 Not Modified, entonces es responsabilidad del cliente mostrar el recurso en cuestión desde su propia caché.En general, el proxy no debería preocuparse por esto.Es sólo el mensajero.

Otros consejos

Este es el comportamiento previsto.

Cuando realiza una solicitud HTTP, el servidor normalmente devuelve código 200 OK.si estableces If-Modified-Since, el servidor puede regresar 304 Not modified (y la respuesta no tendrá el contenido).Se supone que esta es su señal de que la página no ha sido modificada.

El Los autores de la clase han decidido tontamente. eso 304 debe tratarse como un error y generar una excepción.Ahora tienes que limpiarlos detectando la excepción cada vez que intentas usar If-Modified-Since.

Solo presionando F5 no siempre está funcionando.

¿por qué?

Porque su ISP también almacena en caché los datos web por usted.

Solución: Forzar actualización.

Fuerce la actualización de su navegador presionando CONTROL + F5 en Firefox o Chrome para borrar también el caché del ISP, en lugar de simplemente presionar F5

Luego podrá ver la respuesta 200 en lugar de 304 en el navegador. F12 Pestaña de red de herramientas de desarrollador.

Otro truco es añadir un signo de interrogación. ? al final de la cadena URL de la página solicitada:

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

El signo de interrogación garantizará que el navegador actualice la solicitud sin almacenar en caché ninguna solicitud anterior.

Además en Estudio visual puede configurar el navegador predeterminado para Cromo en Incógnito modo para evitar problemas de caché durante el desarrollo, agregando Chrome en modo incógnito como navegador predeterminado, consulte los pasos (autoilustrados):

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

Creo que no has instalado estas funciones.ver abajo en la imagen.

enter image description here

Yo también sufrí este problema hace unos días.Después de instalar esta función, lo resolví.Si no ha instalado esta función, instálela.

Proceso de instalación:

  1. ir al estudio de Android
  2. Herramientas
  3. Androide
  4. Administrador de SDK
  5. Apariencia y comportamiento
  6. SDK de Android
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top