/* * Copyright 2021 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Niels Sascha Reedijk, niels.reedijk@gmail.com */ #include namespace BPrivate { namespace Network { // #pragma mark -- BUnsupportedProtocol BUnsupportedProtocol::BUnsupportedProtocol( const char* origin, BUrl url, BStringList supportedProtocols) : BError(origin), fUrl(std::move(url)), fSupportedProtocols(std::move(supportedProtocols)) { } BUnsupportedProtocol::BUnsupportedProtocol(BString origin, BUrl url, BStringList supportedProtocols) : BError(std::move(origin)), fUrl(std::move(url)), fSupportedProtocols(std::move(supportedProtocols)) { } const char* BUnsupportedProtocol::Message() const noexcept { return "Unsupported Protocol"; } const BUrl& BUnsupportedProtocol::Url() const { return fUrl; } const BStringList& BUnsupportedProtocol::SupportedProtocols() const { return fSupportedProtocols; } // #pragma mark -- BInvalidUrl BInvalidUrl::BInvalidUrl(const char* origin, BUrl url) : BError(origin), fUrl(std::move(url)) { } BInvalidUrl::BInvalidUrl(BString origin, BUrl url) : BError(std::move(origin)), fUrl(std::move(url)) { } const char* BInvalidUrl::Message() const noexcept { return "Invalid URL"; } const BUrl& BInvalidUrl::Url() const { return fUrl; } // #pragma mark -- BNetworkRequestError BNetworkRequestError::BNetworkRequestError( const char* origin, ErrorType type, status_t errorCode, const BString& customMessage) : BError(origin), fErrorType(type), fErrorCode(errorCode), fCustomMessage(customMessage) { } BNetworkRequestError::BNetworkRequestError( const char* origin, ErrorType type, const BString& customMessage) : BError(origin), fErrorType(type), fCustomMessage(customMessage) { } const char* BNetworkRequestError::Message() const noexcept { switch (fErrorType) { case HostnameError: return "Cannot resolving hostname"; case NetworkError: return "Network error during operation"; case ProtocolError: return "Protocol error"; case SystemError: return "System error"; case Canceled: return "Network request was canceled"; } // Unreachable return "Network request error"; } BString BNetworkRequestError::DebugMessage() const { BString debugMessage; debugMessage << "[" << Origin() << "] " << Message(); if (fErrorCode != B_OK) { debugMessage << "\n\tUnderlying System Error: " << fErrorCode << " (" << strerror(fErrorCode) << ")"; } if (fCustomMessage.Length() > 0) { debugMessage << "\n\tAdditional Info: " << fCustomMessage; } return debugMessage; } BNetworkRequestError::ErrorType BNetworkRequestError::Type() const noexcept { return fErrorType; } status_t BNetworkRequestError::ErrorCode() const noexcept { return fErrorCode; } const char* BNetworkRequestError::CustomMessage() const noexcept { return fCustomMessage.String(); } // #pragma mark -- Public functions static const char* kBase64Symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; BString encode_to_base64(const BString& string) { BString result; BString tmpString = string; while (tmpString.Length()) { char in[3] = {0, 0, 0}; char out[4] = {0, 0, 0, 0}; int8 remaining = tmpString.Length(); tmpString.MoveInto(in, 0, 3); out[0] = (in[0] & 0xFC) >> 2; out[1] = ((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4); out[2] = ((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6); out[3] = in[2] & 0x3F; for (int i = 0; i < 4; i++) out[i] = kBase64Symbols[(int) out[i]]; // Add padding if the input length is not a multiple // of 3 switch (remaining) { case 1: out[2] = '='; // Fall through case 2: out[3] = '='; break; } result.Append(out, 4); } return result; } // #pragma mark -- message constants namespace UrlEventData { const char* Id = "url:identifier"; const char* HostName = "url:hostname"; const char* NumBytes = "url:numbytes"; const char* TotalBytes = "url:totalbytes"; const char* Success = "url:success"; const char* DebugType = "url:debugtype"; const char* DebugMessage = "url:debugmessage"; } // namespace UrlEventData // #pragma mark -- Private functions and data static int32 gRequestIdentifier = 1; int32 get_netservices_request_identifier() { return atomic_add(&gRequestIdentifier, 1); } } // namespace Network } // namespace BPrivate