ladybird/Libraries/LibRequests/Request.h

107 lines
3.7 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Badge.h>
#include <AK/ByteBuffer.h>
#include <AK/ByteString.h>
#include <AK/Function.h>
#include <AK/MemoryStream.h>
#include <AK/RefCounted.h>
#include <AK/WeakPtr.h>
#include <LibCore/Notifier.h>
#include <LibHTTP/HeaderMap.h>
#include <LibIPC/Forward.h>
#include <LibRequests/NetworkErrorEnum.h>
namespace Requests {
class RequestClient;
class Request : public RefCounted<Request> {
public:
struct CertificateAndKey {
ByteString certificate;
ByteString key;
};
static NonnullRefPtr<Request> create_from_id(Badge<RequestClient>, RequestClient& client, i32 request_id)
{
return adopt_ref(*new Request(client, request_id));
}
int id() const { return m_request_id; }
int fd() const { return m_fd; }
bool stop();
using BufferedRequestFinished = Function<void(u64 total_size, Optional<NetworkError> const& network_error, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> reason_phrase, ReadonlyBytes payload)>;
// Configure the request such that the entirety of the response data is buffered. The callback receives that data and
// the response headers all at once. Using this method is mutually exclusive with `set_unbuffered_data_received_callback`.
void set_buffered_request_finished_callback(BufferedRequestFinished);
using HeadersReceived = Function<void(HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> const& reason_phrase)>;
using DataReceived = Function<void(ReadonlyBytes data)>;
using RequestFinished = Function<void(u64 total_size, Optional<NetworkError> network_error)>;
// Configure the request such that the response data is provided unbuffered as it is received. Using this method is
// mutually exclusive with `set_buffered_request_finished_callback`.
void set_unbuffered_request_callbacks(HeadersReceived, DataReceived, RequestFinished);
Function<CertificateAndKey()> on_certificate_requested;
void did_finish(Badge<RequestClient>, u64 total_size, Optional<NetworkError> const& network_error);
void did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> const& reason_phrase);
void did_request_certificates(Badge<RequestClient>);
RefPtr<Core::Notifier>& write_notifier(Badge<RequestClient>) { return m_write_notifier; }
void set_request_fd(Badge<RequestClient>, int fd);
private:
explicit Request(RequestClient&, i32 request_id);
void set_up_internal_stream_data(DataReceived on_data_available);
WeakPtr<RequestClient> m_client;
int m_request_id { -1 };
RefPtr<Core::Notifier> m_write_notifier;
int m_fd { -1 };
enum class Mode {
Buffered,
Unbuffered,
Unknown,
};
Mode m_mode { Mode::Unknown };
HeadersReceived on_headers_received;
RequestFinished on_finish;
struct InternalBufferedData {
AllocatingMemoryStream payload_stream;
HTTP::HeaderMap response_headers;
Optional<u32> response_code;
Optional<String> reason_phrase;
};
struct InternalStreamData {
InternalStreamData() { }
OwnPtr<Stream> read_stream;
RefPtr<Core::Notifier> read_notifier;
u32 total_size { 0 };
Optional<NetworkError> network_error;
bool request_done { false };
Function<void()> on_finish {};
bool user_finish_called { false };
};
OwnPtr<InternalBufferedData> m_internal_buffered_data;
OwnPtr<InternalStreamData> m_internal_stream_data;
};
}