1/*
2 * Copyright 2022 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#ifndef _B_HTTP_REQUEST_H_
7#define _B_HTTP_REQUEST_H_
8
9#include <memory>
10#include <optional>
11#include <string_view>
12#include <variant>
13
14#include <ErrorsExt.h>
15#include <String.h>
16
17class BDataIO;
18class BMallocIO;
19class BUrl;
20
21
22namespace BPrivate {
23
24namespace Network {
25
26
27class BHttpFields;
28class HttpBuffer;
29class HttpSerializer;
30
31
32class BHttpMethod
33{
34public:
35	// Constants for default methods in RFC 7230 section 4.2
36	enum Verb { Get, Head, Post, Put, Delete, Connect, Options, Trace };
37
38	// Error type when constructing with a custom method
39	class InvalidMethod;
40
41	// Constructors & Destructor
42								BHttpMethod(Verb verb) noexcept;
43								BHttpMethod(const std::string_view& method);
44								BHttpMethod(const BHttpMethod& other);
45								BHttpMethod(BHttpMethod&& other) noexcept;
46								~BHttpMethod();
47
48	// Assignment operators
49			BHttpMethod&		operator=(const BHttpMethod& other);
50			BHttpMethod&		operator=(BHttpMethod&& other) noexcept;
51
52	// Comparison
53			bool				operator==(const Verb& other) const noexcept;
54			bool				operator!=(const Verb& other) const noexcept;
55
56	// Get the method as a string
57			const std::string_view Method() const noexcept;
58
59private:
60			std::variant<Verb, BString> fMethod;
61};
62
63
64class BHttpMethod::InvalidMethod : public BError
65{
66public:
67								InvalidMethod(const char* origin, BString input);
68
69	virtual	const char*			Message() const noexcept override;
70	virtual	BString				DebugMessage() const override;
71
72			BString				input;
73};
74
75
76struct BHttpAuthentication {
77			BString				username;
78			BString				password;
79};
80
81
82class BHttpRequest
83{
84public:
85	// Aggregate parameter types
86	struct Body;
87
88	// Constructors and Destructor
89								BHttpRequest();
90								BHttpRequest(const BUrl& url);
91								BHttpRequest(const BHttpRequest& other) = delete;
92								BHttpRequest(BHttpRequest&& other) noexcept;
93								~BHttpRequest();
94
95	// Assignment operators
96			BHttpRequest&		operator=(const BHttpRequest& other) = delete;
97			BHttpRequest&		operator=(BHttpRequest&&) noexcept;
98
99	// Access
100			bool				IsEmpty() const noexcept;
101			const BHttpAuthentication* Authentication() const noexcept;
102			const BHttpFields&	Fields() const noexcept;
103			uint8				MaxRedirections() const noexcept;
104			const BHttpMethod&	Method() const noexcept;
105			const Body*			RequestBody() const noexcept;
106			bool				StopOnError() const noexcept;
107			bigtime_t			Timeout() const noexcept;
108			const BUrl&			Url() const noexcept;
109
110	// Named Setters
111			void				SetAuthentication(const BHttpAuthentication& authentication);
112			void				SetFields(const BHttpFields& fields);
113			void				SetMaxRedirections(uint8 maxRedirections);
114			void				SetMethod(const BHttpMethod& method);
115			void				SetRequestBody(std::unique_ptr<BDataIO> input, BString mimeType,
116									std::optional<off_t> size);
117			void				SetStopOnError(bool stopOnError);
118			void				SetTimeout(bigtime_t timeout);
119			void				SetUrl(const BUrl& url);
120
121	// Clearing Options
122			void				ClearAuthentication() noexcept;
123			std::unique_ptr<BDataIO> ClearRequestBody() noexcept;
124
125	// Serialization
126			BString				HeaderToString() const;
127
128private:
129	friend class BHttpSession;
130	friend class HttpSerializer;
131	struct Data;
132
133			bool				RewindBody() noexcept;
134			void				SerializeHeaderTo(HttpBuffer& buffer) const;
135
136			std::unique_ptr<Data> fData;
137};
138
139
140struct BHttpRequest::Body {
141			std::unique_ptr<BDataIO> input;
142			BString				mimeType;
143			std::optional<off_t> size;
144			std::optional<off_t> startPosition;
145};
146
147
148} // namespace Network
149
150} // namespace BPrivate
151
152#endif // _B_HTTP_REQUEST_H_
153