Serenity Operating System
at master 85 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2020-2022, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/HashMap.h> 10#include <AK/Optional.h> 11#include <LibCore/NetworkJob.h> 12#include <LibCore/Socket.h> 13#include <LibHTTP/HttpRequest.h> 14#include <LibHTTP/HttpResponse.h> 15 16namespace HTTP { 17 18class Job : public Core::NetworkJob { 19 C_OBJECT(Job); 20 21public: 22 explicit Job(HttpRequest&&, Stream&); 23 virtual ~Job() override = default; 24 25 virtual void start(Core::Socket&) override; 26 virtual void shutdown(ShutdownMode) override; 27 28 Core::Socket const* socket() const { return m_socket; } 29 URL url() const { return m_request.url(); } 30 31 HttpResponse* response() { return static_cast<HttpResponse*>(Core::NetworkJob::response()); } 32 HttpResponse const* response() const { return static_cast<HttpResponse const*>(Core::NetworkJob::response()); } 33 34protected: 35 void finish_up(); 36 void on_socket_connected(); 37 void flush_received_buffers(); 38 void register_on_ready_to_read(Function<void()>); 39 ErrorOr<DeprecatedString> read_line(size_t); 40 ErrorOr<ByteBuffer> receive(size_t); 41 void timer_event(Core::TimerEvent&) override; 42 43 enum class State { 44 InStatus, 45 InHeaders, 46 InBody, 47 Trailers, 48 Finished, 49 }; 50 51 HttpRequest m_request; 52 State m_state { State::InStatus }; 53 Core::BufferedSocketBase* m_socket { nullptr }; 54 bool m_legacy_connection { false }; 55 int m_code { -1 }; 56 HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> m_headers; 57 Vector<DeprecatedString> m_set_cookie_headers; 58 59 struct ReceivedBuffer { 60 ReceivedBuffer(ByteBuffer d) 61 : data(move(d)) 62 , pending_flush(data.bytes()) 63 { 64 } 65 66 // The entire received buffer. 67 ByteBuffer data; 68 69 // The bytes we have yet to flush. (This is a slice of `data`) 70 ReadonlyBytes pending_flush; 71 }; 72 73 Vector<NonnullOwnPtr<ReceivedBuffer>> m_received_buffers; 74 75 size_t m_buffered_size { 0 }; 76 size_t m_received_size { 0 }; 77 Optional<u32> m_content_length; 78 Optional<ssize_t> m_current_chunk_remaining_size; 79 Optional<size_t> m_current_chunk_total_size; 80 bool m_can_stream_response { true }; 81 bool m_should_read_chunk_ending_line { false }; 82 bool m_has_scheduled_finish { false }; 83}; 84 85}