Форум программистов, компьютерный форум, киберфорум
C#: Web, ASP.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
HttpProxyHelp

HTTP Proxy server

19.04.2013, 18:43. Показов 4867. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Необходимо разработать кеширующий http proxy сервер. В ходе разработки появились вопросы и проблемы:
1 Проблема: используя мазилу, не все страницы корректно отображаются (например google.ru, ya.ru некорректно, yandex.ru, gmail.com - корректно). Похоже проблема с кодировкой, но в каком месте - выяснить не удалось. Пробовал сохранить полученную страницу на прокси сервере локально, открывал её браузером - все отображается нормально, а вот когда прокси сервер отсылает страницу браузеру - там отображается некорректно.
Пробовал решать проблему следующими способами:
-Использовать бинарный поток данных
-Использовать поток данных с указанной кодировкой
Во втором случае появляется еще одна проблема - получить кодировку. Не всегда в ответах HttpListenerResponse она содержится (и не всегда корректная). Поэтому пробовал извлекать из html страницу по поиску "charset=", который тоже не всегда присутствует.
2 Вопрос: какие способы посоветуете для организации кеширования (сохранение страниц локально).
думаю реализовать следующим образом - сохранять Uri каждого запроса в списке и сопоставить Id, под которым страница будет сохраняться локально. Время последнего изменения страницы получаем по дате создания файла, и по запросу myHttpWebRequest.IfModifiedSince определяем, была ли она изменена.
3 Вопрос: Корректно ли реализована многопоточность. Так как ответ на запрос может содержать ссылки на другие страницы, необходимо для ускорения загрузки реализовать многопоточность.
4 Вопрос: Существует множество вариантов использования потоков данных, что посоветуете использовать? Как из Memorystream записать напрямую в поток ответа (response.OutputStream)? memoryStream.CopyTo и memoryStream.WriteTo почему то не сработали (предварительно в потоке памяти смещал указатель на начало).

Класс пересылки:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
 
namespace server_test {
    class Query {
 
        private HttpListenerContext context;
 
        public void setContex(HttpListenerContext context) {
            this.context = context;
        }
 
        public void StartThread() {
            Thread handler = new Thread(processRequest);
            handler.Priority = ThreadPriority.AboveNormal;
            handler.Start();
        }
 
        public void processRequest() {
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;
 
            Uri myUri = new Uri(request.RawUrl);
            HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(myUri);
            DateTime targetDate = DateTime.Now;
            //DateTime fileCreatedDate = File.GetCreationTime(@"C:\Example\MyTest.txt");
            //Console.WriteLine("file created: " + fileCreatedDate);
            //targetDate.AddDays(-7.0);
            //myHttpWebRequest.IfModifiedSince = targetDate;
            Console.WriteLine(myHttpWebRequest.Address);
            try {
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
 
                /*
                String charset = myHttpWebResponse.CharacterSet;
                Console.WriteLine(charset);
                Encoding encoding;
                if (charset == "") encoding = Encoding.Default;
                else encoding = Encoding.GetEncoding(charset);
                response.ContentEncoding = encoding;
 
                //if (targetDate.CompareTo(myHttpWebResponse.LastModified) <= 0)
                //System.Diagnostics.Debug.WriteLine("The page has not been modified since " + targetDate);
                
                Stream streamResponse = myHttpWebResponse.GetResponseStream();
                Stream streamOutput = response.OutputStream;
                StreamReader streamReader = new StreamReader(streamResponse, encoding);
                StreamWriter streamWrite = new StreamWriter(streamOutput, encoding);
                streamWrite.Write(streamReader.ReadToEnd());
 
                streamReader.Close();
                streamWrite.Close();
                streamResponse.Close();
                streamOutput.Close();*/
 
                byte[] buffer = new byte[1024];
                byte[] file;
 
                BinaryReader binaryReader = new BinaryReader(myHttpWebResponse.GetResponseStream());
                MemoryStream memoryStream = new MemoryStream();
                buffer = binaryReader.ReadBytes(1024);
                while (buffer.Length > 0) {
                    memoryStream.Write(buffer, 0, buffer.Length);
                    buffer = binaryReader.ReadBytes(1024);
                }
                file = new byte[(int)memoryStream.Length];
                memoryStream.Position = 0;
                memoryStream.Read(file, 0, file.Length);
                binaryReader.Close();
                memoryStream.Close();
                
                BinaryWriter binaryWriter = new BinaryWriter(response.OutputStream);
                binaryWriter.Write(file);
                binaryWriter.Close();
 
                //FileStream fs = new FileStream("tmp\\log.txt", FileMode.OpenOrCreate, FileAccess.Write);
                //fs.Write(file, 0, file.Length);
                //fs.Dispose();
 
                myHttpWebResponse.Close();
 
            } catch (WebException e) {
                if (e.Response != null) {
                    if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotModified) {
                        Console.WriteLine("The page has not been modified since " + targetDate);
                    }
                    else Console.WriteLine("Unexpected status code = " + ((HttpWebResponse)e.Response).StatusCode);
                }
                else Console.WriteLine("Unexpected Web Exception " + e.Message);
            } catch (Exception e) { Console.WriteLine("Exception: " + e.ToString()); }
 
        }
    }
}
Главная программа:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
 
namespace server_test {
 
    class Program {
 
        static int requestCount = 0;
 
        static void Main(string[] args)
        {
            Thread handler = new Thread(consol_command);
            handler.Start();
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add("http://*:8080/");
            listener.Start();
            Console.WriteLine("Listening...");
 
            while (true) {
                Query query = new Query();
                query.setContex(listener.GetContext());
                query.StartThread();
                requestCount++;
            }
            
            //listener.Stop();
        }
 
        static public void consol_command() {
            while(true) {
                String command = Console.ReadLine();
                if (command == "stat") {
                    Console.WriteLine("Request count: " + requestCount);
                }
            }
        }
    }
}
Добавлено через 7 часов 48 минут
1) Проблема снимается. При переотправке запроса, необходимо задавать свойства:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
            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);
                }
            }
3) Вопрос снимается. Необходимо использовать пул потоков.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.04.2013, 18:43
Ответы с готовыми решениями:

Error while trying to run project: Unable to start debugging on the web server. Server-side error occurred on sending debug HTTP request.
я полнейший новичок в ASP.NET. у меня такая проблема: Я формирую пустой проект, а при запуске выдается ошибка: Error while trying to...

HTTP 500 Internal Server Error
У меня 'полетел' IIS 4.0 (W2K Server). Я установил его заново, но когда иду на http://localhost я всегда получаю ошибку 'The page cannot be...

Изменение http страницы в proxy сервере
Здравствуйте! Ребят, как просматривать и изменять код http страницы, которая проходит через мой прокси сервер? есть вот такой код, но это...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.04.2013, 18:43
Помогаю со студенческими работами здесь

TCP Proxy Server
Добрый день ув. пользователи.В общем появилась необходимость написать прокси сервер.Задача такая - Создаем сокет на локал хосте ,...

Socks Proxy Server
Нужно написать проксификатор(Socks 5) В интернете мало информации на эту тему, единственное что нашел в приложениях,и то даже не...

Proxy Server не работает
Не могу найти ошибку в коде. /* * Пример к статье «Разработка прокси-сервера» *...

Proxy Server HTTPS через SSL
Добрый день. Столкнулся с задачей написать прокси сервер. Нашел хороший пример...

Создание http server
Помогите реализовать простой сервер на базе http. задачи следующие: получать параметры GET или POST, придумать самому в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru