Привет все!
Я написал свой прокси, вот только, судя по всему не учел какую-та мелкую деталь. Дело в том что некоторые сайты грузятся через него корректно, а некоторые — нет. Принцып — пустяк: подставил в браузере свой прокси. А далее что принял прокси, то и отдал клиенту без изменения. Я в сокетах почти новичок, может кто-то мне сможет помочь? Заранее огромное спасибо
Очень прошу, посмотрите упрощеный код этого прокси. Вот его основная ф-ия:
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;
}
Здравствуйте 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()), весьма удобно.
Удачи.
Здравствуйте 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 рабочих дня!
Еще раз спасибо!