Pergunta

Quaisquer idéias por que em alguns links que eu tento acessar usando httpwebrequest, estou recebendo "o servidor remoto retornou um erro: (304) não é modificado". no código?

O código que estou usando é de Postagem de Jeff aqui (a página parece ter desaparecido, ver um cópia do arquivo na máquina Wayback).

Observe que o conceito do código é um servidor de proxy simples, por isso estou apontando meu navegador neste código de código em execução localmente, que recebe minha solicitação de navegadores e, em seguida, proxies, criando um novo httpwebrequest, como você verá em o código. Funciona muito bem para a maioria dos sites/links, mas para alguns esse erro surge. Você verá um bit de chave no código é onde ele parece copiar as configurações do cabeçalho HTTP da solicitação do navegador para sua solicitação para o site e ele copia nos atributos do cabeçalho. Não tem certeza se o problema tem algo a ver com a forma como imita esse aspecto da solicitação e o que acontece quando o resultado volta?

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

Eu recebo o problema, por exemplo, de http://en.wikipedia.org/wiki/Main_Page

Ps. Atualização aqui

Ainda não consigo resolver isso. Basicamente, posso identificar 1 link que tem um problema, e parece funcionar bem, segunda vez que recebe o erro, a terceira vez, a quarta vez recebe o erro, 5ª vez, ok etc. Como se houvesse algum estado não se libertado ou algo no código. Eu tentei limpar um pouco o código usando instruções de tipo "usando" etc.

Aqui está o código. Se alguém pode identificar por que toda a segunda vez eu navego para um link como http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (A partir da 2ª vez, não o primeiro) por meio desse código de proxy, recebo o erro que adoraria ouvir.

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 aqui está um exemplo do que eu vejo - o primeiro golpe é bom, o segundo tem erro ...

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

Solução

Primeiro, isso não é um erro. o 3xx indica um redirecionamento. Os erros reais são 4xx (erro do cliente) e 5xx (erro de servidor).

Se um cliente conseguir um 304 Not Modified, então é responsabilidade do cliente exibir o Resuce em questão de seu próprio cache. Em geral, o proxy não deve se preocupar com isso. É apenas o mensageiro.

Outras dicas

Isso é um comportamento pretendido.

Quando você faz uma solicitação HTTP, o servidor normalmente retorna o código 200 OK. Se você definir If-Modified-Since, o servidor pode retornar 304 Not modified (e a resposta não terá o conteúdo). Esta é a sua sugestão de que a página não foi modificada.

o Autores da classe decidiram tolamente este 304 deve ser tratado como um erro e lançar uma exceção. Agora você tem que limpar depois deles pegando a exceção toda vez que tenta usar If-Modified-Since.

Apenas pressionando F5 Nem sempre está funcionando.

porque?

Porque seu ISP também está em cache de dados da Web para você.

Solução: Força de força.

Forçar a atualização do seu navegador pressionando Ctrl + F5 no Firefox ou Chrome para limpar o cache do ISP também, em vez de apenas pressionar F5

Você pode ver 200 respostas em vez de 304 no navegador F12 Guia de rede de ferramentas de desenvolvedor.

Outro truque é adicionar ponto de interrogação ? No final da sequência de URL da página solicitada:

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

O ponto de interrogação garantirá que o navegador atualize a solicitação sem armazenar em cache de solicitações anteriores.

Além disso Estúdio visual você pode definir o navegador padrão como cromada dentro Incógnito modo para evitar problemas de cache durante o desenvolvimento, adicionando o Chrome no modo Incognito como navegador padrão, consulte as etapas (auto -ilustradas):

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

Eu acho que você não instalou esses recursos. Veja abaixo na foto.

enter image description here

Eu também sofri com esse problema alguns dias atrás. Depois de instalar esse recurso, eu o resolvi. Se você não instalou esse recurso, instalou -o.

Processo de instalação:

  1. Vá para o Android Studio
  2. Ferramentas
  3. Android
  4. Gerente do SDK
  5. Aparência e comportamento
  6. Android SDK
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top