Почему я получаю «(304) не модифицировал« Ошибка по некоторым ссылкам при использовании httpwebrequest?

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

Вопрос

Любые идеи, почему по некоторым ссылкам, которые я пытаюсь получить доступ к использованию httpwebrequest, я получаю сообщение «Удаленный сервер вернул ошибку: (304) не модифицирован». в коде?

Код, который я использую, от Джефф пост здесь (страница, похоже, исчезла, см. Архив скопированной на пуфике).

Примечание. Концепция кода является простым прокси-сервером, поэтому я указываю на мой браузер в этом локально запущенном кусочке кода, который получает мой запрос браузеров, а затем прокси его, создавая новый httpwebrequest, как вы увидите в код. Он отлично работает для большинства сайтов / ссылок, но для некоторой этой ошибки возникает. Вы увидите, что один ключ в коде - это то, где кажется, что скопируйте настройки заголовка HTTP из запроса на браузер к его запросу на сайт, и он копирует в атрибутах заголовка. Не уверен, что проблема - это что-то делать с тем, как она имитирует этот аспект запроса, а затем, что происходит, когда результат возвращается?

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

Я получаю проблему, например из http://en.wikipedia.org/wiki/main_page.

Придавать Обновить здесь

До сих пор не могу это работать. По сути, я могу определить 1 ссылку, которая имеет проблему, и, похоже, работает нормально, 2-й раз это получает ошибку, 3-й раз в порядке, 4-й раз получает ошибку, 5 раз в порядке и т. Д., Как будто есть какое-то состояние, не получаемое не очищенное или что-то в коде. Я попытался убрать код немного, используя «Использование» типовых выписок и т. Д.

Вот код. Если кто-то может заметить, почему каждый 2-й раз я просматриваю ссылку, как http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css. (Начиная с 2-го времени, не первый) через этот прокси-код, я получаю ошибку, я бы слышал.

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

И вот пример того, что я вижу - первый хит хороший, 2-й имеет ошибку ...

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.
Это было полезно?

Решение

Во-первых, это не ошибка. То 3xx обозначает перенаправление. Реальные ошибки 4xx (Клиентская ошибка) и 5xx (Ошибка сервера).

Если клиент получает 304 Not Modified, Затем это ответственность клиента за то, чтобы отобразить вопрос о возобновлении из своего собственного кэша. В общем, прокси не должен беспокоиться об этом. Это просто посланник.

Другие советы

Это предполагаемое поведение.

Когда вы делаете HTTP-запрос, сервер нормально возвращает код 200 OK. Отказ Если вы установите If-Modified-Since, сервер может вернуться 304 Not modified (и ответ не будет иметь содержимого). Это должно быть вашим рецептом, что страница не была изменена.

То Авторы класса по глупости решили это 304 следует рассматривать как ошибку и выбрасывать исключение. Теперь вы должны убирать после них, забив исключение каждый раз, когда вы пытаетесь использовать If-Modified-Since.

Просто нажатие F5. не всегда работает.

Зачем?

Поскольку ваш ISP также кэширует веб-данные для вас.

Решение: Сила обновления.

Сила обновить ваш браузер нажатием Ctrl. + F5. в Firefox или Chrome, чтобы очистить провалочный кеш тоже вместо просто нажатия F5.

Затем вы можете увидеть 200 ответ вместо 304 в браузере F12. Вкладка «Инструменты разработчика».

Еще один трюк - добавить знак вопроса ? В конце строки URL запрошенной страницы:

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

Марк вопроса обеспечит, чтобы браузер обновит запрос без кэширования любых предыдущих запросов.

Дополнительно в Visual Studio Вы можете установить браузер по умолчанию на Хром в Инкогнито Режим, чтобы избежать проблем кэша при разработке, добавив Chrome в режиме Incognito в качестве браузера по умолчанию, см. Шаги (я иллюстрируемые):

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

Я думаю, что вы не установили эти функции. Смотрите ниже на картинке.

enter image description here

Я также страдал от этой проблемы несколько дней назад. После установки этой функции я решил ее. Если вы не установили эту функцию, то установил ее.

Процесс установки:

  1. Перейти к андроидной студии
  2. Инструменты
  3. Андроид
  4. Менеджер SDK
  5. Внешний вид и поведение
  6. Android SDK
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top