2

症状

Mozilla Firefox と Google Chrome の両方が同じエラーを生成するため、何かを台無しにしたと思います。Web サーバーが送信する応答全体を受信して​​いません。CURL は見逃すことはありません。クイック スクロール応答の最後の行は常に"</html>"です。

理由

その理由は、多くの部分で応答を送信するためです。

    sendHeaders();  // is calls sendResponse with a fix header
    sendResponse(html_opening_part);
    for ( ...scan some data... ) {
        sendResponse(the_data);
    } // for
    sendResponse(html_closing_part)

ブラウザーはsendResponse()呼び出しの間にデータの受信を停止します。また、Web サーバーは最後にソケットをclose()しません。

(なぜ私がこのようにしているのか: 私が書いたプログラムは Linux 以外のシステム用に設計されており、組み込みコンピューターで実行されます。メモリはそれほど多くなく、ほとんどがlwIPスタックによって占められています。比較的 - 巨大なウェブページなので、分割して送信します。ブラウザはそれを好み、Linux のように HTML が壊れることはありませんでした。)

環境

プラットフォームは GNU/Linux (3.0 カーネルの Ubuntu 32 ビット) です。私の小さなWebサーバーは、クライアントの標準的な方法に物を送り返します:

    int sendResponse(char* data,int length) {

        int x = send(fd,data,length,MSG_NOSIGNAL);
        if (x == -1) {
            perror("this message never printed, so there's no error \n");
            if (errno == EPIPE) return 0;
            if (errno == ECONNRESET) return 0;

            ... panic() ... (never happened) ...

        } // if send()

    } // sendResponse()

そして、ここに私が使用している固定ヘッダーがあります:

    sendResponse(
        "HTTP/1.0 200 OK\n"
        "Server: MyTinyWebServer\n"
        "Content-Type: text/html; charset=UTF-8\n"
        "Cache-Control: no-store, no-cache\n"
        "Pragma: no-cache\n"
        "Connection: close\n"
        "\n"
    );

質問

これは正常ですか?単一のsend()で応答全体を送信する必要がありますか? (迅速な解決策が見つかるまで、私は現在取り組んでいます。)

4

2 に答える 2

1

RFC 2616 を読むと、行末に を使用する必要があることがわかりますCR+LF

それとは別に、ブラウザ開発者ツールを開いて、彼らが行っている正確なリクエストを確認してください。Netcat などのツールを使用してリクエストを複製し、機能し始めるまで各ヘッダーを順番に削除します。

于 2012-05-15T09:29:53.093 に答える
0

ガッチャ!

@Jim がアドバイスしたように、Mozilla と同じヘッダーを CURL で送信しようとしました: fail、壊れたパイプなど。ヘッダーの半分を削除しました: ok。1 つずつ追加し直しました: failヘッダーの別の半分を削除しました:わかりました...ヘッダーが長すぎる場合にのみ、エラーが発生します。ビンゴ。

私が言ったように、組み込みデバイスには非常に少量のメモリしかありません。そのため、リクエスト ヘッダー全体を読み取るのではなく、256 バイトのみを読み取ります。GET パラメータと「ホスト」ヘッダーのみが必要です (IP アドレスの代わりに同じ「ホスト」でリダイレクトを実行するためだけに、実際には必要ありません)。

そのため、リクエスト ヘッダー全体をrecv()しないと、応答全体を send()することはできません。

アドバイスをありがとう、みんな!

于 2012-05-15T10:29:33.273 に答える