LibGemini: Do not loop in Gemini::Job in case of error
Previously, the job was shutdown only on a deferred invoke while there was still data to be read. This meant that the read callback would get called again and again, and, potentially throw the error again and again This patch introoduces a failed state for the protocol parser and returns early from the read callback if it has already failed
This commit is contained in:
parent
083802d41a
commit
ba9fa59355
Notes:
sideshowbarker
2024-07-17 18:46:57 +09:00
Author: https://github.com/kuzux Commit: https://github.com/SerenityOS/serenity/commit/ba9fa59355 Pull-request: https://github.com/SerenityOS/serenity/pull/16996 Reviewed-by: https://github.com/alimpfard
2 changed files with 8 additions and 0 deletions
|
@ -124,6 +124,8 @@ void Job::on_socket_connected()
|
|||
register_on_ready_to_read([this] {
|
||||
if (is_cancelled())
|
||||
return;
|
||||
if (m_state == State::Failed)
|
||||
return;
|
||||
|
||||
if (m_state == State::InStatus) {
|
||||
if (!can_read_line())
|
||||
|
@ -132,6 +134,7 @@ void Job::on_socket_connected()
|
|||
auto line_or_error = read_line(PAGE_SIZE);
|
||||
if (line_or_error.is_error()) {
|
||||
dbgln("Job: Error getting status line {}", line_or_error.error());
|
||||
m_state = State::Failed;
|
||||
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::TransmissionFailed); });
|
||||
}
|
||||
|
||||
|
@ -141,6 +144,7 @@ void Job::on_socket_connected()
|
|||
auto maybe_space_index = view.find(' ');
|
||||
if (!maybe_space_index.has_value()) {
|
||||
dbgln("Job: Expected 2-part status line, got '{}'", line);
|
||||
m_state = State::Failed;
|
||||
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
|
||||
|
@ -151,6 +155,7 @@ void Job::on_socket_connected()
|
|||
auto status = first_part.to_uint();
|
||||
if (!status.has_value()) {
|
||||
dbgln("Job: Expected numeric status code");
|
||||
m_state = State::Failed;
|
||||
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
|
||||
|
@ -171,6 +176,7 @@ void Job::on_socket_connected()
|
|||
m_state = State::InBody;
|
||||
} else {
|
||||
dbgln("Job: Expected status between 10 and 69; instead got {}", m_status);
|
||||
m_state = State::Failed;
|
||||
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
|
||||
|
@ -188,6 +194,7 @@ void Job::on_socket_connected()
|
|||
auto payload_or_error = receive(read_size);
|
||||
if (payload_or_error.is_error()) {
|
||||
dbgln("Job: Error in receive {}", payload_or_error.error());
|
||||
m_state = State::Failed;
|
||||
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::TransmissionFailed); });
|
||||
}
|
||||
auto payload = payload_or_error.release_value();
|
||||
|
|
|
@ -46,6 +46,7 @@ protected:
|
|||
InStatus,
|
||||
InBody,
|
||||
Finished,
|
||||
Failed,
|
||||
};
|
||||
|
||||
GeminiRequest m_request;
|
||||
|
|
Loading…
Add table
Reference in a new issue