/src/serenity/Userland/Libraries/LibProtocol/Request.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Badge.h> |
10 | | #include <AK/ByteBuffer.h> |
11 | | #include <AK/ByteString.h> |
12 | | #include <AK/Function.h> |
13 | | #include <AK/MemoryStream.h> |
14 | | #include <AK/RefCounted.h> |
15 | | #include <AK/WeakPtr.h> |
16 | | #include <LibCore/Notifier.h> |
17 | | #include <LibHTTP/HeaderMap.h> |
18 | | #include <LibIPC/Forward.h> |
19 | | |
20 | | namespace Protocol { |
21 | | |
22 | | class RequestClient; |
23 | | |
24 | | class Request : public RefCounted<Request> { |
25 | | public: |
26 | | struct CertificateAndKey { |
27 | | ByteString certificate; |
28 | | ByteString key; |
29 | | }; |
30 | | |
31 | | static NonnullRefPtr<Request> create_from_id(Badge<RequestClient>, RequestClient& client, i32 request_id) |
32 | 0 | { |
33 | 0 | return adopt_ref(*new Request(client, request_id)); |
34 | 0 | } |
35 | | |
36 | 0 | int id() const { return m_request_id; } |
37 | 0 | int fd() const { return m_fd; } |
38 | | bool stop(); |
39 | | |
40 | | using BufferedRequestFinished = Function<void(bool success, u64 total_size, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)>; |
41 | | |
42 | | // Configure the request such that the entirety of the response data is buffered. The callback receives that data and |
43 | | // the response headers all at once. Using this method is mutually exclusive with `set_unbuffered_data_received_callback`. |
44 | | void set_buffered_request_finished_callback(BufferedRequestFinished); |
45 | | |
46 | | using HeadersReceived = Function<void(HTTP::HeaderMap const& response_headers, Optional<u32> response_code)>; |
47 | | using DataReceived = Function<void(ReadonlyBytes data)>; |
48 | | using RequestFinished = Function<void(bool success, u64 total_size)>; |
49 | | |
50 | | // Configure the request such that the response data is provided unbuffered as it is received. Using this method is |
51 | | // mutually exclusive with `set_buffered_request_finished_callback`. |
52 | | void set_unbuffered_request_callbacks(HeadersReceived, DataReceived, RequestFinished); |
53 | | |
54 | | Function<void(Optional<u64> total_size, u64 downloaded_size)> on_progress; |
55 | | Function<CertificateAndKey()> on_certificate_requested; |
56 | | |
57 | | void did_finish(Badge<RequestClient>, bool success, u64 total_size); |
58 | | void did_progress(Badge<RequestClient>, Optional<u64> total_size, u64 downloaded_size); |
59 | | void did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code); |
60 | | void did_request_certificates(Badge<RequestClient>); |
61 | | |
62 | 0 | RefPtr<Core::Notifier>& write_notifier(Badge<RequestClient>) { return m_write_notifier; } |
63 | | void set_request_fd(Badge<RequestClient>, int fd); |
64 | | |
65 | | private: |
66 | | explicit Request(RequestClient&, i32 request_id); |
67 | | |
68 | | void set_up_internal_stream_data(DataReceived on_data_available); |
69 | | |
70 | | WeakPtr<RequestClient> m_client; |
71 | | int m_request_id { -1 }; |
72 | | RefPtr<Core::Notifier> m_write_notifier; |
73 | | int m_fd { -1 }; |
74 | | |
75 | | enum class Mode { |
76 | | Buffered, |
77 | | Unbuffered, |
78 | | Unknown, |
79 | | }; |
80 | | Mode m_mode { Mode::Unknown }; |
81 | | |
82 | | HeadersReceived on_headers_received; |
83 | | RequestFinished on_finish; |
84 | | |
85 | | struct InternalBufferedData { |
86 | | AllocatingMemoryStream payload_stream; |
87 | | HTTP::HeaderMap response_headers; |
88 | | Optional<u32> response_code; |
89 | | }; |
90 | | |
91 | | struct InternalStreamData { |
92 | 0 | InternalStreamData() { } |
93 | | |
94 | | OwnPtr<Stream> read_stream; |
95 | | RefPtr<Core::Notifier> read_notifier; |
96 | | bool success; |
97 | | u32 total_size { 0 }; |
98 | | bool request_done { false }; |
99 | | Function<void()> on_finish {}; |
100 | | bool user_finish_called { false }; |
101 | | }; |
102 | | |
103 | | OwnPtr<InternalBufferedData> m_internal_buffered_data; |
104 | | OwnPtr<InternalStreamData> m_internal_stream_data; |
105 | | }; |
106 | | |
107 | | } |