From d4dae49dcd1e0bbaabf47f5ed221e617426c6e3f Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 18 Aug 2020 20:34:15 -0600 Subject: [PATCH] LibHTTP: Fix processing terminating chunk After encountering the terminating chunk we need to read the trailing headers line by line, until encountering the final empty line. Fixes #3197 --- Libraries/LibHTTP/Job.cpp | 23 ++++++++++++----------- Libraries/LibHTTP/Job.h | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Libraries/LibHTTP/Job.cpp b/Libraries/LibHTTP/Job.cpp index 285338db63e..a3bfb32d78b 100644 --- a/Libraries/LibHTTP/Job.cpp +++ b/Libraries/LibHTTP/Job.cpp @@ -117,12 +117,12 @@ void Job::on_socket_connected() m_state = State::InHeaders; return; } - if (m_state == State::InHeaders || m_state == State::AfterChunkedEncodingTrailer) { + if (m_state == State::InHeaders || m_state == State::Trailers) { if (!can_read_line()) return; auto line = read_line(PAGE_SIZE); if (line.is_null()) { - if (m_state == State::AfterChunkedEncodingTrailer) { + if (m_state == State::Trailers) { // 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. @@ -133,7 +133,7 @@ void Job::on_socket_connected() } auto chomped_line = String::copy(line, Chomp); if (chomped_line.is_empty()) { - if (m_state == State::AfterChunkedEncodingTrailer) { + if (m_state == State::Trailers) { return finish_up(); } else { m_state = State::InBody; @@ -142,7 +142,7 @@ void Job::on_socket_connected() } auto parts = chomped_line.split(':'); if (parts.is_empty()) { - if (m_state == State::AfterChunkedEncodingTrailer) { + if (m_state == State::Trailers) { // 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. @@ -153,7 +153,7 @@ void Job::on_socket_connected() } auto name = parts[0]; if (chomped_line.length() < name.length() + 2) { - if (m_state == State::AfterChunkedEncodingTrailer) { + if (m_state == State::Trailers) { // 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. @@ -186,7 +186,7 @@ void Job::on_socket_connected() #endif if (size_lines.size() == 0) { dbg() << "Job: Reached end of stream"; - m_state = State::AfterChunkedEncodingTrailer; + finish_up(); return IterationDecision::Break; } else { auto chunk = size_lines[0].split_view(';', true); @@ -264,6 +264,12 @@ void Job::on_socket_connected() #ifdef JOB_DEBUG dbg() << "Job: Finished a chunk of " << m_current_chunk_total_size.value() << " bytes"; #endif + + if (m_current_chunk_total_size.value() == 0) { + m_state = State::Trailers; + return IterationDecision::Break; + } + // we've read everything, now let's get the next chunk size = -1; auto line = read_line(PAGE_SIZE); @@ -271,11 +277,6 @@ void Job::on_socket_connected() dbg() << "Line following (should be empty): _" << line << "_"; #endif (void)line; - - if (m_current_chunk_total_size.value() == 0) { - m_state = State::AfterChunkedEncodingTrailer; - return IterationDecision::Break; - } } m_current_chunk_remaining_size = size; } diff --git a/Libraries/LibHTTP/Job.h b/Libraries/LibHTTP/Job.h index 2cc3f559379..ae9c3e2a36d 100644 --- a/Libraries/LibHTTP/Job.h +++ b/Libraries/LibHTTP/Job.h @@ -65,8 +65,8 @@ protected: InStatus, InHeaders, InBody, + Trailers, Finished, - AfterChunkedEncodingTrailer, }; HttpRequest m_request;