From ec0315883beca84ab143f094d10703034b6dc896 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sun, 26 Jul 2020 06:38:33 +0430 Subject: LibHTTP: Be more tolerant about bad chunked encoding trailers Some servers (*glares at cloudflare*) like to send two last chunks, which is strictly against the spec. Let's be more tolerant of this behaviour. --- Libraries/LibHTTP/HttpJob.h | 1 + Libraries/LibHTTP/Job.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'Libraries') diff --git a/Libraries/LibHTTP/HttpJob.h b/Libraries/LibHTTP/HttpJob.h index 9eff924e34..4cd306c102 100644 --- a/Libraries/LibHTTP/HttpJob.h +++ b/Libraries/LibHTTP/HttpJob.h @@ -51,6 +51,7 @@ public: virtual void shutdown() override; protected: + virtual bool should_fail_on_empty_payload() const override { return false; } virtual void register_on_ready_to_read(Function) override; virtual void register_on_ready_to_write(Function) override; virtual bool can_read_line() const override; diff --git a/Libraries/LibHTTP/Job.cpp b/Libraries/LibHTTP/Job.cpp index c1d5e8bae6..36d47f9455 100644 --- a/Libraries/LibHTTP/Job.cpp +++ b/Libraries/LibHTTP/Job.cpp @@ -122,6 +122,12 @@ void Job::on_socket_connected() return; auto line = read_line(PAGE_SIZE); if (line.is_null()) { + if (m_state == State::AfterChunkedEncodingTrailer) { + // Some servers like to send two ending chunks + // use this fact as an excuse to ignore anything after the last chunk + // that is not a valid trailing header. + return finish_up(); + } fprintf(stderr, "Job: Expected HTTP header\n"); return did_fail(Core::NetworkJob::Error::ProtocolFailed); } @@ -136,11 +142,23 @@ void Job::on_socket_connected() } auto parts = chomped_line.split(':'); if (parts.is_empty()) { + if (m_state == State::AfterChunkedEncodingTrailer) { + // Some servers like to send two ending chunks + // use this fact as an excuse to ignore anything after the last chunk + // that is not a valid trailing header. + return finish_up(); + } fprintf(stderr, "Job: Expected HTTP header with key/value\n"); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); } auto name = parts[0]; if (chomped_line.length() < name.length() + 2) { + if (m_state == State::AfterChunkedEncodingTrailer) { + // Some servers like to send two ending chunks + // use this fact as an excuse to ignore anything after the last chunk + // that is not a valid trailing header. + return finish_up(); + } fprintf(stderr, "Job: Malformed HTTP header: '%s' (%zu)\n", chomped_line.characters(), chomped_line.length()); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); } -- cgit v1.2.3