現在、C++で透過的なHTTPプロキシを構築する方法を学んでいます。プロキシクライアント側には、長い間解決できなかった2つの問題がありました。次のシナリオに基づいて、誰かが根本的な原因を指摘できることを願っています。どうもありがとう。:D
私が今構築したHTTPプロキシは、どういうわけか部分的にしか機能しません。たとえば、キーワードを入力した後、検索結果を取得できなかったときに、プロキシを介してGoogleのメインページにアクセスできました(Googleインスタントもまったく機能していません)。一方、YouTubeは、検索、動画の読み込み、コメントなど、完璧に機能しています。さらに、yahooのようないくつかのWebサイトでは、URLを入力した後もメインページを表示できませんでした。
最初に問題がプロキシクライアント側にあると言ったのは、プログラムのデータフローを追跡したためです。ソケットプログラミング関数write()によって返される書き込みサイズが、ライトバック関数に渡したデータサイズよりも小さいことがわかりました。私にとって最も奇妙な観察は、データ損失の問題がデータのサイズとは無関係であるということでした。ソケットのwrite()関数は、2MB近くのYouTubeビデオデータに対しては適切に機能しますが、わずか20KBのGoogle検索リクエストのデータは失われます。
さらに、ライトバック関数に渡したデータサイズとソケット書き込み関数()によって返される書き込みサイズが同じである場合に、ブラウザーが空白で表示されるという別の状況もありました。私はwiresharkを使用して通信の流れを追跡し、プロキシを使用しない純粋なIP通信と比較しました。純粋なIP通信フローと比較して、特定のHTTP応答を受信した後、ブラウザーがHTTP要求を継続的に送信しないことがわかりました。ブラウザが残りのHTTPリクエストを送信しなかった理由がわかりませんでした。
以下は、ライトバック関数のコードです。
void Proxy::get_data(char* buffer, size_t length)
{
cout<<"Length:"<<length<<endl;
int connfd;
size_t ret;
// get connfd from buffer
memset(&connfd, 0, sizeof(int));
memcpy(&connfd, buffer, sizeof(int));
cout<<"Get Connection FD:"<<connfd<<endl;
// get receive data size
size_t rData_length = length-sizeof(int);
cout<<"Data Size:"<<rData_length<<endl;
// create receive buffer
char* rBuf = new char[rData_length];
// allocate memory to receive buffer
memset(rBuf, 0, rData_length);
// copy data to buffer
memcpy(rBuf, buffer+sizeof(int), rData_length);
ret = write(connfd, rBuf, rData_length);
if(ret < 0)
{
cout<< "received data failed"<< endl;
close(connfd);
delete[] rBuf;
exit(1);
}
else
{
printf("Write Data[%d] to Socket\n", ret);
}
close(connfd);
delete[] rBuf;
}