1/*
2 * Copyright 2021 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Niels Sascha Reedijk, niels.reedijk@gmail.com
7 */
8
9#include <NetServicesDefs.h>
10
11
12namespace BPrivate {
13
14namespace Network {
15
16
17// #pragma mark -- BUnsupportedProtocol
18
19
20BUnsupportedProtocol::BUnsupportedProtocol(
21	const char* origin, BUrl url, BStringList supportedProtocols)
22	:
23	BError(origin),
24	fUrl(std::move(url)),
25	fSupportedProtocols(std::move(supportedProtocols))
26{
27}
28
29
30BUnsupportedProtocol::BUnsupportedProtocol(BString origin, BUrl url, BStringList supportedProtocols)
31	:
32	BError(std::move(origin)),
33	fUrl(std::move(url)),
34	fSupportedProtocols(std::move(supportedProtocols))
35{
36}
37
38
39const char*
40BUnsupportedProtocol::Message() const noexcept
41{
42	return "Unsupported Protocol";
43}
44
45
46const BUrl&
47BUnsupportedProtocol::Url() const
48{
49	return fUrl;
50}
51
52
53const BStringList&
54BUnsupportedProtocol::SupportedProtocols() const
55{
56	return fSupportedProtocols;
57}
58
59
60// #pragma mark -- BInvalidUrl
61
62
63BInvalidUrl::BInvalidUrl(const char* origin, BUrl url)
64	:
65	BError(origin),
66	fUrl(std::move(url))
67{
68}
69
70
71BInvalidUrl::BInvalidUrl(BString origin, BUrl url)
72	:
73	BError(std::move(origin)),
74	fUrl(std::move(url))
75{
76}
77
78
79const char*
80BInvalidUrl::Message() const noexcept
81{
82	return "Invalid URL";
83}
84
85
86const BUrl&
87BInvalidUrl::Url() const
88{
89	return fUrl;
90}
91
92
93// #pragma mark -- BNetworkRequestError
94
95
96BNetworkRequestError::BNetworkRequestError(
97	const char* origin, ErrorType type, status_t errorCode, const BString& customMessage)
98	:
99	BError(origin),
100	fErrorType(type),
101	fErrorCode(errorCode),
102	fCustomMessage(customMessage)
103{
104}
105
106
107BNetworkRequestError::BNetworkRequestError(
108	const char* origin, ErrorType type, const BString& customMessage)
109	:
110	BError(origin),
111	fErrorType(type),
112	fCustomMessage(customMessage)
113{
114}
115
116
117const char*
118BNetworkRequestError::Message() const noexcept
119{
120	switch (fErrorType) {
121		case HostnameError:
122			return "Cannot resolving hostname";
123		case NetworkError:
124			return "Network error during operation";
125		case ProtocolError:
126			return "Protocol error";
127		case SystemError:
128			return "System error";
129		case Canceled:
130			return "Network request was canceled";
131	}
132	// Unreachable
133	return "Network request error";
134}
135
136
137BString
138BNetworkRequestError::DebugMessage() const
139{
140	BString debugMessage;
141	debugMessage << "[" << Origin() << "] " << Message();
142	if (fErrorCode != B_OK) {
143		debugMessage << "\n\tUnderlying System Error: " << fErrorCode << " ("
144					 << strerror(fErrorCode) << ")";
145	}
146	if (fCustomMessage.Length() > 0) {
147		debugMessage << "\n\tAdditional Info: " << fCustomMessage;
148	}
149	return debugMessage;
150}
151
152
153BNetworkRequestError::ErrorType
154BNetworkRequestError::Type() const noexcept
155{
156	return fErrorType;
157}
158
159
160status_t
161BNetworkRequestError::ErrorCode() const noexcept
162{
163	return fErrorCode;
164}
165
166
167const char*
168BNetworkRequestError::CustomMessage() const noexcept
169{
170	return fCustomMessage.String();
171}
172
173
174// #pragma mark -- Public functions
175
176
177static const char* kBase64Symbols
178	= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
179
180
181BString
182encode_to_base64(const BString& string)
183{
184	BString result;
185	BString tmpString = string;
186
187	while (tmpString.Length()) {
188		char in[3] = {0, 0, 0};
189		char out[4] = {0, 0, 0, 0};
190		int8 remaining = tmpString.Length();
191
192		tmpString.MoveInto(in, 0, 3);
193
194		out[0] = (in[0] & 0xFC) >> 2;
195		out[1] = ((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4);
196		out[2] = ((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6);
197		out[3] = in[2] & 0x3F;
198
199		for (int i = 0; i < 4; i++)
200			out[i] = kBase64Symbols[(int) out[i]];
201
202		//  Add padding if the input length is not a multiple
203		// of 3
204		switch (remaining) {
205			case 1:
206				out[2] = '=';
207				// Fall through
208			case 2:
209				out[3] = '=';
210				break;
211		}
212
213		result.Append(out, 4);
214	}
215
216	return result;
217}
218
219
220// #pragma mark -- message constants
221namespace UrlEventData {
222const char* Id = "url:identifier";
223const char* HostName = "url:hostname";
224const char* NumBytes = "url:numbytes";
225const char* TotalBytes = "url:totalbytes";
226const char* Success = "url:success";
227const char* DebugType = "url:debugtype";
228const char* DebugMessage = "url:debugmessage";
229} // namespace UrlEventData
230
231
232// #pragma mark -- Private functions and data
233
234
235static int32 gRequestIdentifier = 1;
236
237
238int32
239get_netservices_request_identifier()
240{
241	return atomic_add(&gRequestIdentifier, 1);
242}
243
244
245} // namespace Network
246
247} // namespace BPrivate
248