0

C でプロキシ サーバーを実装するのに苦労しています。最初のいくつかの Web ページでは機能しますが、新しいリクエストを待っている間にブロックされます。

デザイン:

Firefox -> Proxy -> Webserver --.
Firefox <- Proxy <- Webserver <-'

したがって、各リクエストは、ブラウザからプロキシおよびサーバーへの往復です。リクエストからのレスポンスが返ってくるまで、何も起こらないはずです。私はパイプライン、スレッド、またはそのようなものを使用せず、線形シリアル方式のみrecv()を使用します (単純さと直感のため)。また、永続的な接続send()が必要なため、ソケットを閉じません。

css、img、jsなどのサブリクエストされたリソースを含む1つのWebページ全体を取得できると期待しています.

私の実装では、Web ページに対するいくつかの最初のリクエストを取得することができました。次に、ステップ 1 でハングします

実装:

puts("Waiting for user to connect..");
int sock_user = accept(sock, (struct sockaddr*)NULL, NULL);
int sock_host = -1;
printf("User connected.\n");


// Accept requests
while(1){

   http_request req;
   http_response resp;


   // 1. Client ==> Proxy     Server
   http_parse_request(sock_user, &req);                         // uses recv()

   // 2. Client     Proxy ==> Server
   if (sock_host < 0)
      sock_host = proxy_connect_host(req.header->host);
   write(sock_host, req.header->raw_data, req.header->raw_size);

   // 3. Client     Proxy <== Server
   http_parse_response(sock_host, &resp);                      // uses recv()

   // 4. Client <== Proxy     Server
   write(sock_user, resp.header->raw_data,          resp.header->raw_size);
   write(sock_user, resp.body  ->first_block->data, resp.body  ->first_block->size);

}

ログ:

     ---- ......................................... ----

     ---- after succesfully responded to 4 requests ----


Client ==> Proxy     Server
                                Received              389

Client     Proxy ==> Server
                                Sending..             389
                                Sent                  389

Client     Proxy <== Server
                                Got header            312
                                Got body              1437
                                Response total        1749

Client <== Proxy     Server
                                Sending header..      312
                                Sent                  312
                                Sending body..        1437
                                Sent                  1437

Client ==> Proxy     Server


                ---- Hangs/blocks here ----

ファイアーバグ:

ここに画像の説明を入力

Wireshark: ここに画像の説明を入力

そのブロックの理由が何であるかについての直感はありません。ブレークスルーなしでこの問題を解決するために丸 1 週間を費やしました。

問題を解決しようとしたものの中で:

  1. CRLF応答本文ごとに追加の送信
  2. recv()とのそれぞれからの戻り値を確認しましたsend()。(上記のログでは、出力される値はからの戻り値ですrecvsend)

誰かがこれをトラブルシューティングする方法について少なくとも何らかの方向性を示してくれることを願っています:)

4

1 に答える 1

0

あまり多くのデータを読み取らないように注意する必要があります。たとえば、次のことを確認してください。

  • ヘッダーは、ダブル CRLF まで読み取り専用です。余分なデータを保存し、本文とともに送信します

  • 本文の送信は、サーバーが完全なヘッダーを送信する前ではなく開始されます (この GET ケースには適用されませんが、POST または CONNECT では重要です)

  • 本文から Content-Length バイトのみが送受信されます

これは、クライアント -> プロキシ リクエストとサーバー -> プロキシ レスポンスの両方に適用されます。

サンプル コードは無限ループ ( while (1) ...) にとどまります。これをどのように中止しますか?「Proxy-Connection」ヘッダーを尊重しますか?

于 2013-10-26T14:15:03.317 に答える