web-dev-qa-db-ja.com

Cloudflare経由でHTTP 404ページを返すときの「無効な応答」

私のウェブサイトはSSLを有効にするためにCloudflareを使用しています(ホストであるHostgatorでは無料のSSLは利用できません)。 404ページを返す場合を除き、すべてが正常に機能しているようです。その結果

このサイトにアクセスできません

https://example.com/example-url のWebページが一時的にダウンしているか、新しいWebアドレスに永久に移動した可能性があります。

ERR_INVALID_RESPONSE

404の代わりにHTTP 200応答コードを送信すると、同じURLであってもすべてが正常に機能します。また、HTTP 500を送信しようとしましたが、これも正常に機能します!したがって、問題を引き起こしているのは、404応答コードに関するものです。

問題がCloudflareに関係していると思う理由は

  1. ローカル開発環境(SSLを使用しない)で正常に動作します。
  2. curl https://example.com/example-urlを実行すると、正しい404ページが返され、HTTPステータスは予想どおり404です。

Cloudflareを使用している他のサイトもありますが、404応答を返すのに問題はないようです。これは、この1つのサイトのCloudflareの設定の問題だと思います。

何か案は?

1
Magnus W

問題は、応答ヘッダーをどのように生成していたかでした。

Slim PHPフレームワークとカスタムエラーハンドラミドルウェアを使用しています。このように見えた:

class ErrorResponseHandler {

    protected $view = null;

    function __construct(\Slim\Views\Twig $view) {
        $this->view = $view;
    }


    public function __invoke(Request $request, Response $response, $next) {
        $response = $next($request, $response);

        if (404 === $response->getStatusCode() ) {
            // Pass an empty response to the 404-handler in MainController
            return (new MainController($this->view))->notFound404($request, new Response());
        }

        // Any other request, pass on current response
        return $response;
    }

}

Slimによって生成されたデフォルトの404 HTMLなしで空のボディを取得するために、新しいResponseオブジェクトを作成しています。ただし、新しいResponseオブジェクトを作成すると、明らかにContent-Typeヘッダーがapplication/x-httpd-php5に設定されますが、これはブラウザーには理解されません(curl --headを使用するときにこれを確認する必要がありますが、それを逃しました)。

解決策は、次のように正しいContent-Typeヘッダーを設定することです。

    if (404 === $response->getStatusCode() ) {
        // Pass an empty response to the 404-handler in MainController
        $new_response = (new Response())->withHeader('Content-Type', 'text/html');
        return (new MainController($this->view))->notFound404($request, $new_response);
    }
1
Magnus W