Сокеты: Прокси
От: gis Украина  
Дата: 08.08.02 12:37
Оценка:
Привет все!

Я написал свой прокси, вот только, судя по всему не учел какую-та мелкую деталь. Дело в том что некоторые сайты грузятся через него корректно, а некоторые — нет. Принцып — пустяк: подставил в браузере свой прокси. А далее что принял прокси, то и отдал клиенту без изменения. Я в сокетах почти новичок, может кто-то мне сможет помочь? Заранее огромное спасибо
Очень прошу, посмотрите упрощеный код этого прокси. Вот его основная ф-ия:


   CSocket sockRecv;
   sockRecv.Attach(((MT_PARAM*)param)->sock);

   for (;;)
   {
      int nBufLen = sockRecv.Receive(buf,nMaxBufLen);
      /*    ....
            Cutting from HTTP header "Proxy-Connection" field    
      */

      CSocket sockClient;
      sockClient.Create();
      int nParam = 60000;
      sockClient.SetSockOpt(SO_RCVTIMEO,(char*)&nParam,sizeof(nParam));
      sockClient.SetSockOpt(SO_SNDTIMEO,(char*)&nParam,sizeof(nParam));
      sockRecv.SetSockOpt(SO_RCVTIMEO,(char*)&nParam,sizeof(nParam));
      sockRecv.SetSockOpt(SO_SNDTIMEO,(char*)&nParam,sizeof(nParam));

      /*    ....
            Define from HTTP header host name -> strHost
      */

      if (!sockClient.Connect(strHost,nPort))
         break;

      int nSent = sockClient.Send(strSend,nBufLen);
      if (nSent != nBufLen)
         break;

      for (;;)
      {
         nBufLen = sockClient.Receive(buf,nMaxBufLen);
         
  //  I comment it.     pthread->MakeSomeChanges(nBufLen,buf);

         if (nBufLen <= 0) break;

         int nSent = sockRecv.Send(buf,nBufLen);
         if (nSent != nBufLen)
            break;

      }
      sockClient.Close();
      sockRecv.Close();
      break;
   }
best regards, Ivan
Re: Сокеты: Прокси
От: DS Украина  
Дата: 14.08.02 06:51
Оценка:
Здравствуйте gis.

Как я понял из приведенного текста проги, алгоритм примерно следующий:
— ждем подключения от клиента;
— подключаем клиента;
— подключаемся к указанному в запросе хосту;
— передаем запрос;
— все, что получаем от хоста передаем клиенту.

Как мне кажется дело может быть вот в чем:
Когда был передан запрос хосту, прога больше не принимает запросы поступающие от клиента, а браузеры могут посылать несколько запросов подрят (см. Keep-Alive) для закачки картинок и т.п..
В результате запрошенные не первым запросом данные, браузер не получит.

Следующий код, на мой взгляд, не совсем корректен:

gis> int nSent = sockRecv.Send(buf,nBufLen);

gis> if (nSent != nBufLen)
gis> break;

Ведь, если Send() возвращает != SOCKET_ERROR, то все ОК.
Лучше примерно следующее:

int send_size = 0;
while(nBufLen != send_size)
{
int n = sockRecv.Send((char *)buf + send_size, nBufLen — send_size);
if(n == SOCKET_ERROR) break;
if(n > 0) send_size += n;
}

Рекомендую, если конечно уже не используешь, пользоваться асинхр. свойствами сокетов (WSAAsyncSelect()), весьма удобно.

Удачи.
Re[2]: Сокеты: Прокси
От: Аноним  
Дата: 14.08.02 07:22
Оценка:
Здравствуйте DS, спасибо за уделенное мне время.

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

GET www.aol.com/image.gif HTTP....
Host: www.aol.com
....

то прокси должен отдать серверу следующее:
GET /image.gif
Host: www.aol.com

Этот самый АОЛ (как пример), онализирует запрос немного не так как большинство и пытался найти www.aol.com/image.gif относительно своего хоста. По крайней мере я так понимаю, может я и не прав :)

Думаю, что браузер к АОЛу шлет именно второй запрос, просто так как я прокси, он мне прислал первый. Все логично, но из-за отсутствия знаний в этой области я просидел над этим 2-3 рабочих дня!


Еще раз спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.