Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > Прокси сервер на .Net


Автор: ivashkanet 24.12.2006, 17:33
Решил попробовать себя в Remouting-е. 

Задумал написать Proxy сервер. Для этих целей (мне, как новичку) очень подходит HttpListerner.

Обернул его немножко:
Код

public class InternetBoosterProxy : IDisposable
    {
        #region Main members
        private HttpListener _listener;
        private Thread _listerningThread;
        private bool isStarted = false;

        public InternetBoosterProxy()
        {
            _listener = new HttpListener();
            _listener.Prefixes.Add(@"http://*:8090/");
        }

        public void Start()
        {
            if (!isStarted)
            {
                _listener.Start();

                _listerningThread = new Thread(new ThreadStart(Listerning));
                _listerningThread.Start();
            }
            else
                throw new Exception("Listerning has already started");
        }

        public void Stop()
        {
            if (!isStarted)
            {
                _listerningThread.Abort();
                _listener.Stop();
            }
            else
                throw new Exception("Listerning has not started yet");
        }
        #endregion

        #region Listerning loop
        private void Listerning()
        {
            try
            {
                while (true)
                {
                    HttpListenerContext context = _listener.GetContext();
             
                    // Код тута :)
                }
            }
            catch (ThreadAbortException) { }
            finally
            {
                _listener.Close();
            }

        }
        #endregion

        #region IDisposable Members
        public void Dispose()
        {
            if (_listener != null) _listener.Close();
        }
        #endregion
    }

Установил в настройках Оперы ссылку на мой прокси: localhost, 8090. 

Все работает smile Все отлично. Я могу перехватывать запросы браузера, могу ему отвечать:
Код

// Вместо "Код тута"
                
                    HttpListenerRequest request = context.Request;
                    // Obtain a response object.
                    HttpListenerResponse response = context.Response;
                    // Construct a response.
                    string responseString = "<HTML><BODY>" +request.Url.ToString() +"</BODY></HTML>";
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                    // Get a response stream and write the response to it.
                    response.ContentLength64 = buffer.Length;
                    System.IO.Stream output = response.OutputStream;
                    output.Write(buffer, 0, buffer.Length);
                    // You must close the output stream.
                    output.Close();


Но это так, баловство.

Нормальный прокси сервер должен пропускать через себя запрос в интрернет.

Запрос в инет проще всего сделать с помощью HttpWebRequest и HttpWebResponse
Код

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://forum.vingrad.ru/index.php?showtopic=108198&st=0&#entry824527");

HttpWebResponse respodse = (HttpWebResponse)request.GetResponse();

StreamReader readStream = new StreamReader(respodse.GetResponseStream(), Encoding.GetEncoding("windows-1251"));

Но загвоздка в том, что HttpWebRequest не переводиться в HttpListenerRequest легко, читай стандартными средствами.

Можно, конечно, сделать так:

Код

        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(request.Url);
        
        webRequest.ContentLength = request.ContentLength64;
        webRequest.ContentType = request.ContentType;
        webRequest.CookieContainer.Add(request.Cookies);
        // ...........

        HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
        // И наоборот


Но как-то это кривовато  smile Может я чето-нить забуду перевести (поля-то у них отличаются), может что-то перевести совсем нельзя  smile 

Полазил по инету, нашел только такую http://www.thescripts.com/forum/thread510683.html.
Там он хотел сделать точно такую же штуку, но его отговорили:
Цитата

I had tried this but i would not recommend to use it as HTTPListener
gives strange behaviour and you wont be able to get your proxy at work
completely
. still if you wanna try your luck then, You can forward the
request got from HTTPListenerRequest using HTTPWebRequest class and
get the response back from the web server using HTTPWebResponse class,
then you can write back this response to the HTTPListenerResponse
object.

After appx 2 months of work i wasnt able to solve some errors of
HTTPListener so then i changed my approach and shifted towards sockets.

For examples in .NET you can see the source code of Mentalis proxy at


CodeProject тоже ничего не сказал.

Вопрос:
Как правильно перевести HttpWebRequest в HttpListenerRequest?
И аналогично с Response.


Может у кого есть идеи? Зарание спасибо. ivashkanet.

P.S. Может точно переписать под сокеты?

Автор: stab 27.12.2006, 00:11
мой тебе совет: пиши сразу на сокетах. там просто тонкостей всяких очень много, например заголовки proxy-connection: keep-alive (или как-то так), сомневаюсь, что высокоуровневые средства их обрабатывают.

Цитата(ivashkanet @  24.12.2006,  21:33 Найти цитируемый пост)
Решил попробовать себя в Remouting-е

это не remoting.

Автор: ivashkanet 27.12.2006, 09:59
Цитата(cully @  26.12.2006,  23:11 Найти цитируемый пост)
мой тебе совет: пиши сразу на сокетах

Это образовательный проект smile Я хотел его кое как состряпать и перейти на сокеты.
Сделать, хотябы, чтобы Винград хорошо обрабатывался smile

Цитата(cully @  26.12.2006,  23:11 Найти цитируемый пост)
это не remoting.

Я в курсе, пасиб smile
Просто для меня, пока, все распределенные приложения --- Remoting  smile 

Автор: AlexBar 6.6.2007, 17:15
ivashkanet, и успехи? у самого есть мысль написать сжимающий прокси... вот только пока не знаю с чего начать...

Автор: ivashkanet 6.6.2007, 17:57
AlexBar, никаких  smile 
Я на работе получил проект, сразу времени не стало, поэтому идея загрызть гранит ремоутинга заглохла smile

Автор: Nil 6.6.2007, 19:03
Вот у меня всегда с .NET ощущение ограниченности. Вот тот же случай, используя эти классы теряешь полный контроль над процессом. Имхо такие вещи стоит писать на c++

Автор: ivashkanet 7.6.2007, 07:44
Цитата(Nil @  6.6.2007,  18:03 Найти цитируемый пост)
используя эти классы теряешь полный контроль над процессом

Nil, ИМХО, эти классы не предназначены для написания прокси. Вот отправить запрос в инет и получить ответ --- запросто, а для прокси лучше использовать сокеты.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)