1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08:11 +00:00
serenity/Userland/Libraries/LibGemini/Job.h
Arda Cinar ba9fa59355 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
2023-01-14 12:28:02 +01:00

62 lines
1.6 KiB
C++

/*
* Copyright (c) 2020-2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <LibCore/NetworkJob.h>
#include <LibGemini/GeminiRequest.h>
#include <LibGemini/GeminiResponse.h>
namespace Gemini {
class Job : public Core::NetworkJob {
C_OBJECT(Job);
public:
explicit Job(GeminiRequest const&, Core::Stream::Stream&);
virtual ~Job() override = default;
virtual void start(Core::Stream::Socket&) override;
virtual void shutdown(ShutdownMode) override;
GeminiResponse* response() { return static_cast<GeminiResponse*>(Core::NetworkJob::response()); }
GeminiResponse const* response() const { return static_cast<GeminiResponse const*>(Core::NetworkJob::response()); }
const URL& url() const { return m_request.url(); }
Core::Stream::Socket const* socket() const { return m_socket; }
ErrorOr<size_t> response_length() const;
protected:
void finish_up();
void on_socket_connected();
void flush_received_buffers();
void register_on_ready_to_read(Function<void()>);
bool can_read_line() const;
ErrorOr<String> read_line(size_t);
bool can_read() const;
ErrorOr<ByteBuffer> receive(size_t);
bool write(ReadonlyBytes);
enum class State {
InStatus,
InBody,
Finished,
Failed,
};
GeminiRequest m_request;
State m_state { State::InStatus };
int m_status { -1 };
DeprecatedString m_meta;
Vector<ByteBuffer, 2> m_received_buffers;
size_t m_received_size { 0 };
size_t m_buffered_size { 0 };
Core::Stream::BufferedSocketBase* m_socket { nullptr };
};
}