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 12 namespace BPrivate { 13 14 namespace Network { 15 16 17 // #pragma mark -- BUnsupportedProtocol 18 19 20 BUnsupportedProtocol::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 30 BUnsupportedProtocol::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 39 const char* 40 BUnsupportedProtocol::Message() const noexcept 41 { 42 return "Unsupported Protocol"; 43 } 44 45 46 const BUrl& 47 BUnsupportedProtocol::Url() const 48 { 49 return fUrl; 50 } 51 52 53 const BStringList& 54 BUnsupportedProtocol::SupportedProtocols() const 55 { 56 return fSupportedProtocols; 57 } 58 59 60 // #pragma mark -- BInvalidUrl 61 62 63 BInvalidUrl::BInvalidUrl(const char* origin, BUrl url) 64 : 65 BError(origin), 66 fUrl(std::move(url)) 67 { 68 } 69 70 71 BInvalidUrl::BInvalidUrl(BString origin, BUrl url) 72 : 73 BError(std::move(origin)), 74 fUrl(std::move(url)) 75 { 76 } 77 78 79 const char* 80 BInvalidUrl::Message() const noexcept 81 { 82 return "Invalid URL"; 83 } 84 85 86 const BUrl& 87 BInvalidUrl::Url() const 88 { 89 return fUrl; 90 } 91 92 93 // #pragma mark -- BNetworkRequestError 94 95 96 BNetworkRequestError::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 107 BNetworkRequestError::BNetworkRequestError( 108 const char* origin, ErrorType type, const BString& customMessage) 109 : 110 BError(origin), 111 fErrorType(type), 112 fCustomMessage(customMessage) 113 { 114 } 115 116 117 const char* 118 BNetworkRequestError::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 137 BString 138 BNetworkRequestError::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 153 BNetworkRequestError::ErrorType 154 BNetworkRequestError::Type() const noexcept 155 { 156 return fErrorType; 157 } 158 159 160 status_t 161 BNetworkRequestError::ErrorCode() const noexcept 162 { 163 return fErrorCode; 164 } 165 166 167 const char* 168 BNetworkRequestError::CustomMessage() const noexcept 169 { 170 return fCustomMessage.String(); 171 } 172 173 174 // #pragma mark -- Public functions 175 176 177 static const char* kBase64Symbols 178 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 179 180 181 BString 182 encode_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 221 namespace UrlEventData { 222 const char* Id = "url:identifier"; 223 const char* HostName = "url:hostname"; 224 const char* NumBytes = "url:numbytes"; 225 const char* TotalBytes = "url:totalbytes"; 226 const char* Success = "url:success"; 227 const char* DebugType = "url:debugtype"; 228 const char* DebugMessage = "url:debugmessage"; 229 } // namespace UrlEventData 230 231 232 // #pragma mark -- Private functions and data 233 234 235 static int32 gRequestIdentifier = 1; 236 237 238 int32 239 get_netservices_request_identifier() 240 { 241 return atomic_add(&gRequestIdentifier, 1); 242 } 243 244 245 } // namespace Network 246 247 } // namespace BPrivate 248