├── .gitignore ├── .gitattributes ├── README.md ├── stdinc.cpp ├── web-server ├── version.h ├── SystemUtil.h ├── ContextMenuManager.cpp ├── TarFile.h ├── ApiRouter.h ├── HttpRequest.h ├── SessionListener.h ├── SocketManagerListener.h ├── SystemUtil.cpp ├── LazyInitWrapper.h ├── WebUserManagerListener.h ├── Access.h ├── ExtensionListener.h ├── JsonUtil.cpp ├── WebServerManagerListener.h ├── HttpUtil.h ├── NpmRepository.h ├── Exception.h ├── ExtensionManagerListener.h ├── TarFile.cpp ├── WebSocket.h ├── HttpManager.h ├── FileServer.h ├── WebUser.h ├── IServerEndpoint.h ├── SocketManager.h ├── ApiRouter.cpp ├── ContextMenuItem.h ├── Session.h ├── Timer.h └── WebServerSettings.h ├── api ├── common │ ├── Validation.h │ ├── Validation.cpp │ ├── Format.h │ ├── FileSearchParser.h │ ├── Format.cpp │ ├── SettingUtils.h │ ├── ViewTasks.h │ ├── MessageUtils.h │ └── Property.h ├── FilesystemApi.h ├── ConnectivityApi.h ├── EventApi.h ├── SystemApi.h ├── HistoryApi.h ├── FilelistUtils.h ├── SettingApi.h ├── WebUserUtils.h ├── SearchUtils.h ├── OnlineUserUtils.h ├── FavoriteDirectoryApi.h ├── TransferUtils.h ├── QueueBundleUtils.h ├── WebUserApi.h ├── FilelistItemInfo.cpp ├── ShareUtils.h ├── platform │ └── windows │ │ └── Filesystem.h ├── QueueFileUtils.h ├── PrivateChatApi.h ├── ExtensionApi.h ├── FavoriteHubApi.h ├── ViewFileApi.h ├── FavoriteHubUtils.h ├── ShareProfileApi.h ├── HubApi.h ├── UserApi.h ├── SessionApi.h ├── HashApi.h ├── TransferApi.h ├── FilelistItemInfo.h ├── SearchApi.h ├── ShareRootApi.h ├── ExtensionInfo.h ├── base │ ├── SubscribableApiModule.h │ ├── HookApiModule.h │ ├── HookActionHandler.h │ ├── ApiModule.cpp │ └── SubscribableApiModule.cpp ├── WebUserUtils.cpp ├── FilelistApi.h ├── SearchEntity.h ├── PrivateChatInfo.h ├── FilelistInfo.h └── EventApi.cpp ├── json.h ├── stdinc.h ├── CMakeLists.txt ├── microtar └── microtar.h └── forward.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.sdf 2 | /packages 3 | *.user 4 | *.config 5 | *.psess 6 | *.vspx 7 | *.aps 8 | Thumbs.db 9 | *.suo 10 | *.opensdf 11 | *.exe -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | *.vcxproj text=crlf 5 | *.vcxproj.filters text=crlf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AirDC++ Web API 2 | 3 | A Websocket/REST API for applications using the [AirDC++ core](https://github.com/airdcpp/airdcpp-core), such as [AirDC++ (Windows)](https://github.com/airdcpp/airgit) and [AirDC++ Web Client](https://github.com/airdcpp-web/airdcpp-webclient/). 4 | 5 | Consult the documentation of the respective project for more information about setting up API access. 6 | 7 | Issues and pull requests should be posted either for [AirDC++ (Windows)](https://github.com/airdcpp/airdcpp-windows) or [AirDC++ Web Client](https://github.com/airdcpp-web/airdcpp-webclient/). 8 | 9 | ## Documentation 10 | 11 | API reference is available at http://apidocs.airdcpp.net 12 | 13 | -------------------------------------------------------------------------------- /stdinc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2001-2024 Jacek Sieka, arnetheduck on gmail point com 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | -------------------------------------------------------------------------------- /web-server/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_API_VERSION_H 20 | #define DCPLUSPLUS_API_VERSION_H 21 | 22 | namespace webserver { 23 | #define API_VERSION 1 24 | #define API_FEATURE_LEVEL 10 25 | 26 | } 27 | 28 | #endif -------------------------------------------------------------------------------- /web-server/SystemUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_SYSTEMUTIL_H 20 | #define DCPLUSPLUS_WEBSERVER_SYSTEMUTIL_H 21 | 22 | #include "forward.h" 23 | 24 | namespace webserver { 25 | class SystemUtil { 26 | public: 27 | static string getHostname() noexcept; 28 | static string getPlatform() noexcept; 29 | }; 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /api/common/Validation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2011-2024 AirDC++ Project 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | */ 19 | 20 | #ifndef DCPLUSPLUS_DCPP_VALIDATION_H 21 | #define DCPLUSPLUS_DCPP_VALIDATION_H 22 | 23 | #include 24 | 25 | namespace webserver { 26 | class Validation { 27 | public: 28 | static const string& validateAdcDirectoryPath(const string& aPath); 29 | }; 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /web-server/ContextMenuManager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include "ContextMenuManager.h" 22 | 23 | 24 | namespace webserver { 25 | const string ContextMenuManager::URLS_SUPPORT("urls"); 26 | 27 | ContextMenuManager::ContextMenuManager() { 28 | 29 | } 30 | 31 | ContextMenuManager::~ContextMenuManager() { 32 | 33 | } 34 | 35 | } // namespace webserver -------------------------------------------------------------------------------- /web-server/TarFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_TARFILE_H 20 | #define DCPLUSPLUS_WEBSERVER_TARFILE_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | namespace webserver { 27 | class TarFile { 28 | public: 29 | TarFile(const string& aPath); 30 | ~TarFile(); 31 | 32 | void extract(const string& aDestPath); 33 | private: 34 | mtar_t tar; 35 | }; 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /json.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2011-2015 AirDC++ Project 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | */ 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_JSON_H 21 | #define DCPLUSPLUS_WEBSERVER_JSON_H 22 | 23 | #include 24 | 25 | #include 26 | 27 | 28 | namespace webserver { 29 | using json = nlohmann::json; 30 | 31 | using ArgumentException = webserver::JsonException; 32 | 33 | using SettingValueMap = std::map; 34 | } 35 | 36 | #endif // !defined(DCPLUSPLUS_WEBSERVER_JSON_H) 37 | -------------------------------------------------------------------------------- /web-server/ApiRouter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_APIROUTER_H 20 | #define DCPLUSPLUS_WEBSERVER_APIROUTER_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | namespace webserver { 27 | struct RouterRequest; 28 | 29 | class ApiRouter { 30 | public: 31 | static api_return handleRequest(RouterRequest& aRequest) noexcept; 32 | private: 33 | static api_return routeAuthRequest(RouterRequest& aRequest); 34 | }; 35 | } 36 | 37 | #endif -------------------------------------------------------------------------------- /api/common/Validation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include "Validation.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace webserver { 28 | const string& Validation::validateAdcDirectoryPath(const string& aPath) { 29 | if (!PathUtil::isAdcDirectoryPath(aPath)) { 30 | JsonUtil::throwError("Path", JsonException::ERROR_INVALID, "Path " + aPath + " isn't a valid ADC directory path"); 31 | } 32 | 33 | return aPath; 34 | } 35 | } -------------------------------------------------------------------------------- /web-server/HttpRequest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_HTTP_REQUEST_H 20 | #define DCPLUSPLUS_WEBSERVER_HTTP_REQUEST_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | namespace webserver { 27 | struct HttpRequest { 28 | const SessionPtr& session; 29 | const string& ip; 30 | const std::string& path; 31 | // Adapter-agnostic snapshot of HTTP request fields 32 | std::string method; 33 | std::string body; 34 | // Header accessor provided by the endpoint 35 | std::function getHeader; 36 | bool secure; 37 | }; 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /web-server/SessionListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_SESSIONLISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_SESSIONLISTENER_H 22 | 23 | #include "forward.h" 24 | 25 | namespace webserver { 26 | 27 | class SessionListener { 28 | public: 29 | virtual ~SessionListener() { } 30 | template struct X { enum { TYPE = I }; }; 31 | 32 | typedef X<0> SocketConnected; 33 | typedef X<1> SocketDisconnected; 34 | 35 | virtual void on(SocketConnected, const WebSocketPtr&) noexcept { } 36 | virtual void on(SocketDisconnected) noexcept { } 37 | }; 38 | 39 | } 40 | 41 | #endif // !defined(DCPLUSPLUS_DCPP_SESSIONLISTENER_H) -------------------------------------------------------------------------------- /api/FilesystemApi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2011-2024 AirDC++ Project 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | */ 19 | 20 | #ifndef DCPLUSPLUS_DCPP_FILESYSTEM_API_H 21 | #define DCPLUSPLUS_DCPP_FILESYSTEM_API_H 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace webserver { 28 | class FilesystemApi : public ApiModule { 29 | public: 30 | FilesystemApi(Session* aSession); 31 | ~FilesystemApi(); 32 | private: 33 | api_return handleListItems(ApiRequest& aRequest); 34 | api_return handlePostDirectory(ApiRequest& aRequest); 35 | api_return handleGetDiskInfo(ApiRequest& aRequest); 36 | 37 | json serializeDirectoryContent(const string& aPath, bool aDirectoriesOnly); 38 | }; 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /api/common/Format.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FORMAT_H 20 | #define DCPLUSPLUS_DCPP_FORMAT_H 21 | 22 | #include 23 | 24 | namespace webserver { 25 | class Format { 26 | public: 27 | static std::string formatIp(const string& aIP, const string& aCountryCode) noexcept; 28 | static std::string formatIp(const string& aIP) noexcept; 29 | 30 | // Basic string conversion for copying/filtering (will ignore the hint) 31 | static std::string nicksToString(const HintedUser& aUser) noexcept; 32 | 33 | // Basic string conversion for copying/filtering (will ignore the hint) 34 | static std::string hubsToString(const HintedUser& aUser) noexcept; 35 | }; 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /web-server/SocketManagerListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_SOCKET_MANAGER_LISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_SOCKET_MANAGER_LISTENER_H 22 | 23 | #include "forward.h" 24 | #include "stdinc.h" 25 | 26 | namespace webserver { 27 | class SocketManagerListener { 28 | public: 29 | virtual ~SocketManagerListener() = default; 30 | template struct X { enum { TYPE = I }; }; 31 | 32 | typedef X<0> SocketConnected; 33 | typedef X<1> SocketDisconnected; 34 | 35 | virtual void on(SocketConnected, const WebSocketPtr&) noexcept { } 36 | virtual void on(SocketDisconnected, const WebSocketPtr&) noexcept { } 37 | }; 38 | 39 | } 40 | 41 | #endif // !defined(DCPLUSPLUS_WEBSERVER_SOCKET_MANAGER_LISTENER_H) -------------------------------------------------------------------------------- /api/common/FileSearchParser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILESEARCH_PARSER_H 20 | #define DCPLUSPLUS_DCPP_FILESEARCH_PARSER_H 21 | 22 | #include 23 | #include 24 | 25 | namespace webserver { 26 | class FileSearchParser { 27 | public: 28 | static SearchPtr parseSearch(const json& aJson, bool aIsDirectSearch); 29 | 30 | static string parseSearchType(const string& aType); 31 | static string serializeSearchType(const string& aType); 32 | private: 33 | static void parseMatcher(const json& aJson, const SearchPtr& aSearch); 34 | static void parseOptions(const json& aJson, const SearchPtr& aSearch); 35 | 36 | static Search::MatchType parseMatchType(const string& aTypeStr); 37 | }; 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /web-server/SystemUtil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | #include 21 | 22 | #include 23 | 24 | namespace webserver { 25 | string SystemUtil::getHostname() noexcept { 26 | #ifdef _WIN32 27 | TCHAR computerName[1024]; 28 | DWORD size = 1024; 29 | GetComputerName(computerName, &size); 30 | return Text::fromT(computerName); 31 | #else 32 | char hostname[128]; 33 | gethostname(hostname, sizeof hostname); 34 | return hostname; 35 | #endif 36 | } 37 | 38 | string SystemUtil::getPlatform() noexcept { 39 | #ifdef _WIN32 40 | return "win32"; 41 | #elif APPLE 42 | return "darwin"; 43 | #elif __linux__ 44 | return "linux"; 45 | #elif __FreeBSD__ 46 | return "freebsd"; 47 | #else 48 | return "other"; 49 | #endif 50 | } 51 | } -------------------------------------------------------------------------------- /web-server/LazyInitWrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_LAZYWRAPPER_H 20 | #define DCPLUSPLUS_WEBSERVER_LAZYWRAPPER_H 21 | 22 | #include "forward.h" 23 | 24 | namespace webserver { 25 | template 26 | 27 | // NOTE: initialization is not thread safe 28 | class LazyInitWrapper { 29 | public: 30 | using InitF = std::function ()>; 31 | explicit LazyInitWrapper(InitF&& aInitF) : initF(std::move(aInitF)) {} 32 | 33 | T* operator->() { 34 | ensureInit(); 35 | return apiModule.operator->(); 36 | } 37 | 38 | T* get() { 39 | ensureInit(); 40 | return apiModule.get(); 41 | } 42 | private: 43 | void ensureInit() { 44 | if (!apiModule) { 45 | apiModule = initF(); 46 | } 47 | } 48 | 49 | unique_ptr apiModule; 50 | InitF initF; 51 | }; 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /api/common/Format.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include "Format.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace webserver { 29 | std::string Format::nicksToString(const HintedUser& aUser) noexcept { 30 | return Util::listToString(ClientManager::getInstance()->getNicks(aUser)); 31 | } 32 | 33 | std::string Format::hubsToString(const HintedUser& aUser) noexcept { 34 | return Util::listToString(ClientManager::getInstance()->getHubNames(aUser)); 35 | } 36 | 37 | std::string Format::formatIp(const string& aIP, const string& aCountryCode) noexcept { 38 | if (!aCountryCode.empty()) { 39 | return aCountryCode + " (" + aIP + ")"; 40 | } 41 | 42 | return aIP; 43 | } 44 | 45 | std::string Format::formatIp(const string& aIP) noexcept { 46 | return formatIp(aIP, GeoManager::getInstance()->getCountry(aIP)); 47 | } 48 | } -------------------------------------------------------------------------------- /web-server/WebUserManagerListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_WEBUSERMANAGER_LISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_WEBUSERMANAGER_LISTENER_H 22 | 23 | #include "forward.h" 24 | #include 25 | 26 | namespace webserver { 27 | class WebUserManagerListener { 28 | public: 29 | virtual ~WebUserManagerListener() { } 30 | template struct X { enum { TYPE = I }; }; 31 | 32 | typedef X<0> UserAdded; 33 | typedef X<1> UserUpdated; 34 | typedef X<2> UserRemoved; 35 | 36 | typedef X<3> SessionCreated; 37 | typedef X<4> SessionRemoved; 38 | 39 | virtual void on(UserAdded, const WebUserPtr&) noexcept { } 40 | virtual void on(UserUpdated, const WebUserPtr&) noexcept { } 41 | virtual void on(UserRemoved, const WebUserPtr&) noexcept { } 42 | 43 | virtual void on(SessionCreated, const SessionPtr&) noexcept { } 44 | virtual void on(SessionRemoved, const SessionPtr&, int /*aReason*/) noexcept { } 45 | }; 46 | 47 | } 48 | 49 | #endif // !defined(DCPLUSPLUS_DCPP_WEBUSER_LISTENER_H) -------------------------------------------------------------------------------- /api/ConnectivityApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_CONNECTIVITYAPI_H 20 | #define DCPLUSPLUS_DCPP_CONNECTIVITYAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace webserver { 28 | class ConnectivityApi : public SubscribableApiModule, private ConnectivityManagerListener { 29 | public: 30 | ConnectivityApi(Session* aSession); 31 | ~ConnectivityApi(); 32 | private: 33 | static json formatStatus(bool v6) noexcept; 34 | 35 | api_return handleDetect(ApiRequest& aRequest); 36 | api_return handleGetStatus(ApiRequest& aRequest); 37 | 38 | void on(ConnectivityManagerListener::Message, const LogMessagePtr& aMessage) noexcept override; 39 | void on(ConnectivityManagerListener::Started, bool /*v6*/) noexcept override; 40 | void on(ConnectivityManagerListener::Finished, bool /*v6*/, bool /*failed*/) noexcept override; 41 | //virtual void on(SettingChanged) noexcept { } 42 | }; 43 | } 44 | 45 | #endif -------------------------------------------------------------------------------- /api/EventApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_LOGAPI_H 20 | #define DCPLUSPLUS_DCPP_LOGAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace webserver { 28 | class EventApi : public SubscribableApiModule, private LogManagerListener { 29 | public: 30 | EventApi(Session* aSession); 31 | ~EventApi(); 32 | private: 33 | void onMessagesChanged() noexcept; 34 | 35 | api_return handleGetInfo(ApiRequest& aRequest); 36 | api_return handleRead(ApiRequest& aRequest); 37 | 38 | api_return handleGetMessages(ApiRequest& aRequest); 39 | api_return handleClearMessages(ApiRequest& aRequest); 40 | api_return handlePostMessage(ApiRequest& aRequest); 41 | 42 | // LogManagerListener 43 | void on(LogManagerListener::Message, const LogMessagePtr& aMessageData) noexcept override; 44 | void on(LogManagerListener::Cleared) noexcept override; 45 | void on(LogManagerListener::MessagesRead) noexcept override; 46 | }; 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /api/SystemApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SYSTEMAPI_H 20 | #define DCPLUSPLUS_DCPP_SYSTEMAPI_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | class SystemApi : public SubscribableApiModule, private ActivityManagerListener { 29 | public: 30 | SystemApi(Session* aSession); 31 | ~SystemApi(); 32 | 33 | static json getSystemInfo() noexcept; 34 | private: 35 | static string getAwayState(AwayMode aAwayMode) noexcept; 36 | static json serializeAwayState() noexcept; 37 | 38 | api_return handleGetAwayState(ApiRequest& aRequest); 39 | api_return handleSetAway(ApiRequest& aRequest); 40 | 41 | api_return handleGetStats(ApiRequest& aRequest); 42 | api_return handleRestartWeb(ApiRequest& aRequest); 43 | api_return handleShutdown(ApiRequest& aRequest); 44 | 45 | api_return handleGetSystemInfo(ApiRequest& aRequest); 46 | 47 | void on(ActivityManagerListener::AwayModeChanged, AwayMode aNewMode) noexcept override; 48 | }; 49 | } 50 | 51 | #endif -------------------------------------------------------------------------------- /web-server/Access.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_ACCESS_H 20 | #define DCPLUSPLUS_WEBSERVER_ACCESS_H 21 | 22 | 23 | namespace webserver { 24 | using AccessType = int8_t; 25 | 26 | // Remember to edit WebUser::accessStrings as well 27 | enum class Access: AccessType { 28 | NONE = -2, 29 | ANY = -1, 30 | ADMIN = 0, 31 | 32 | SEARCH, 33 | DOWNLOAD, 34 | TRANSFERS, 35 | 36 | EVENTS_VIEW, 37 | EVENTS_EDIT, 38 | 39 | QUEUE_VIEW, 40 | QUEUE_EDIT, 41 | 42 | FAVORITE_HUBS_VIEW, 43 | FAVORITE_HUBS_EDIT, 44 | 45 | SETTINGS_VIEW, 46 | SETTINGS_EDIT, 47 | 48 | SHARE_VIEW, 49 | SHARE_EDIT, 50 | 51 | FILESYSTEM_VIEW, 52 | FILESYSTEM_EDIT, 53 | 54 | HUBS_VIEW, 55 | HUBS_EDIT, 56 | HUBS_SEND, 57 | 58 | PRIVATE_CHAT_VIEW, 59 | PRIVATE_CHAT_EDIT, 60 | PRIVATE_CHAT_SEND, 61 | 62 | FILELISTS_VIEW, 63 | FILELISTS_EDIT, 64 | 65 | VIEW_FILES_VIEW, 66 | VIEW_FILES_EDIT, 67 | 68 | LAST, 69 | }; 70 | 71 | using AccessMap = std::map; 72 | using AccessList = std::vector; 73 | } 74 | 75 | #endif -------------------------------------------------------------------------------- /api/HistoryApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_HISTORYAPI_H 20 | #define DCPLUSPLUS_DCPP_HISTORYAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace webserver { 29 | class HistoryApi : public ApiModule { 30 | public: 31 | HistoryApi(Session* aSession); 32 | ~HistoryApi(); 33 | private: 34 | api_return handleGetStrings(ApiRequest& aRequest); 35 | api_return handleDeleteStrings(ApiRequest& aRequest); 36 | api_return handlePostString(ApiRequest& aRequest); 37 | 38 | static json serializeRecentEntry(const RecentEntryPtr& aHub) noexcept; 39 | 40 | api_return handleSearchRecents(ApiRequest& aRequest); 41 | api_return handleGetRecents(ApiRequest& aRequest); 42 | api_return handleClearRecents(ApiRequest& aRequest); 43 | 44 | static SettingsManager::HistoryType toHistoryType(ApiRequest& aRequest); 45 | static RecentEntry::Type toRecentType(ApiRequest& aRequest); 46 | }; 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /api/FilelistUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILELISTUTILS_H 20 | #define DCPLUSPLUS_DCPP_FILELISTUTILS_H 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | 28 | namespace webserver { 29 | class FilelistUtils { 30 | public: 31 | static const PropertyList properties; 32 | static const PropertyItemHandler propertyHandler; 33 | 34 | enum Properties { 35 | PROP_TOKEN = -1, 36 | PROP_NAME, 37 | PROP_TYPE, 38 | PROP_SIZE, 39 | PROP_DATE, 40 | PROP_PATH, 41 | PROP_TTH, 42 | PROP_DUPE, 43 | PROP_COMPLETE, 44 | PROP_LAST 45 | }; 46 | 47 | static json serializeItem(const FilelistItemInfoPtr& aResult, int aPropertyName) noexcept; 48 | 49 | static int compareItems(const FilelistItemInfoPtr& a, const FilelistItemInfoPtr& b, int aPropertyName) noexcept; 50 | static std::string getStringInfo(const FilelistItemInfoPtr& a, int aPropertyName) noexcept; 51 | static double getNumericInfo(const FilelistItemInfoPtr& a, int aPropertyName) noexcept; 52 | }; 53 | } 54 | 55 | #endif -------------------------------------------------------------------------------- /api/SettingApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SETTINGAPI_H 20 | #define DCPLUSPLUS_DCPP_SETTINGAPI_H 21 | 22 | #include 23 | 24 | 25 | namespace webserver { 26 | class ApiSettingItem; 27 | class SettingApi : public ApiModule { 28 | public: 29 | explicit SettingApi(Session* aSession); 30 | ~SettingApi() override; 31 | private: 32 | api_return handleGetDefinitions(ApiRequest& aRequest); 33 | api_return handleGetValues(ApiRequest& aRequest); 34 | api_return handleSetValues(ApiRequest& aRequest); 35 | api_return handleResetValues(ApiRequest& aRequest); 36 | api_return handleGetDefaultValues(ApiRequest& aRequest); 37 | api_return handleSetDefaultValues(ApiRequest& aRequest); 38 | 39 | using KeyParserF = function; 40 | void parseSettingKeys(const json& aJson, const KeyParserF& aHandler, WebServerManager* aWsm); 41 | 42 | using ValueParserF = function; 43 | void parseSettingValues(const json& aJson, const ValueParserF& aHandler, WebServerManager* aWsm); 44 | 45 | static ApiSettingItem* getSettingItem(const string& aKey, WebServerManager* aWsm) noexcept; 46 | }; 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /api/WebUserUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_WEBUSER_UTILS_H 20 | #define DCPLUSPLUS_DCPP_WEBUSER_UTILS_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | 30 | namespace webserver { 31 | class WebUserUtils { 32 | public: 33 | static const PropertyList properties; 34 | static const PropertyItemHandler propertyHandler; 35 | 36 | enum Properties { 37 | PROP_TOKEN = -1, 38 | PROP_NAME, 39 | PROP_PERMISSIONS, 40 | PROP_ACTIVE_SESSIONS, 41 | PROP_LAST_LOGIN, 42 | PROP_LAST 43 | }; 44 | 45 | static json serializeItem(const WebUserPtr& aItem, int aPropertyName) noexcept; 46 | static bool filterItem(const WebUserPtr& aItem, int aPropertyName, const StringMatch& aTextMatcher, double aNumericMatcher) noexcept; 47 | 48 | static int compareItems(const WebUserPtr& a, const WebUserPtr& b, int aPropertyName) noexcept; 49 | static std::string getStringInfo(const WebUserPtr& a, int aPropertyName) noexcept; 50 | static double getNumericInfo(const WebUserPtr& a, int aPropertyName) noexcept; 51 | }; 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /web-server/ExtensionListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_EXTENSION_LISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_EXTENSION_LISTENER_H 22 | 23 | #include "forward.h" 24 | 25 | #include "stdinc.h" 26 | 27 | namespace webserver { 28 | class ExtensionListener { 29 | public: 30 | virtual ~ExtensionListener() { } 31 | template struct X { enum { TYPE = I }; }; 32 | 33 | typedef X<0> ExtensionStarted; 34 | typedef X<1> ExtensionStopped; 35 | 36 | typedef X<2> SettingValuesUpdated; 37 | typedef X<3> SettingDefinitionsUpdated; 38 | 39 | typedef X<4> PackageUpdated; 40 | typedef X<5> StateUpdated; 41 | 42 | 43 | virtual void on(ExtensionStarted, const Extension*) noexcept { } 44 | virtual void on(ExtensionStopped, const Extension*, bool /*aFailed*/) noexcept { } 45 | 46 | virtual void on(SettingValuesUpdated, const Extension*, const SettingValueMap&) noexcept { } 47 | virtual void on(SettingDefinitionsUpdated, const Extension*) noexcept { } 48 | virtual void on(PackageUpdated, const Extension*) noexcept { } 49 | virtual void on(StateUpdated, const Extension*) noexcept { } 50 | }; 51 | 52 | } 53 | 54 | #endif // !defined(DCPLUSPLUS_WEBSERVER_EXTENSION_LISTENER_H) -------------------------------------------------------------------------------- /api/SearchUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SEARCHUTILS_H 20 | #define DCPLUSPLUS_DCPP_SEARCHUTILS_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | 28 | namespace webserver { 29 | class SearchUtils { 30 | public: 31 | static const PropertyList properties; 32 | static const PropertyItemHandler propertyHandler; 33 | 34 | enum Properties { 35 | PROP_TOKEN = -1, 36 | PROP_NAME, 37 | PROP_RELEVANCE, 38 | PROP_HITS, 39 | PROP_USERS, 40 | PROP_TYPE, 41 | PROP_SIZE, 42 | PROP_DATE, 43 | PROP_PATH, 44 | PROP_CONNECTION, 45 | PROP_SLOTS, 46 | PROP_TTH, 47 | PROP_DUPE, 48 | PROP_LAST 49 | }; 50 | 51 | static json serializeResult(const GroupedSearchResultPtr& aResult, int aPropertyName) noexcept; 52 | 53 | static int compareResults(const GroupedSearchResultPtr& a, const GroupedSearchResultPtr& b, int aPropertyName) noexcept; 54 | static std::string getStringInfo(const GroupedSearchResultPtr& a, int aPropertyName) noexcept; 55 | static double getNumericInfo(const GroupedSearchResultPtr& a, int aPropertyName) noexcept; 56 | }; 57 | } 58 | 59 | #endif -------------------------------------------------------------------------------- /web-server/JsonUtil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace webserver { 26 | 27 | const json JsonUtil::emptyJson; 28 | 29 | 30 | JsonException::JsonException(const std::string& aFieldName, ErrorType aType, const std::string& aMessage) : fieldName(aFieldName), type(aType), std::runtime_error(aMessage.c_str()) { 31 | dcassert(!aFieldName.empty()); 32 | dcassert(!aMessage.empty()); 33 | } 34 | 35 | string JsonException::errorTypeToString(ArgumentException::ErrorType aType) noexcept { 36 | switch (aType) { 37 | case ArgumentException::ERROR_MISSING: return "missing_field"; 38 | case ArgumentException::ERROR_INVALID: return "invalid"; 39 | case ArgumentException::ERROR_EXISTS: return "already_exists"; 40 | default: dcassert(0); return ""; 41 | } 42 | } 43 | 44 | json JsonException::toJSON() const noexcept { 45 | return { 46 | { "message", what() }, 47 | { "field", fieldName }, 48 | { "code", errorTypeToString(type) } 49 | }; 50 | } 51 | 52 | 53 | JsonException JsonException::toField(const string& aFieldName) const noexcept { 54 | return JsonException(aFieldName, type, what()); 55 | } 56 | } -------------------------------------------------------------------------------- /stdinc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2015 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_STDINC_H 20 | #define DCPLUSPLUS_WEBSERVER_STDINC_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "json.h" 30 | 31 | namespace webserver { 32 | using json = nlohmann::json; 33 | 34 | namespace http = boost::beast::http; 35 | namespace websocket = boost::beast::websocket; 36 | 37 | // Generic connection handle used by adapters (points to underlying session object) 38 | using ConnectionHdl = std::weak_ptr; 39 | 40 | // API aliases 41 | using api_return = http::status; 42 | 43 | using HTTPFileCompletionF = std::function>& aHeaders)>; 44 | using ApiCompletionF = std::function; 45 | using FileDeferredHandler = std::function; 46 | using ApiDeferredHandler = std::function; 47 | 48 | using namespace dcpp; 49 | } 50 | 51 | #endif // !defined(DCPLUSPLUS_WEBSERVER_STDINC_H) 52 | -------------------------------------------------------------------------------- /web-server/WebServerManagerListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_WEBSERVERMANAGER_LISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_WEBSERVERMANAGER_LISTENER_H 22 | 23 | #include "forward.h" 24 | #include "stdinc.h" 25 | 26 | namespace webserver { 27 | enum class TransportType { 28 | TYPE_SOCKET, TYPE_HTTP_API, TYPE_HTTP_FILE 29 | }; 30 | 31 | enum class Direction { 32 | INCOMING, OUTGOING 33 | }; 34 | 35 | class WebServerManagerListener { 36 | public: 37 | virtual ~WebServerManagerListener() { } 38 | template struct X { enum { TYPE = I }; }; 39 | 40 | typedef X<0> Started; 41 | typedef X<1> Stopping; 42 | typedef X<2> Stopped; 43 | 44 | typedef X<3> LoadSettings; 45 | typedef X<4> SaveSettings; 46 | 47 | typedef X<5> Data; 48 | 49 | 50 | virtual void on(Started) noexcept { } 51 | virtual void on(Stopping) noexcept { } 52 | virtual void on(Stopped) noexcept { } 53 | 54 | virtual void on(LoadSettings, const MessageCallback&) noexcept { } 55 | virtual void on(SaveSettings, const MessageCallback&) noexcept { } 56 | 57 | virtual void on(Data, const string& /*aData*/, TransportType, Direction, const string& /*aIP*/) noexcept { } 58 | }; 59 | 60 | } 61 | 62 | #endif // !defined(DCPLUSPLUS_DCPP_WEBSERVER_LISTENER_H) -------------------------------------------------------------------------------- /api/OnlineUserUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_ONLINEUSER_UTILS_H 20 | #define DCPLUSPLUS_DCPP_ONLINEUSER_UTILS_H 21 | 22 | #include "stdinc.h" 23 | 24 | #include 25 | 26 | #include 27 | 28 | 29 | namespace webserver { 30 | class OnlineUserUtils { 31 | public: 32 | static const PropertyList properties; 33 | static const PropertyItemHandler propertyHandler; 34 | 35 | enum Properties { 36 | PROP_TOKEN = -1, 37 | PROP_NICK, 38 | PROP_SHARED, 39 | PROP_DESCRIPTION, 40 | PROP_TAG, 41 | PROP_UPLOAD_SPEED, 42 | PROP_DOWNLOAD_SPEED, 43 | PROP_IP4, 44 | PROP_IP6, 45 | PROP_EMAIL, 46 | PROP_FILES, 47 | PROP_HUB_ID, 48 | PROP_HUB_URL, 49 | PROP_HUB_NAME, 50 | PROP_SUPPORTS, 51 | PROP_FLAGS, 52 | PROP_CID, 53 | PROP_UPLOAD_SLOTS, 54 | PROP_LAST 55 | }; 56 | 57 | static json serializeUser(const OnlineUserPtr& aUser, int aPropertyName) noexcept; 58 | 59 | static int compareUsers(const OnlineUserPtr& a, const OnlineUserPtr& b, int aPropertyName) noexcept; 60 | static std::string getStringInfo(const OnlineUserPtr& a, int aPropertyName) noexcept; 61 | static double getNumericInfo(const OnlineUserPtr& a, int aPropertyName) noexcept; 62 | }; 63 | } 64 | 65 | #endif -------------------------------------------------------------------------------- /web-server/HttpUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_HTTPUTIL_H 20 | #define DCPLUSPLUS_WEBSERVER_HTTPUTIL_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | class HttpUtil { 29 | public: 30 | static const char* getMimeType(const string& aFileName) noexcept; 31 | static bool unescapeUrl(const std::string& in, std::string& out) noexcept; 32 | static string getExtension(const string& aResource) noexcept; 33 | 34 | // Parses start and end position from a range HTTP request field 35 | // Initial value of end_ should be the file size 36 | // Returns true if the partial range was parsed successfully 37 | static bool parsePartialRange(const string& aHeaderData, int64_t& start_, int64_t& end_) noexcept; 38 | 39 | static string formatPartialRange(int64_t aStart, int64_t aEnd, int64_t aFileSize) noexcept; 40 | 41 | static void addCacheControlHeader(StringPairList& headers_, int aDaysValid) noexcept; 42 | 43 | static bool isStatusOk(http::status aCode) noexcept; 44 | static bool parseStatus(const string& aResponse, http::status& code_, string& text_) noexcept; 45 | static string parseAuthToken(const string& authorizationHeader, const string& xAuthorizationHeader) noexcept; 46 | }; 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /api/FavoriteDirectoryApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FAVORITEDIRECTORYAPI_H 20 | #define DCPLUSPLUS_DCPP_FAVORITEDIRECTORYAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace webserver { 28 | class FavoriteDirectoryApi : public SubscribableApiModule, private FavoriteManagerListener { 29 | public: 30 | FavoriteDirectoryApi(Session* aSession); 31 | ~FavoriteDirectoryApi(); 32 | private: 33 | static json serializeDirectories() noexcept; 34 | 35 | api_return handleGetGroupedDirectories(ApiRequest& aRequest); 36 | api_return handleGetDirectories(ApiRequest& aRequest); 37 | 38 | api_return handleAddDirectory(ApiRequest& aRequest); 39 | api_return handleGetDirectory(ApiRequest& aRequest); 40 | api_return handleUpdateDirectory(ApiRequest& aRequest); 41 | api_return handleRemoveDirectory(ApiRequest& aRequest); 42 | 43 | StringPair updatePath(const string& aPath, const json& aRequestJson); 44 | 45 | void on(FavoriteManagerListener::FavoriteDirectoriesUpdated) noexcept override; 46 | 47 | static string getPath(const ApiRequest& aRequest); 48 | static json serializeDirectory(const StringPair& aDirectory) noexcept; 49 | }; 50 | } 51 | 52 | #endif -------------------------------------------------------------------------------- /api/TransferUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_TRANSFERUTILS_H 20 | #define DCPLUSPLUS_DCPP_TRANSFERUTILS_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace webserver { 27 | class TransferUtils { 28 | public: 29 | static const PropertyList properties; 30 | static const PropertyItemHandler propertyHandler; 31 | 32 | enum Properties { 33 | PROP_TOKEN = -1, 34 | PROP_NAME, 35 | PROP_TARGET, 36 | PROP_TYPE, 37 | PROP_DOWNLOAD, 38 | PROP_SIZE, 39 | PROP_STATUS, 40 | PROP_BYTES_TRANSFERRED, 41 | PROP_USER, 42 | PROP_TIME_STARTED, 43 | PROP_SPEED, 44 | PROP_SECONDS_LEFT, 45 | PROP_IP, 46 | PROP_FLAGS, 47 | PROP_SUPPORTS, 48 | PROP_ENCRYPTION, 49 | PROP_QUEUE_ID, 50 | PROP_LAST 51 | }; 52 | 53 | static json serializeProperty(const TransferInfoPtr& aItem, int aPropertyName) noexcept; 54 | 55 | static int compareItems(const TransferInfoPtr& a, const TransferInfoPtr& b, int aPropertyName) noexcept; 56 | 57 | static std::string getStringInfo(const TransferInfoPtr& aItem, int aPropertyName) noexcept; 58 | static double getNumericInfo(const TransferInfoPtr& aItem, int aPropertyName) noexcept; 59 | static string serializeStateKey(TransferInfo::ItemState aState) noexcept; 60 | private: 61 | 62 | }; 63 | } 64 | 65 | #endif -------------------------------------------------------------------------------- /web-server/NpmRepository.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_NPMREPOSITORY_H 20 | #define DCPLUSPLUS_WEBSERVER_NPMREPOSITORY_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace dcpp { 29 | struct HttpDownload; 30 | } 31 | 32 | namespace webserver { 33 | class NpmRepository { 34 | public: 35 | static const string repository; 36 | 37 | using InstallF = std::function; 38 | 39 | NpmRepository(InstallF&& aInstallF, ModuleLogger&& aLoggerF); 40 | ~NpmRepository(); 41 | 42 | void checkUpdates(const string& aName, const string& aCurrentVersion) noexcept; 43 | void install(const string& aName) noexcept; 44 | 45 | NpmRepository(NpmRepository&) = delete; 46 | NpmRepository& operator=(NpmRepository&) = delete; 47 | private: 48 | void onPackageInfoDownloaded(const string& aName, const string& aCurrentVersion) noexcept; 49 | void checkPackageData(const string& aPackageData, const string& aName, const string& aCurrentVersion) const; 50 | 51 | using HttpDownloadMap = map>; 52 | HttpDownloadMap httpDownloads; 53 | 54 | mutable SharedMutex cs; 55 | 56 | const InstallF installF; 57 | const ModuleLogger loggerF; 58 | }; 59 | } 60 | 61 | #endif -------------------------------------------------------------------------------- /api/QueueBundleUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_QUEUE_BUNDLE_UTILS_H 20 | #define DCPLUSPLUS_DCPP_QUEUE_BUNDLE_UTILS_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | class QueueBundleUtils { 29 | public: 30 | static const PropertyList properties; 31 | static const PropertyItemHandler propertyHandler; 32 | 33 | enum Properties { 34 | PROP_TOKEN = -1, 35 | PROP_NAME, 36 | PROP_TARGET, 37 | PROP_TYPE, 38 | PROP_SIZE, 39 | PROP_STATUS, 40 | PROP_BYTES_DOWNLOADED, 41 | PROP_PRIORITY, 42 | PROP_TIME_ADDED, 43 | PROP_TIME_FINISHED, 44 | PROP_SPEED, 45 | PROP_SECONDS_LEFT, 46 | PROP_SOURCES, 47 | PROP_LAST 48 | }; 49 | 50 | static json serializeBundleProperty(const BundlePtr& aBundle, int aPropertyName) noexcept; 51 | 52 | static int compareBundles(const BundlePtr& a, const BundlePtr& b, int aPropertyName) noexcept; 53 | 54 | static std::string getStringInfo(const BundlePtr& a, int aPropertyName) noexcept; 55 | static double getNumericInfo(const BundlePtr& a, int aPropertyName) noexcept; 56 | 57 | private: 58 | static std::string formatStatusId(const BundlePtr& aBundle) noexcept; 59 | static std::string formatBundleSources(const BundlePtr& aBundle) noexcept; 60 | static std::string formatBundleType(const BundlePtr& aBundle) noexcept; 61 | }; 62 | } 63 | 64 | #endif -------------------------------------------------------------------------------- /api/WebUserApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_WEBUSER_API_H 20 | #define DCPLUSPLUS_DCPP_WEBUSER_API_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class WebUserApi : public SubscribableApiModule, private WebUserManagerListener { 30 | public: 31 | WebUserApi(Session* aSession); 32 | ~WebUserApi(); 33 | private: 34 | api_return handleGetUsers(ApiRequest& aRequest); 35 | api_return handleAddUser(ApiRequest& aRequest); 36 | api_return handleGetUser(ApiRequest& aRequest); 37 | api_return handleUpdateUser(ApiRequest& aRequest); 38 | api_return handleRemoveUser(ApiRequest& aRequest); 39 | 40 | bool updateUserProperties(WebUserPtr& aUser, const json& j, bool aIsNew); 41 | 42 | void on(WebUserManagerListener::UserAdded, const WebUserPtr& aUser) noexcept override; 43 | void on(WebUserManagerListener::UserUpdated, const WebUserPtr& aUser) noexcept override; 44 | void on(WebUserManagerListener::UserRemoved, const WebUserPtr& aUser) noexcept override; 45 | 46 | typedef ListViewController RootView; 47 | RootView view; 48 | 49 | WebUserManager& um; 50 | WebUserList getUsers() const noexcept; 51 | 52 | WebUserPtr parseUserNameParam(ApiRequest& aRequest); 53 | }; 54 | } 55 | 56 | #endif -------------------------------------------------------------------------------- /web-server/Exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_EXCEPTION_H 20 | #define DCPLUSPLUS_WEBSERVER_EXCEPTION_H 21 | 22 | #include "stdinc.h" 23 | 24 | namespace webserver { 25 | using json = nlohmann::json; 26 | 27 | class JsonException : public std::runtime_error 28 | { 29 | public: 30 | enum ErrorType { 31 | ERROR_MISSING, 32 | ERROR_INVALID, 33 | ERROR_EXISTS, 34 | ERROR_LAST 35 | }; 36 | 37 | JsonException(const std::string& aFieldName, ErrorType aType, const std::string& aMessage); 38 | 39 | virtual ~JsonException() noexcept { } 40 | json toJSON() const noexcept; 41 | JsonException toField(const std::string& aFieldName) const noexcept; 42 | 43 | const std::string& getField() const noexcept { 44 | return fieldName; 45 | } 46 | 47 | const ErrorType getType() const noexcept { 48 | return type; 49 | } 50 | protected: 51 | const std::string fieldName; 52 | const ErrorType type; 53 | 54 | static std::string errorTypeToString(ErrorType aType) noexcept; 55 | }; 56 | 57 | class RequestException : public std::runtime_error 58 | { 59 | public: 60 | RequestException(boost::beast::http::status aCode, const std::string& aMessage) : code(aCode), std::runtime_error(aMessage.c_str()) { } 61 | 62 | boost::beast::http::status getCode() const noexcept { return code; } 63 | protected: 64 | const boost::beast::http::status code; 65 | }; 66 | } 67 | 68 | #endif // !defined(EXCEPTION_H) -------------------------------------------------------------------------------- /web-server/ExtensionManagerListener.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | 20 | #ifndef DCPLUSPLUS_WEBSERVER_EXTENSIONMANAGER_LISTENER_H 21 | #define DCPLUSPLUS_WEBSERVER_EXTENSIONMANAGER_LISTENER_H 22 | 23 | #include "forward.h" 24 | 25 | namespace webserver { 26 | class ExtensionManagerListener { 27 | public: 28 | virtual ~ExtensionManagerListener() { } 29 | template struct X { enum { TYPE = I }; }; 30 | 31 | typedef X<0> ExtensionAdded; 32 | typedef X<1> ExtensionStateUpdated; 33 | typedef X<2> ExtensionRemoved; 34 | 35 | typedef X<3> InstallationStarted; 36 | typedef X<4> InstallationSucceeded; 37 | typedef X<5> InstallationFailed; 38 | 39 | typedef X<6> Started; 40 | typedef X<7> Stopped; 41 | 42 | virtual void on(ExtensionAdded, const ExtensionPtr&) noexcept { } 43 | virtual void on(ExtensionStateUpdated, const Extension*) noexcept { } 44 | virtual void on(ExtensionRemoved, const ExtensionPtr&) noexcept { } 45 | 46 | virtual void on(InstallationStarted, const string& /*installId*/) noexcept { } 47 | virtual void on(InstallationSucceeded, const string& /*installId*/, const ExtensionPtr&, bool /*updated*/) noexcept { } 48 | virtual void on(InstallationFailed, const string& /*installId*/, const string& /*error*/) noexcept { } 49 | 50 | virtual void on(Started) noexcept { } 51 | virtual void on(Stopped) noexcept { } 52 | }; 53 | 54 | } 55 | 56 | #endif // !defined(DCPLUSPLUS_WEBSERVER_EXTENSIONMANAGER_LISTENER_H) -------------------------------------------------------------------------------- /api/FilelistItemInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | 23 | 24 | namespace webserver { 25 | DirectoryListingItemToken FilelistItemInfo::getToken() const noexcept { 26 | return type == DIRECTORY ? dir->getToken() : file->getToken(); 27 | } 28 | 29 | FilelistItemInfo::FilelistItemInfo(const DirectoryListing::File::Ptr& f, const OptionalProfileToken aShareProfileToken) : file(f), shareProfileToken(aShareProfileToken), type(FILE) { 30 | //dcdebug("FilelistItemInfo (file) %s was created\n", f->getName().c_str()); 31 | } 32 | 33 | FilelistItemInfo::FilelistItemInfo(const DirectoryListing::Directory::Ptr& d, const OptionalProfileToken aShareProfileToken) : dir(d), shareProfileToken(aShareProfileToken), type(DIRECTORY) { 34 | //dcdebug("FilelistItemInfo (directory) %s was created\n", d->getName().c_str()); 35 | } 36 | 37 | FilelistItemInfo::~FilelistItemInfo() { 38 | //dcdebug("FilelistItemInfo %s was deleted\n", getName().c_str()); 39 | 40 | // The member destructor is not called automatically in an union 41 | if (type == FILE) { 42 | file.~shared_ptr(); 43 | } else { 44 | dir.~shared_ptr(); 45 | } 46 | } 47 | 48 | void FilelistItemInfo::getLocalPathsThrow(StringList& paths_) const { 49 | // TODO 50 | if (type == DIRECTORY) { 51 | dir->getLocalPathsUnsafe(paths_, shareProfileToken); 52 | } else { 53 | file->getLocalPathsUnsafe(paths_, shareProfileToken); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project( 2 | "airdcpp-webapi" 3 | DESCRIPTION "AirDC++ Web API" 4 | ) 5 | cmake_minimum_required(VERSION 3.16) 6 | 7 | # ######### General setup ########## 8 | 9 | 10 | find_package (nlohmann_json 3.0.0 REQUIRED) 11 | 12 | 13 | file (GLOB_RECURSE webapi_hdrs ${PROJECT_SOURCE_DIR}/*.h) 14 | file (GLOB_RECURSE webapi_srcs ${PROJECT_SOURCE_DIR}/*.cpp ${PROJECT_SOURCE_DIR}/*.c) 15 | 16 | add_library (${PROJECT_NAME} ${webapi_srcs} ${webapi_hdrs} ) 17 | 18 | # Project file generation 19 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${webapi_srcs}) 20 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${webapi_hdrs}) 21 | 22 | 23 | target_include_directories(${PROJECT_NAME} 24 | #PUBLIC 25 | # ${CMAKE_CURRENT_SOURCE_DIR} 26 | PUBLIC 27 | # where top-level project will look for the library's public headers 28 | $ 29 | # where external projects will look for the library's public headers 30 | $ 31 | ) 32 | 33 | if (CMAKE_BUILD_TYPE STREQUAL Debug) 34 | add_definitions(-D_DEBUG) 35 | endif() 36 | 37 | if (WIN32) 38 | target_compile_definitions(${PROJECT_NAME} 39 | PRIVATE 40 | "_UNICODE" 41 | "UNICODE" 42 | ) 43 | 44 | target_link_libraries (${PROJECT_NAME} 45 | bcrypt # for Boost::uuid 46 | ) 47 | 48 | # C1128 number of sections exceeded object file format limit: compile with /bigobj (WebServerManager.cpp) 49 | target_compile_options(${PROJECT_NAME} PRIVATE "/bigobj") 50 | endif() 51 | 52 | 53 | target_link_libraries (${PROJECT_NAME} 54 | airdcpp 55 | nlohmann_json::nlohmann_json 56 | ) 57 | set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${VERSION} OUTPUT_NAME "airdcpp-webapi") 58 | 59 | target_precompile_headers(${PROJECT_NAME} PUBLIC 60 | "$<$:${CMAKE_CURRENT_SOURCE_DIR}/stdinc.h>" 61 | "$<$:>" 62 | ) 63 | 64 | if (APPLE) 65 | set (LIBDIR1 .) 66 | set (LIBDIR ${PROJECT_NAME_GLOBAL}.app/Contents/MacOS) 67 | endif(APPLE) 68 | 69 | 70 | if (BUILD_SHARED_LIBS) 71 | install (TARGETS ${PROJECT_NAME} 72 | LIBRARY DESTINATION "${LIBDIR}" NAMELINK_SKIP 73 | BUNDLE DESTINATION ${LIBDIR1}) 74 | endif () 75 | -------------------------------------------------------------------------------- /api/ShareUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SHARE_UTILS_H 20 | #define DCPLUSPLUS_DCPP_SHARE_UTILS_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | namespace webserver { 30 | class ShareUtils { 31 | public: 32 | static const PropertyList properties; 33 | static const PropertyItemHandler propertyHandler; 34 | 35 | enum Properties { 36 | PROP_TOKEN = -1, 37 | PROP_PATH, 38 | PROP_VIRTUAL_NAME, 39 | PROP_SIZE, 40 | PROP_PROFILES, 41 | PROP_INCOMING, 42 | PROP_LAST_REFRESH_TIME, 43 | PROP_STATUS, 44 | PROP_TYPE, 45 | PROP_LAST 46 | }; 47 | 48 | static string formatDisplayStatus(const ShareDirectoryInfoPtr& aItem) noexcept; 49 | static string formatStatusId(const ShareDirectoryInfoPtr& aItem) noexcept; 50 | 51 | static json serializeItem(const ShareDirectoryInfoPtr& aItem, int aPropertyName) noexcept; 52 | static bool filterItem(const ShareDirectoryInfoPtr& aItem, int aPropertyName, const StringMatch& aTextMatcher, double aNumericMatcher) noexcept; 53 | 54 | static int compareItems(const ShareDirectoryInfoPtr& a, const ShareDirectoryInfoPtr& b, int aPropertyName) noexcept; 55 | static std::string getStringInfo(const ShareDirectoryInfoPtr& a, int aPropertyName) noexcept; 56 | static double getNumericInfo(const ShareDirectoryInfoPtr& a, int aPropertyName) noexcept; 57 | }; 58 | } 59 | 60 | #endif -------------------------------------------------------------------------------- /web-server/TarFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef _WIN32 27 | #include 28 | #endif 29 | 30 | namespace webserver { 31 | TarFile::TarFile(const string& aPath) { 32 | auto res = mtar_open(&tar, Text::fromUtf8(aPath).c_str(), "r"); 33 | if (res != MTAR_ESUCCESS) { 34 | throw Exception(mtar_strerror(res)); 35 | } 36 | } 37 | 38 | void TarFile::extract(const string& aDestPath) { 39 | mtar_header_t h; 40 | while ((mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD) { 41 | if (h.type != MTAR_TDIR && strcmp(h.name, "pax_global_header") != 0) { 42 | boost::scoped_array buf(new char[h.size + 1]); 43 | auto res = mtar_read_data(&tar, &buf[0], h.size); 44 | if (res != MTAR_ESUCCESS) { 45 | throw Exception(mtar_strerror(res)); 46 | } 47 | 48 | string destFile = aDestPath + h.name; 49 | 50 | #ifdef _WIN32 51 | // Wrong path separators would hit assertions... 52 | boost::replace_all(destFile, "/", PATH_SEPARATOR_STR); 53 | #endif 54 | 55 | File::ensureDirectory(destFile); 56 | { 57 | File f(destFile, File::WRITE, File::OPEN | File::CREATE | File::TRUNCATE, File::BUFFER_SEQUENTIAL); 58 | f.write(&buf[0], h.size); 59 | } 60 | } 61 | 62 | mtar_next(&tar); 63 | } 64 | } 65 | 66 | TarFile::~TarFile() { 67 | mtar_close(&tar); 68 | } 69 | } -------------------------------------------------------------------------------- /api/platform/windows/Filesystem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_WINDOWS_FILESYSTEM_H 20 | #define DCPLUSPLUS_DCPP_WINDOWS_FILESYSTEM_H 21 | 22 | #include 23 | 24 | namespace webserver { 25 | class Filesystem { 26 | public: 27 | static json getDriveListing(bool aListCdrom) noexcept { 28 | json retJson; 29 | 30 | //Enumerate the drive letters 31 | auto dwDrives = GetLogicalDrives(); 32 | DWORD dwMask = 1; 33 | for (int i = 0; i<32; i++) { 34 | if (dwDrives & dwMask) { 35 | 36 | tstring sDrive; 37 | sDrive = (wchar_t)('A' + i); 38 | sDrive += _T(":"); 39 | 40 | auto driveType = GetDriveType(sDrive.c_str()); 41 | if (aListCdrom || driveType != DRIVE_CDROM) { 42 | retJson.push_back(serializeDrive(sDrive, driveType)); 43 | } 44 | } 45 | 46 | dwMask <<= 1; 47 | } 48 | 49 | return retJson; 50 | } 51 | 52 | private: 53 | static json serializeDrive(const tstring& aDrive, UINT aDriveType) noexcept { 54 | return { 55 | { "name", Text::fromT(aDrive) }, 56 | { "type", { 57 | { "id", driveTypeToString(aDriveType) } 58 | } } 59 | }; 60 | } 61 | 62 | static string driveTypeToString(UINT aDriveType) noexcept { 63 | switch (aDriveType) { 64 | case DRIVE_RAMDISK: 65 | case DRIVE_CDROM: 66 | case DRIVE_REMOVABLE: return "removable"; 67 | case DRIVE_FIXED: return "drive_fixed"; 68 | case DRIVE_REMOTE: return "drive_remote"; 69 | } 70 | 71 | return Util::emptyString; 72 | } 73 | }; 74 | } 75 | 76 | #endif -------------------------------------------------------------------------------- /microtar/microtar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See `microtar.c` for details. 6 | */ 7 | 8 | #ifndef MICROTAR_H 9 | #define MICROTAR_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include 16 | #include 17 | 18 | #define MTAR_VERSION "0.1.0" 19 | 20 | enum { 21 | MTAR_ESUCCESS = 0, 22 | MTAR_EFAILURE = -1, 23 | MTAR_EOPENFAIL = -2, 24 | MTAR_EREADFAIL = -3, 25 | MTAR_EWRITEFAIL = -4, 26 | MTAR_ESEEKFAIL = -5, 27 | MTAR_EBADCHKSUM = -6, 28 | MTAR_ENULLRECORD = -7, 29 | MTAR_ENOTFOUND = -8 30 | }; 31 | 32 | enum { 33 | MTAR_TREG = '0', 34 | MTAR_TLNK = '1', 35 | MTAR_TSYM = '2', 36 | MTAR_TCHR = '3', 37 | MTAR_TBLK = '4', 38 | MTAR_TDIR = '5', 39 | MTAR_TFIFO = '6' 40 | }; 41 | 42 | typedef struct { 43 | unsigned mode; 44 | unsigned owner; 45 | unsigned size; 46 | unsigned mtime; 47 | unsigned type; 48 | char name[100]; 49 | char linkname[100]; 50 | } mtar_header_t; 51 | 52 | 53 | typedef struct mtar_t mtar_t; 54 | 55 | struct mtar_t { 56 | int (*read)(mtar_t *tar, void *data, unsigned size); 57 | int (*write)(mtar_t *tar, const void *data, unsigned size); 58 | int (*seek)(mtar_t *tar, unsigned pos); 59 | int (*close)(mtar_t *tar); 60 | void *stream; 61 | unsigned pos; 62 | unsigned remaining_data; 63 | unsigned last_header; 64 | }; 65 | 66 | 67 | const char* mtar_strerror(int err); 68 | 69 | int mtar_open(mtar_t *tar, const char *filename, const char *mode); 70 | int mtar_close(mtar_t *tar); 71 | 72 | int mtar_seek(mtar_t *tar, unsigned pos); 73 | int mtar_rewind(mtar_t *tar); 74 | int mtar_next(mtar_t *tar); 75 | int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h); 76 | int mtar_read_header(mtar_t *tar, mtar_header_t *h); 77 | int mtar_read_data(mtar_t *tar, void *ptr, unsigned size); 78 | 79 | int mtar_write_header(mtar_t *tar, const mtar_header_t *h); 80 | int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size); 81 | int mtar_write_dir_header(mtar_t *tar, const char *name); 82 | int mtar_write_data(mtar_t *tar, const void *data, unsigned size); 83 | int mtar_finalize(mtar_t *tar); 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /api/QueueFileUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_QUEUE_FILE_UTILS_H 20 | #define DCPLUSPLUS_DCPP_QUEUE_FILE_UTILS_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | class QueueFileUtils { 29 | public: 30 | static const PropertyList properties; 31 | 32 | enum Properties { 33 | PROP_TOKEN = -1, 34 | PROP_NAME, 35 | PROP_TARGET, 36 | PROP_TYPE, 37 | PROP_SIZE, 38 | PROP_STATUS, 39 | PROP_BYTES_DOWNLOADED, 40 | PROP_PRIORITY, 41 | PROP_TIME_ADDED, 42 | PROP_TIME_FINISHED, 43 | PROP_SPEED, 44 | PROP_SECONDS_LEFT, 45 | PROP_SOURCES, 46 | PROP_BUNDLE, 47 | PROP_TTH, 48 | PROP_LAST 49 | }; 50 | 51 | static const PropertyItemHandler propertyHandler; 52 | 53 | static json serializeFileProperty(const QueueItemPtr& aItem, int aPropertyName) noexcept; 54 | 55 | static int compareFiles(const QueueItemPtr& a, const QueueItemPtr& b, int aPropertyName) noexcept; 56 | 57 | static std::string getStringInfo(const QueueItemPtr& a, int aPropertyName) noexcept; 58 | static double getNumericInfo(const QueueItemPtr& a, int aPropertyName) noexcept; 59 | 60 | private: 61 | static string formatStatusId(const QueueItemPtr& aItem) noexcept; 62 | static string getDisplayName(const QueueItemPtr& aItem) noexcept; 63 | 64 | static std::string formatDisplayStatus(const QueueItemPtr& aItem) noexcept; 65 | static std::string formatFileSources(const QueueItemPtr& aItem) noexcept; 66 | }; 67 | } 68 | 69 | #endif -------------------------------------------------------------------------------- /forward.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2015 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_FORWARD_H 20 | #define DCPLUSPLUS_WEBSERVER_FORWARD_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class ApiRequest; 30 | 31 | class ContextMenuItem; 32 | using ContextMenuItemPtr = std::shared_ptr; 33 | using ContextMenuItemList = std::vector; 34 | struct ContextMenuItemClickData; 35 | 36 | class GroupedContextMenuItem; 37 | using GroupedContextMenuItemPtr = std::shared_ptr; 38 | using GroupedContextMenuItemList = std::vector; 39 | 40 | class Extension; 41 | using ExtensionPtr = std::shared_ptr; 42 | using ExtensionList = std::vector; 43 | 44 | class Session; 45 | using SessionPtr = std::shared_ptr; 46 | using SessionList = std::vector; 47 | using SessionCallback = std::function; 48 | using LocalSessionId = uint32_t; 49 | 50 | class Timer; 51 | using TimerPtr = std::shared_ptr; 52 | 53 | class WebSocket; 54 | using WebSocketPtr = std::shared_ptr; 55 | 56 | class WebServerManager; 57 | 58 | using Callback = std::function; 59 | using MessageCallback = std::function; 60 | 61 | class WebUser; 62 | using WebUserPtr = std::shared_ptr; 63 | using WebUserList = std::vector; 64 | } 65 | 66 | #endif // !defined(DCPLUSPLUS_WEBSERVER_FORWARD_H) 67 | -------------------------------------------------------------------------------- /api/PrivateChatApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_PRIVATEMESSAGEAPI_H 20 | #define DCPLUSPLUS_DCPP_PRIVATEMESSAGEAPI_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | namespace webserver { 30 | class PrivateChatApi : public ParentApiModule, private PrivateChatManagerListener { 31 | public: 32 | static StringList subscriptionList; 33 | 34 | PrivateChatApi(Session* aSession); 35 | ~PrivateChatApi(); 36 | private: 37 | ActionHookResult incomingMessageHook(const ChatMessagePtr& aMessage, const ActionHookResultGetter& aResultGetter); 38 | ActionHookResult<> outgoingMessageHook(const OutgoingChatMessage& aMessage, const HintedUser& aUser, bool aEcho, const ActionHookResultGetter<>& aResultGetter); 39 | 40 | void addChat(const PrivateChatPtr& aChat) noexcept; 41 | 42 | api_return handlePostChat(ApiRequest& aRequest); 43 | api_return handleDeleteSubmodule(ApiRequest& aRequest) override; 44 | 45 | api_return handlePostMessage(ApiRequest& aRequest); 46 | 47 | void on(PrivateChatManagerListener::ChatCreated, const PrivateChatPtr& aChat, bool aReceivedMessage) noexcept override; 48 | void on(PrivateChatManagerListener::ChatRemoved, const PrivateChatPtr& aChat) noexcept override; 49 | 50 | static json serializeChat(const PrivateChatPtr& aChat) noexcept; 51 | }; 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /api/ExtensionApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_EXTENSION_API_H 20 | #define DCPLUSPLUS_DCPP_EXTENSION_API_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | namespace webserver { 30 | class ExtensionManager; 31 | class ExtensionApi : public ParentApiModule, private ExtensionManagerListener { 32 | public: 33 | ExtensionApi(Session* aSession); 34 | ~ExtensionApi(); 35 | 36 | static StringList subscriptionList; 37 | private: 38 | void addExtension(const ExtensionPtr& aExtension) noexcept; 39 | 40 | api_return handleDownloadExtension(ApiRequest& aRequest); 41 | api_return handlePostExtension(ApiRequest& aRequest); 42 | api_return handleDeleteSubmodule(ApiRequest& aRequest) override; 43 | 44 | api_return handleGetEngineStatuses(ApiRequest& aRequest); 45 | 46 | void on(ExtensionManagerListener::ExtensionAdded, const ExtensionPtr& aExtension) noexcept override; 47 | void on(ExtensionManagerListener::ExtensionRemoved, const ExtensionPtr& aExtension) noexcept override; 48 | 49 | void on(ExtensionManagerListener::InstallationStarted, const string& aInstallId) noexcept override; 50 | void on(ExtensionManagerListener::InstallationSucceeded, const string& aInstallId, const ExtensionPtr&, bool aUpdated) noexcept override; 51 | void on(ExtensionManagerListener::InstallationFailed, const string& aInstallId, const string& aError) noexcept override; 52 | 53 | ExtensionManager& em; 54 | }; 55 | } 56 | 57 | #endif -------------------------------------------------------------------------------- /api/FavoriteHubApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FAVORITEHUBAPI_H 20 | #define DCPLUSPLUS_DCPP_FAVORITEHUBAPI_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | namespace webserver { 31 | class FavoriteHubApi : public SubscribableApiModule, private FavoriteManagerListener { 32 | public: 33 | FavoriteHubApi(Session* aSession); 34 | ~FavoriteHubApi(); 35 | private: 36 | api_return handleAddHub(ApiRequest& aRequest); 37 | api_return handleRemoveHub(ApiRequest& aRequest); 38 | api_return handleUpdateHub(ApiRequest& aRequest); 39 | 40 | api_return handleGetHubs(ApiRequest& aRequest); 41 | api_return handleGetHub(ApiRequest& aRequest); 42 | 43 | void updateProperties(FavoriteHubEntryPtr& aEntry, const json& j, bool aNewHub); 44 | 45 | void on(FavoriteManagerListener::FavoriteHubAdded, const FavoriteHubEntryPtr& /*e*/) noexcept override; 46 | void on(FavoriteManagerListener::FavoriteHubRemoved, const FavoriteHubEntryPtr& e) noexcept override; 47 | void on(FavoriteManagerListener::FavoriteHubUpdated, const FavoriteHubEntryPtr& e) noexcept override; 48 | 49 | typedef ListViewController HubView; 50 | HubView view; 51 | 52 | static FavoriteHubEntryList getEntryList() noexcept; 53 | 54 | static tribool deserializeTribool(const string& aFieldName, const json& aJson); 55 | FavoriteHubEntryPtr parseFavoriteHubParam(ApiRequest& aRequest); 56 | }; 57 | } 58 | 59 | #endif -------------------------------------------------------------------------------- /api/ViewFileApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILEVIEW_API_H 20 | #define DCPLUSPLUS_DCPP_FILEVIEW_API_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class ViewFileApi : public SubscribableApiModule, private ViewFileManagerListener { 30 | public: 31 | 32 | ViewFileApi(Session* aSession); 33 | ~ViewFileApi(); 34 | private: 35 | api_return handleGetFiles(ApiRequest& aRequest); 36 | 37 | api_return handleAddFile(ApiRequest& aRequest); 38 | api_return handleAddLocalFile(ApiRequest& aRequest); 39 | api_return handleGetFile(ApiRequest& aRequest); 40 | api_return handleRemoveFile(ApiRequest& aRequest); 41 | 42 | api_return handleSetRead(ApiRequest& aRequest); 43 | 44 | static json serializeDownloadState(const ViewFilePtr& aFile) noexcept; 45 | static json serializeFile(const ViewFilePtr& aFile) noexcept; 46 | void onViewFileUpdated(const ViewFilePtr& aFile) noexcept; 47 | 48 | void on(ViewFileManagerListener::FileAdded, const ViewFilePtr& aFile) noexcept override; 49 | void on(ViewFileManagerListener::FileClosed, const ViewFilePtr& aFile) noexcept override; 50 | void on(ViewFileManagerListener::FileStateUpdated, const ViewFilePtr& aFile) noexcept override; 51 | void on(ViewFileManagerListener::FileFinished, const ViewFilePtr& aFile) noexcept override; 52 | void on(ViewFileManagerListener::FileRead, const ViewFilePtr& aFile) noexcept override; 53 | 54 | ViewFilePtr parseViewFileParam(ApiRequest& aRequest); 55 | }; 56 | } 57 | 58 | #endif -------------------------------------------------------------------------------- /api/FavoriteHubUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FAVORITEHUBUTILS_H 20 | #define DCPLUSPLUS_DCPP_FAVORITEHUBUTILS_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | 28 | namespace webserver { 29 | class FavoriteHubUtils { 30 | public: 31 | static const PropertyList properties; 32 | static const PropertyItemHandler propertyHandler; 33 | 34 | enum Properties { 35 | PROP_TOKEN = -1, 36 | PROP_NAME, 37 | PROP_HUB_URL, 38 | PROP_HUB_DESCRIPTION, 39 | PROP_AUTO_CONNECT, 40 | PROP_SHARE_PROFILE, 41 | PROP_CONNECT_STATE, 42 | 43 | PROP_NICK, 44 | PROP_HAS_PASSWORD, 45 | PROP_USER_DESCRIPTION, 46 | PROP_NMDC_ENCODING, 47 | PROP_AWAY_MESSAGE, 48 | 49 | PROP_CONN_MODE4, 50 | PROP_CONN_MODE6, 51 | PROP_IP4, 52 | PROP_IP6, 53 | 54 | PROP_SHOW_JOINS, 55 | PROP_FAV_SHOW_JOINS, 56 | PROP_CHAT_NOTIFY, 57 | PROP_LOG_HUB_CHAT, 58 | PROP_LAST 59 | }; 60 | 61 | static json serializeHub(const FavoriteHubEntryPtr& aEntry, int aPropertyName) noexcept; 62 | 63 | static int compareEntries(const FavoriteHubEntryPtr& a, const FavoriteHubEntryPtr& b, int aPropertyName) noexcept; 64 | static std::string getStringInfo(const FavoriteHubEntryPtr& a, int aPropertyName) noexcept; 65 | static double getNumericInfo(const FavoriteHubEntryPtr& a, int aPropertyName) noexcept; 66 | private: 67 | static string getConnectStateStr(const FavoriteHubEntryPtr& aEntry) noexcept; 68 | static string getConnectStateId(const FavoriteHubEntryPtr& aEntry) noexcept; 69 | }; 70 | } 71 | 72 | #endif -------------------------------------------------------------------------------- /api/ShareProfileApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SHAREPROFILE_API_H 20 | #define DCPLUSPLUS_DCPP_SHAREPROFILE_API_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace dcpp { 28 | class ShareProfileManager; 29 | } 30 | 31 | namespace webserver { 32 | class ShareProfileApi : public SubscribableApiModule, private ShareProfileManagerListener { 33 | public: 34 | ShareProfileApi(Session* aSession); 35 | ~ShareProfileApi(); 36 | private: 37 | static json serializeShareProfile(const ShareProfilePtr& aProfile) noexcept; 38 | 39 | api_return handleGetProfiles(ApiRequest& aRequest); 40 | api_return handleGetProfile(ApiRequest& aRequest); 41 | 42 | api_return handleAddProfile(ApiRequest& aRequest); 43 | api_return handleUpdateProfile(ApiRequest& aRequest); 44 | api_return handleRemoveProfile(ApiRequest& aRequest); 45 | 46 | api_return handleGetDefaultProfile(ApiRequest& aRequest); 47 | api_return handleSetDefaultProfile(ApiRequest& aRequest); 48 | 49 | void updateProfileProperties(ShareProfilePtr& aProfile, const json& j); 50 | 51 | void on(ShareProfileManagerListener::ProfileAdded, ProfileToken aProfile) noexcept override; 52 | void on(ShareProfileManagerListener::ProfileUpdated, ProfileToken aProfile, bool aIsMajorChange) noexcept override; 53 | void on(ShareProfileManagerListener::ProfileRemoved, ProfileToken aProfile) noexcept override; 54 | 55 | ShareProfilePtr parseProfileToken(ApiRequest& aRequest, bool aAllowHidden); 56 | 57 | ShareProfileManager& mgr; 58 | }; 59 | } 60 | 61 | #endif -------------------------------------------------------------------------------- /api/HubApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_HUBAPI_H 20 | #define DCPLUSPLUS_DCPP_HUBAPI_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace webserver { 31 | class HubApi : public ParentApiModule, private ClientManagerListener { 32 | public: 33 | static StringList subscriptionList; 34 | 35 | explicit HubApi(Session* aSession); 36 | ~HubApi() override; 37 | 38 | static json serializeClient(const ClientPtr& aClient) noexcept; 39 | private: 40 | ActionHookResult incomingMessageHook(const ChatMessagePtr& aMessage, const ActionHookResultGetter& aResultGetter); 41 | ActionHookResult<> outgoingMessageHook(const OutgoingChatMessage& aMessage, const Client& aClient, const ActionHookResultGetter<>& aResultGetter); 42 | 43 | void addHub(const ClientPtr& aClient) noexcept; 44 | 45 | api_return handlePostMessage(ApiRequest& aRequest); 46 | api_return handlePostStatus(ApiRequest& aRequest); 47 | 48 | api_return handleConnect(ApiRequest& aRequest); 49 | api_return handleDeleteSubmodule(ApiRequest& aRequest) override; 50 | api_return handleGetStats(ApiRequest& aRequest); 51 | 52 | api_return handleFindByUrl(ApiRequest& aRequest); 53 | 54 | void on(ClientManagerListener::ClientCreated, const ClientPtr&) noexcept override; 55 | void on(ClientManagerListener::ClientRemoved, const ClientPtr&) noexcept override; 56 | }; 57 | } 58 | 59 | #endif -------------------------------------------------------------------------------- /api/UserApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_USER_API_H 20 | #define DCPLUSPLUS_DCPP_USER_API_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | namespace webserver { 32 | class UserApi : public SubscribableApiModule, private IgnoreManagerListener, private ClientManagerListener { 33 | public: 34 | UserApi(Session* aSession); 35 | ~UserApi(); 36 | private: 37 | UserPtr getUser(ApiRequest& aRequest); 38 | 39 | api_return handleIgnore(ApiRequest& aRequest); 40 | api_return handleUnignore(ApiRequest& aRequest); 41 | api_return handleGetIgnores(ApiRequest& aRequest); 42 | 43 | api_return handleGetUser(ApiRequest& aRequest); 44 | api_return handleSearchNicks(ApiRequest& aRequest); 45 | api_return handleSearchHintedUser(ApiRequest& aRequest); 46 | 47 | api_return handleGrantSlot(ApiRequest& aRequest); 48 | 49 | void on(IgnoreManagerListener::IgnoreAdded, const UserPtr& aUser) noexcept override; 50 | void on(IgnoreManagerListener::IgnoreRemoved, const UserPtr& aUser) noexcept override; 51 | 52 | void on(ClientManagerListener::UserConnected, const OnlineUser& aUser, bool) noexcept override; 53 | void on(ClientManagerListener::UserUpdated, const OnlineUser& aUser) noexcept override; 54 | void on(ClientManagerListener::UserDisconnected, const UserPtr& aUser, bool) noexcept override; 55 | 56 | static json serializeConnectResult(const optional aResult) noexcept; 57 | }; 58 | } 59 | 60 | #endif -------------------------------------------------------------------------------- /api/SessionApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SESSIONAPI_H 20 | #define DCPLUSPLUS_DCPP_SESSIONAPI_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class SessionApi : public SubscribableApiModule, private WebUserManagerListener { 30 | public: 31 | explicit SessionApi(Session* aSession); 32 | ~SessionApi() override; 33 | 34 | // Session isn't associated yet when these get called... 35 | static api_return handleLogin(RouterRequest& aRequest); 36 | static api_return handleSocketConnect(RouterRequest& aRequest); 37 | private: 38 | api_return failAuthenticatedRequest(ApiRequest& aRequest); 39 | 40 | api_return handleRemoveCurrentSession(ApiRequest& aRequest); 41 | api_return handleActivity(ApiRequest& aRequest); 42 | 43 | api_return handleGetSessions(ApiRequest& aRequest); 44 | api_return handleGetCurrentSession(ApiRequest& aRequest) const; 45 | 46 | api_return handleGetSession(ApiRequest& aRequest); 47 | api_return handleRemoveSession(ApiRequest& aRequest); 48 | 49 | api_return logout(ApiRequest& aRequest, const SessionPtr& aSession); 50 | 51 | static json serializeLoginInfo(const SessionPtr& aSession, const string& aRefreshToken); 52 | static json serializeSession(const SessionPtr& aSession) noexcept; 53 | static string getSessionType(const SessionPtr& aSession) noexcept; 54 | 55 | void on(WebUserManagerListener::SessionCreated, const SessionPtr& aSession) noexcept override; 56 | void on(WebUserManagerListener::SessionRemoved, const SessionPtr& aSession, int aReason) noexcept override; 57 | 58 | SessionPtr parseSessionParam(ApiRequest& aRequest); 59 | }; 60 | } 61 | 62 | #endif -------------------------------------------------------------------------------- /api/HashApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_HASHAPI_H 20 | #define DCPLUSPLUS_DCPP_HASHAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace webserver { 28 | class HashApi : public SubscribableApiModule, private HashManagerListener { 29 | public: 30 | HashApi(Session* aSession); 31 | ~HashApi(); 32 | private: 33 | json previousStats; 34 | void onTimer() noexcept; 35 | 36 | json serializeHashStatistics(const HashManager::HashStats& aStats) noexcept; 37 | 38 | static json formatDbStatus(bool aMaintenanceRunning) noexcept; 39 | void updateDbStatus(bool aMaintenanceRunning) noexcept; 40 | 41 | api_return handlePause(ApiRequest& aRequest); 42 | api_return handleResume(ApiRequest& aRequest); 43 | api_return handleStop(ApiRequest& aRequest); 44 | 45 | api_return handleOptimize(ApiRequest& aRequest); 46 | api_return handleGetDbStatus(ApiRequest& aRequest); 47 | api_return handleGetStats(ApiRequest& aRequest); 48 | 49 | api_return handleRenamePath(ApiRequest& aRequest); 50 | 51 | void on(HashManagerListener::FileHashed, const string& aPath, HashedFile& aFileInfo, int aHasherId) noexcept override; 52 | void on(HashManagerListener::FileFailed, const string& aFilePath, const string& aErrorId, const string& aMessage, int aHasherId) noexcept override; 53 | 54 | void on(HashManagerListener::DirectoryHashed, const string& aPath, const HasherStats& aStats, int aHasherId) noexcept override; 55 | void on(HashManagerListener::HasherFinished, int aDirsHashed, const HasherStats& aStats, int aHasherId) noexcept override; 56 | 57 | void on(HashManagerListener::MaintananceStarted) noexcept override; 58 | void on(HashManagerListener::MaintananceFinished) noexcept override; 59 | 60 | TimerPtr timer; 61 | }; 62 | } 63 | 64 | #endif -------------------------------------------------------------------------------- /web-server/WebSocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_WEBSOCKET_H 20 | #define DCPLUSPLUS_WEBSERVER_WEBSOCKET_H 21 | 22 | #include "stdinc.h" 23 | 24 | #include "forward.h" 25 | #include "IServerEndpoint.h" 26 | 27 | #include 28 | 29 | namespace webserver { 30 | // WebSockets are owned by SocketManager and API modules 31 | class WebServerManager; 32 | 33 | class WebSocket { 34 | public: 35 | WebSocket(bool aIsSecure, ConnectionHdl aHdl, IServerEndpoint& aEndpoint, WebServerManager* aWsm); 36 | ~WebSocket(); 37 | 38 | void close(uint16_t aCode, const std::string& aMsg); 39 | 40 | IGETSET(SessionPtr, session, Session, nullptr); 41 | 42 | // Send raw data 43 | // Throws json::exception on JSON conversion errors 44 | void sendPlain(const json& aJson); 45 | void sendApiResponse(const json& aJsonResponse, const json& aErrorJson, http::status aCode, int aCallbackId) noexcept; 46 | 47 | void onData(const string& aPayload, const SessionCallback& aAuthCallback); 48 | 49 | WebSocket(WebSocket&) = delete; 50 | WebSocket& operator=(WebSocket&) = delete; 51 | 52 | const string& getIp() const noexcept { 53 | return ip; 54 | } 55 | 56 | void ping() noexcept; 57 | 58 | void logError(const string& aMessage) const noexcept; 59 | void debugMessage(const string& aMessage) const noexcept; 60 | 61 | time_t getTimeCreated() const noexcept { 62 | return timeCreated; 63 | } 64 | 65 | const string& getConnectUrl() const noexcept { 66 | return url; 67 | } 68 | 69 | // Throws json exception (from the json library) in case of invalid JSON, ArgumentException in case of invalid properties 70 | static void parseRequest(const string& aRequest, int& callbackId_, string& method_, string& path_, json& data_); 71 | private: 72 | const ConnectionHdl hdl; 73 | IServerEndpoint& endpoint; 74 | WebServerManager* wsm; 75 | const bool secure; 76 | const time_t timeCreated; 77 | string url; 78 | string ip; 79 | }; 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /api/TransferApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_TRANSFERAPI_H 20 | #define DCPLUSPLUS_DCPP_TRANSFERAPI_H 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | 29 | #include 30 | 31 | 32 | namespace webserver { 33 | class TransferApi : public SubscribableApiModule, private TransferInfoManagerListener { 34 | public: 35 | TransferApi(Session* aSession); 36 | ~TransferApi(); 37 | private: 38 | json serializeTransferStats() const noexcept; 39 | 40 | api_return handleGetTransfers(ApiRequest& aRequest); 41 | api_return handleGetTransfer(ApiRequest& aRequest); 42 | 43 | api_return handleGetTransferredBytes(ApiRequest& aRequest); 44 | api_return handleGetTransferStats(ApiRequest& aRequest); 45 | api_return handleForce(ApiRequest& aRequest); 46 | api_return handleDisconnect(ApiRequest& aRequest); 47 | 48 | void onTimer(); 49 | 50 | void on(TransferInfoManagerListener::Added, const TransferInfoPtr& aInfo) noexcept override; 51 | void on(TransferInfoManagerListener::Updated, const TransferInfoPtr& aInfo, int aUpdatedProperties, bool aTick) noexcept override; 52 | void on(TransferInfoManagerListener::Removed, const TransferInfoPtr& aInfo) noexcept override; 53 | void on(TransferInfoManagerListener::Failed, const TransferInfoPtr& aInfo) noexcept override; 54 | void on(TransferInfoManagerListener::Starting, const TransferInfoPtr& aInfo) noexcept override; 55 | void on(TransferInfoManagerListener::Completed, const TransferInfoPtr& aInfo) noexcept override; 56 | 57 | json previousStats; 58 | 59 | TimerPtr timer; 60 | 61 | typedef ListViewController TransferListView; 62 | TransferListView view; 63 | 64 | TransferInfoPtr getTransfer(ApiRequest& aRequest) const; 65 | TransferInfo::List getTransfers() const noexcept; 66 | static PropertyIdSet updateFlagsToPropertyIds(int aUpdatedProperties) noexcept; 67 | }; 68 | } 69 | 70 | #endif -------------------------------------------------------------------------------- /web-server/HttpManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_HTTP_MANAGER_H 20 | #define DCPLUSPLUS_WEBSERVER_HTTP_MANAGER_H 21 | 22 | #include "stdinc.h" 23 | 24 | #include "FileServer.h" 25 | 26 | #include "HttpRequest.h" 27 | #include "HttpUtil.h" 28 | #include "WebServerManager.h" 29 | #include "WebUserManager.h" 30 | #include "IServerEndpoint.h" 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | 37 | namespace webserver { 38 | class HttpManager { 39 | public: 40 | explicit HttpManager(WebServerManager* aWsm) noexcept : wsm(aWsm) {} 41 | 42 | const FileServer& getFileServer() const noexcept { 43 | return fileServer; 44 | } 45 | 46 | HttpManager(HttpManager&) = delete; 47 | HttpManager& operator=(HttpManager&) = delete; 48 | 49 | void setEndpointHandlers(IServerEndpoint& aEndpoint, bool aIsSecure) { 50 | aEndpoint.setHttpHandler(std::bind_front(&HttpManager::handleHttpRequest, this, std::ref(aEndpoint), aIsSecure)); 51 | } 52 | 53 | void start(const string& aWebResourcePath) noexcept; 54 | void stop() noexcept; 55 | 56 | static constexpr int64_t MAX_HTTP_BODY_SIZE = 16LL * 1024 * 1024; // 16 MiB default 57 | private: 58 | static api_return handleApiRequest(const HttpRequest& aRequest, 59 | json& output_, json& error_, const ApiDeferredHandler& aDeferredHandler) noexcept; 60 | 61 | // Returns false in case of invalid token format 62 | bool getOptionalHttpSession(IServerEndpoint& ep, ConnectionHdl hdl, const string& aIp, SessionPtr& session_); 63 | 64 | bool setHttpResponse(IServerEndpoint& ep, ConnectionHdl hdl, http::status aStatus, const string& aOutput); 65 | 66 | void handleHttpApiRequest(const HttpRequest& aRequest, IServerEndpoint& ep, ConnectionHdl hdl); 67 | void handleHttpFileRequest(const HttpRequest& aRequest, IServerEndpoint& ep, ConnectionHdl hdl); 68 | 69 | void handleHttpRequest(IServerEndpoint& ep, bool aIsSecure, ConnectionHdl hdl); 70 | 71 | WebServerManager* wsm; 72 | FileServer fileServer; 73 | }; 74 | } 75 | 76 | #endif // DCPLUSPLUS_DCPP_WEBSERVER_H 77 | -------------------------------------------------------------------------------- /web-server/FileServer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_FILESERVER_H 20 | #define DCPLUSPLUS_WEBSERVER_FILESERVER_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | #include 26 | 27 | 28 | namespace webserver { 29 | struct HttpRequest; 30 | class FileServer { 31 | public: 32 | FileServer(); 33 | ~FileServer(); 34 | 35 | void setResourcePath(const string& aPath) noexcept; 36 | 37 | // Get location of the file server root directory (Web UI files) 38 | const string& getResourcePath() const noexcept; 39 | 40 | http::status handleRequest(const HttpRequest& aRequest, 41 | std::string& output_, StringPairList& headers_, const FileDeferredHandler& aDeferF); 42 | 43 | string getTempFilePath(const string& fileId) const noexcept; 44 | void stop() noexcept; 45 | 46 | FileServer(FileServer&) = delete; 47 | FileServer& operator=(FileServer&) = delete; 48 | private: 49 | http::status handleGetRequest(const HttpRequest& aRequest, 50 | std::string& output_, StringPairList& headers_, const SessionPtr& aSession, const FileDeferredHandler& aDeferF); 51 | 52 | http::status handleProxyDownload(const string& aUrl, string& output_, const FileDeferredHandler& aDeferF) noexcept; 53 | void onProxyDownloadCompleted(int64_t aDownloadId, const HTTPFileCompletionF& aCompletionF) noexcept; 54 | 55 | http::status handlePostRequest(const HttpRequest& aRequest, 56 | std::string& output_, StringPairList& headers_, const SessionPtr& aSession) noexcept; 57 | 58 | string resourcePath; 59 | 60 | string parseResourcePath(const string& aResource, const HttpRequest& aRequest, StringPairList& headers_) const; 61 | string parseViewFilePath(const string& aResource, StringPairList& headers_, const SessionPtr& aSession) const; 62 | string getPath(const TTHValue& aTTH) const; 63 | 64 | static string getExtension(const string& aResource) noexcept; 65 | 66 | mutable SharedMutex cs; 67 | StringMap tempFiles; 68 | 69 | int64_t proxyDownloadCounter = 0; 70 | map> proxyDownloads; 71 | }; 72 | } 73 | 74 | #endif -------------------------------------------------------------------------------- /api/FilelistItemInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILELIST_ITEMINFO_H 20 | #define DCPLUSPLUS_DCPP_FILELIST_ITEMINFO_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | class FilelistItemInfo : public FastAlloc { 29 | public: 30 | using Ptr = shared_ptr; 31 | using List = vector; 32 | 33 | enum ItemType { 34 | FILE, 35 | DIRECTORY 36 | }; 37 | 38 | union { 39 | const DirectoryListing::File::Ptr file; 40 | const DirectoryListing::Directory::Ptr dir; 41 | }; 42 | 43 | FilelistItemInfo(const DirectoryListing::File::Ptr& f, const OptionalProfileToken aShareProfileToken); 44 | FilelistItemInfo(const DirectoryListing::Directory::Ptr& d, const OptionalProfileToken aShareProfileToken); 45 | ~FilelistItemInfo(); 46 | 47 | DupeType getDupe() const noexcept { 48 | if (shareProfileToken) { 49 | // Own filelist 50 | return DUPE_SHARE_FULL; 51 | } 52 | 53 | return type == DIRECTORY ? dir->getDupe() : file->getDupe(); 54 | } 55 | const string& getName() const noexcept { return type == DIRECTORY ? dir->getName() : file->getName(); } 56 | string getAdcPath() const noexcept { return type == DIRECTORY ? dir->getAdcPathUnsafe() : file->getAdcPathUnsafe(); } // TODO 57 | bool isComplete() const noexcept { return type == DIRECTORY ? dir->isComplete() : true; } 58 | void getLocalPathsThrow(StringList& paths_) const; 59 | 60 | time_t getDate() const noexcept { return type == DIRECTORY ? dir->getRemoteDate() : file->getRemoteDate(); } 61 | int64_t getSize() const noexcept { return type == DIRECTORY ? dir->getTotalSize(false) : file->getSize(); } 62 | 63 | DirectoryListingItemToken getToken() const noexcept; 64 | 65 | ItemType getType() const noexcept { 66 | return type; 67 | } 68 | 69 | bool isDirectory() const noexcept { 70 | return type == DIRECTORY; 71 | } 72 | private: 73 | const OptionalProfileToken shareProfileToken; 74 | const ItemType type; 75 | }; 76 | 77 | using FilelistItemInfoPtr = FilelistItemInfo::Ptr; 78 | } 79 | 80 | #endif -------------------------------------------------------------------------------- /api/SearchApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SEARCHAPI_H 20 | #define DCPLUSPLUS_DCPP_SEARCHAPI_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | namespace webserver { 31 | class SearchApi: public ParentApiModule, public SearchManagerListener { 32 | public: 33 | static StringList subscriptionList; 34 | 35 | explicit SearchApi(Session* aSession); 36 | ~SearchApi() override; 37 | private: 38 | static json serializeSearchInstance(const SearchInstancePtr& aSearch) noexcept; 39 | 40 | api_return handleCreateInstance(ApiRequest& aRequest) const; 41 | api_return handleDeleteSubmodule(ApiRequest& aRequest) override; 42 | 43 | api_return handleGetTypes(ApiRequest& aRequest) const; 44 | api_return handlePostType(ApiRequest& aRequest) const; 45 | api_return handleGetType(ApiRequest& aRequest) const; 46 | api_return handleUpdateType(ApiRequest& aRequest) const; 47 | api_return handleRemoveType(ApiRequest& aRequest) const; 48 | 49 | void on(SearchManagerListener::SearchTypesChanged) noexcept override; 50 | void on(SearchManagerListener::SearchInstanceCreated, const SearchInstancePtr& aInstance) noexcept override; 51 | void on(SearchManagerListener::SearchInstanceRemoved, const SearchInstancePtr& aInstance) noexcept override; 52 | void on(SearchManagerListener::IncomingSearch, Client* aClient, const OnlineUserPtr& aAdcUser, const SearchQuery& aQuery, const SearchResultList& aResults, bool) noexcept override; 53 | 54 | static string serializeSearchQueryItemType(const SearchQuery& aQuery) noexcept; 55 | static json serializeSearchQuery(const SearchQuery& aQuery) noexcept; 56 | static json serializeSearchType(const SearchTypePtr& aType) noexcept; 57 | static string parseSearchTypeId(ApiRequest& aRequest) noexcept; 58 | string createCurrentSessionOwnerId(const string& aSuffix) const noexcept; 59 | 60 | ActionHookResult<> incomingUserResultHook(const SearchResultPtr& aResult, const ActionHookResultGetter<>& aResultGetter) noexcept; 61 | }; 62 | } 63 | 64 | #endif -------------------------------------------------------------------------------- /web-server/WebUser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_WEBUSER_H 20 | #define DCPLUSPLUS_WEBSERVER_WEBUSER_H 21 | 22 | #include "forward.h" 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | namespace webserver { 29 | class WebUser { 30 | public: 31 | WebUser(const std::string& aUserName, const std::string& aPasswordHashOrPlain, bool aIsAdmin = false); 32 | 33 | const string& getToken() const noexcept { 34 | return userName; 35 | } 36 | 37 | GETSET(std::string, userName, UserName); 38 | IGETSET(time_t, lastLogin, LastLogin, 0); 39 | 40 | WebUser(WebUser&) = delete; 41 | WebUser& operator=(WebUser&) = delete; 42 | 43 | // Sessions 44 | int getActiveSessions() const noexcept { 45 | return activeSessions; 46 | } 47 | 48 | void addSession() noexcept { 49 | activeSessions++; 50 | } 51 | 52 | void removeSession() noexcept { 53 | activeSessions--; 54 | } 55 | 56 | // Access 57 | bool hasPermission(Access aAccess) const noexcept; 58 | 59 | void setPermissions(const string& aStr) noexcept; 60 | void setPermissions(const StringList& aPermissions) noexcept; 61 | 62 | string getPermissionsStr() const noexcept; 63 | static StringList permissionsToStringList(const AccessList& aPermissions) noexcept; 64 | AccessList getPermissions() const noexcept; 65 | bool isAdmin() const noexcept; 66 | 67 | const static StringList accessStrings; 68 | static Access stringToAccess(const string& aStr) noexcept; 69 | static const string& accessToString(Access aAccess) noexcept; 70 | 71 | int countPermissions() const noexcept; 72 | 73 | static bool validateUsername(const string& aUsername) noexcept; 74 | 75 | bool matchPassword(const string& aPasswordPlain) const noexcept; 76 | void setPassword(const std::string& aPasswordHashOrPlain) noexcept; 77 | const string& getPasswordHash() const noexcept { 78 | return passwordHash; 79 | } 80 | private: 81 | void clearPermissions() noexcept; 82 | int activeSessions = 0; 83 | 84 | AccessMap permissions; 85 | 86 | static string hashPassword(const string& aPasswordPlain) noexcept; 87 | 88 | string passwordHash; 89 | }; 90 | 91 | } 92 | 93 | #endif -------------------------------------------------------------------------------- /api/common/SettingUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SETTING_UTILS_H 20 | #define DCPLUSPLUS_DCPP_SETTING_UTILS_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | namespace webserver { 27 | class SettingUtils { 28 | public: 29 | static json validateValue(const json& aValue, const ApiSettingItem& aItem, SettingReferenceList* references_); 30 | 31 | static ExtensionSettingItem deserializeDefinition(const json& aJson, bool aIsListValue = false); 32 | static ExtensionSettingItem::List deserializeDefinitions(const json& aJson); 33 | 34 | static json serializeDefinition(const ApiSettingItem& aItem) noexcept; 35 | private: 36 | static void validateEnumValue(const json& aValue, const string& aKey, ApiSettingItem::Type aType, ApiSettingItem::Type aItemType, const ApiSettingItem::EnumOption::List& aEnumOptions); 37 | static json validateObjectListValue(const ApiSettingItem::PtrList& aPropertyDefinitions, const json& aValue, SettingReferenceList* references_); 38 | 39 | static json convertValue(const json& aValue, const string& aKey, ApiSettingItem::Type aType, ApiSettingItem::Type aItemType, bool aOptional, const ApiSettingItem::MinMax& aMinMax, const ApiSettingItem::PtrList& aObjectValues, SettingReferenceList* references_); 40 | static json convertListCompatibleValue(const json& aValue, const string& aKey, ApiSettingItem::Type aType, bool aOptional, const ApiSettingItem::MinMax& aMinMax, SettingReferenceList* references_); 41 | 42 | 43 | static json parseEnumOptionId(const json& aJson, ApiSettingItem::Type aType); 44 | static json parseStringSetting(const string& aFieldName, const json& aJson, bool aOptional, ApiSettingItem::Type aType); 45 | static json parseIntSetting(const string& aFieldName, const json& aJson, bool aOptional, const ApiSettingItem::MinMax& aMinMax); 46 | 47 | static bool isListCompatibleValue(ApiSettingItem::Type aType) noexcept { 48 | return aType == ApiSettingItem::TYPE_NUMBER || ApiSettingItem::isString(aType) || aType == ApiSettingItem::TYPE_HINTER_USER; 49 | } 50 | 51 | static string typeToStr(ApiSettingItem::Type aType) noexcept; 52 | static ApiSettingItem::Type deserializeType(const string& aFieldName, const json& aJson, bool aOptional); 53 | }; 54 | } 55 | 56 | #endif -------------------------------------------------------------------------------- /api/ShareRootApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SHAREROOT_API_H 20 | #define DCPLUSPLUS_DCPP_SHAREROOT_API_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace webserver { 32 | class ShareRootApi : public SubscribableApiModule, private ShareManagerListener, private HashManagerListener { 33 | public: 34 | ShareRootApi(Session* aSession); 35 | ~ShareRootApi(); 36 | private: 37 | api_return handleGetRoots(ApiRequest& aRequest); 38 | 39 | api_return handleAddRoot(ApiRequest& aRequest); 40 | api_return handleGetRoot(ApiRequest& aRequest); 41 | api_return handleUpdateRoot(ApiRequest& aRequest); 42 | api_return handleRemoveRoot(ApiRequest& aRequest); 43 | 44 | void parseRoot(ShareDirectoryInfoPtr& aInfo, const json& j); 45 | 46 | void on(ShareManagerListener::RootCreated, const string& aPath) noexcept override; 47 | void on(ShareManagerListener::RootRemoved, const string& aPath) noexcept override; 48 | void on(ShareManagerListener::RootUpdated, const string& aPath) noexcept override; 49 | void on(ShareManagerListener::RootRefreshState, const string& aPath) noexcept override; 50 | 51 | void on(HashManagerListener::FileHashed, const string& aFilePath, HashedFile& aFileInfo, int) noexcept override; 52 | 53 | typedef ListViewController RootView; 54 | RootView rootView; 55 | 56 | void onRootUpdated(const string& aPath, PropertyIdSet&& aUpdatedProperties) noexcept; 57 | void onRootUpdated(const ShareDirectoryInfoPtr& aInfo, PropertyIdSet&& aUpdatedProperties) noexcept; 58 | 59 | ShareDirectoryInfoList getRoots() const noexcept; 60 | ShareDirectoryInfoPtr findRoot(const string& aPath) noexcept; 61 | ShareDirectoryInfoPtr getRoot(const ApiRequest& aRequest); 62 | 63 | // ListViewController compares items by memory address so we need to store the list here 64 | ShareDirectoryInfoList roots; 65 | mutable SharedMutex cs; 66 | 67 | TimerPtr timer; 68 | void onTimer() noexcept; 69 | StringSet hashedPaths; 70 | }; 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /api/ExtensionInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_EXTENSIONINFO_H 20 | #define DCPLUSPLUS_DCPP_EXTENSIONINFO_H 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class ExtensionManager; 30 | class ExtensionInfo : public SubApiModule, private ExtensionListener { 31 | public: 32 | typedef shared_ptr Ptr; 33 | 34 | ExtensionInfo(ParentType* aParentModule, const ExtensionPtr& aExtension); 35 | ~ExtensionInfo(); 36 | 37 | static const StringList subscriptionList; 38 | 39 | const ExtensionPtr& getExtension() const noexcept { 40 | return extension; 41 | } 42 | 43 | ExtensionPtr getExtension() noexcept { 44 | return extension; 45 | } 46 | 47 | string getId() const noexcept override; 48 | 49 | void init() noexcept override; 50 | 51 | static json serializeLogs(const ExtensionPtr& aExtension) noexcept; 52 | static json serializeExtension(const ExtensionPtr& aExtension) noexcept; 53 | private: 54 | void on(ExtensionListener::SettingValuesUpdated, const Extension*, const SettingValueMap& aUpdatedSettings) noexcept override; 55 | void on(ExtensionListener::SettingDefinitionsUpdated, const Extension*) noexcept override; 56 | 57 | void on(ExtensionListener::ExtensionStarted, const Extension*) noexcept override; 58 | void on(ExtensionListener::ExtensionStopped, const Extension*, bool aFailed) noexcept override; 59 | void on(ExtensionListener::PackageUpdated, const Extension*) noexcept override; 60 | void on(ExtensionListener::StateUpdated, const Extension*) noexcept override; 61 | 62 | api_return handleStartExtension(ApiRequest& aRequest); 63 | api_return handleStopExtension(ApiRequest& aRequest); 64 | api_return handleReady(ApiRequest& aRequest); 65 | api_return handleUpdateProperties(ApiRequest& aRequest); 66 | 67 | api_return handleGetSettingDefinitions(ApiRequest& aRequest); 68 | api_return handlePostSettingDefinitions(ApiRequest& aRequest); 69 | 70 | api_return handleGetSettings(ApiRequest& aRequest); 71 | api_return handlePostSettings(ApiRequest& aRequest); 72 | 73 | ExtensionPtr extension; 74 | 75 | void onUpdated(const JsonCallback& aDataCallback) noexcept; 76 | }; 77 | } 78 | 79 | #endif -------------------------------------------------------------------------------- /web-server/IServerEndpoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Abstraction for HTTP/WebSocket server endpoint to decouple from concrete libraries 3 | */ 4 | #ifndef DCPLUSPLUS_WEBSERVER_ISERVERENDPOINT_H 5 | #define DCPLUSPLUS_WEBSERVER_ISERVERENDPOINT_H 6 | 7 | #include "stdinc.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace webserver { 14 | using contextPtr = std::shared_ptr; 15 | 16 | class IServerEndpoint { 17 | public: 18 | virtual ~IServerEndpoint() = default; 19 | 20 | // Initialization 21 | virtual void initAsio(boost::asio::io_context* ios) = 0; 22 | 23 | // Timeouts & limits 24 | virtual void setOpenHandshakeTimeout(int millis) = 0; 25 | virtual void setPongTimeout(int millis) = 0; 26 | virtual void setMaxHttpBodySize(std::size_t bytes) = 0; 27 | 28 | // TLS init (no handle is required by the current user code) 29 | virtual void setTlsInitHandler(std::function handler) = 0; 30 | 31 | // Logging 32 | virtual void configureLogging(std::ostream* access, std::ostream* error, bool enable) = 0; 33 | 34 | // Listening / lifecycle 35 | virtual void setReuseAddr(bool enable) = 0; 36 | virtual void listen(const std::string& bindAddress, const std::string& port) = 0; 37 | virtual void listen(const boost::asio::ip::tcp& protocol, uint16_t port) = 0; 38 | virtual void startAccept() = 0; 39 | virtual bool isListening() const noexcept = 0; 40 | virtual void stopListening() = 0; 41 | 42 | // Event handlers 43 | virtual void setMessageHandler(std::function onMessage) = 0; 44 | virtual void setHttpHandler(std::function onHttp) = 0; 45 | virtual void setCloseHandler(std::function onClose) = 0; 46 | virtual void setOpenHandler(std::function onOpen) = 0; 47 | virtual void setPongTimeoutHandler(std::function onPongTimeout) = 0; 48 | 49 | // Connection helpers used by higher layers 50 | virtual std::string getRemoteIp(ConnectionHdl hdl) = 0; 51 | // Generic HTTP request accessors (adapter-agnostic) 52 | virtual std::string getHeader(ConnectionHdl hdl, const std::string& name) = 0; 53 | virtual std::string getBody(ConnectionHdl hdl) = 0; 54 | virtual std::string getMethod(ConnectionHdl hdl) = 0; 55 | virtual std::string getUri(ConnectionHdl hdl) = 0; 56 | virtual std::string getResource(ConnectionHdl hdl) = 0; 57 | 58 | // HTTP response helpers 59 | virtual void httpAppendHeader(ConnectionHdl hdl, const std::string& name, const std::string& value) = 0; 60 | virtual void httpSetBody(ConnectionHdl hdl, const std::string& body) = 0; 61 | virtual void httpSetStatus(ConnectionHdl hdl, http::status status) = 0; 62 | virtual void httpDeferResponse(ConnectionHdl hdl) = 0; 63 | virtual void httpSendResponse(ConnectionHdl hdl) = 0; 64 | 65 | // WebSocket helpers 66 | virtual void wsSendText(ConnectionHdl hdl, const std::string& text) = 0; 67 | virtual void wsPing(ConnectionHdl hdl) = 0; 68 | virtual void wsClose(ConnectionHdl hdl, uint16_t code, const std::string& reason) = 0; 69 | }; 70 | } 71 | 72 | #endif // DCPLUSPLUS_WEBSERVER_ISERVERENDPOINT_H 73 | -------------------------------------------------------------------------------- /api/common/ViewTasks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_VIEWTASKS_H 20 | #define DCPLUSPLUS_DCPP_VIEWTASKS_H 21 | 22 | #include 23 | 24 | 25 | namespace webserver { 26 | 27 | // Must be in merging order (lower ones replace other) 28 | enum Tasks { 29 | UPDATE_ITEM = 0, 30 | ADD_ITEM, 31 | REMOVE_ITEM 32 | }; 33 | 34 | 35 | template 36 | class ItemTasks { 37 | public: 38 | struct MergeTask { 39 | int8_t type; 40 | PropertyIdSet updatedProperties; 41 | 42 | MergeTask(int8_t aType, const PropertyIdSet& aUpdatedProperties = PropertyIdSet()) : type(aType), updatedProperties(aUpdatedProperties) { 43 | 44 | } 45 | 46 | void merge(const MergeTask& aTask) { 47 | // Ignore 48 | if (type > aTask.type) { 49 | return; 50 | } 51 | 52 | // Merge 53 | if (type == aTask.type) { 54 | updatedProperties.insert(aTask.updatedProperties.begin(), aTask.updatedProperties.end()); 55 | return; 56 | } 57 | 58 | // Replace the task 59 | type = aTask.type; 60 | updatedProperties = aTask.updatedProperties; 61 | } 62 | }; 63 | 64 | using TaskMap = map; 65 | 66 | void addItem(const T& aItem) { 67 | WLock l(cs); 68 | queueTask(aItem, MergeTask(ADD_ITEM)); 69 | } 70 | 71 | void removeItem(const T& aItem) { 72 | WLock l(cs); 73 | queueTask(aItem, MergeTask(REMOVE_ITEM)); 74 | } 75 | 76 | void updateItem(const T& aItem, const PropertyIdSet& aUpdatedProperties) { 77 | WLock l(cs); 78 | updatedProperties.insert(aUpdatedProperties.begin(), aUpdatedProperties.end()); 79 | queueTask(aItem, MergeTask(UPDATE_ITEM, aUpdatedProperties)); 80 | } 81 | 82 | void clear() { 83 | WLock l(cs); 84 | updatedProperties.clear(); 85 | tasks.clear(); 86 | } 87 | 88 | void get(typename ItemTasks::TaskMap& tasks_, PropertyIdSet& updatedProperties_) { 89 | WLock l(cs); 90 | tasks_.swap(tasks); 91 | updatedProperties_.swap(updatedProperties); 92 | } 93 | private: 94 | void queueTask(const T& aItem, MergeTask&& aData) { 95 | auto j = tasks.find(aItem); 96 | if (j != tasks.end()) { 97 | (*j).second.merge(aData); 98 | return; 99 | } 100 | 101 | tasks.emplace(aItem, std::move(aData)); 102 | } 103 | 104 | PropertyIdSet updatedProperties; 105 | SharedMutex cs; 106 | TaskMap tasks; 107 | }; 108 | 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /api/base/SubscribableApiModule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_SUBSCRIBABLE_APIMODULE_H 20 | #define DCPLUSPLUS_WEBSERVER_SUBSCRIBABLE_APIMODULE_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class WebSocket; 30 | #define LISTENER_PARAM_ID "listener_param" 31 | class SubscribableApiModule : public ApiModule, protected SessionListener { 32 | public: 33 | SubscribableApiModule(Session* aSession, Access aSubscriptionAccess); 34 | ~SubscribableApiModule() override; 35 | 36 | using SubscriptionMap = std::map; 37 | 38 | virtual void createSubscriptions(const StringList& aSubscriptions) noexcept; 39 | 40 | virtual bool send(const json& aJson); 41 | virtual bool send(const string& aSubscription, const json& aJson); 42 | 43 | using JsonCallback = std::function; 44 | virtual bool maybeSend(const string& aSubscription, const JsonCallback& aCallback); 45 | 46 | virtual void setSubscriptionState(const string& aSubscription, bool aActive) noexcept { 47 | subscriptions[aSubscription] = aActive; 48 | } 49 | 50 | virtual bool subscriptionActive(const string& aSubscription) const noexcept { 51 | auto s = subscriptions.find(aSubscription); 52 | dcassert(s != subscriptions.end()); 53 | return s->second; 54 | } 55 | 56 | virtual bool subscriptionExists(const string& aSubscription) const noexcept { 57 | auto i = subscriptions.find(aSubscription); 58 | return i != subscriptions.end(); 59 | } 60 | 61 | Access getSubscriptionAccess() const noexcept { 62 | return subscriptionAccess; 63 | } 64 | 65 | const WebSocketPtr& getSocket() const noexcept { 66 | return socket; 67 | } 68 | protected: 69 | void createSubscription(const string& aSubscription) noexcept; 70 | 71 | void on(SessionListener::SocketConnected, const WebSocketPtr&) noexcept override; 72 | void on(SessionListener::SocketDisconnected) noexcept override; 73 | 74 | const Access subscriptionAccess; 75 | 76 | virtual api_return handleSubscribe(ApiRequest& aRequest); 77 | virtual api_return handleUnsubscribe(ApiRequest& aRequest); 78 | 79 | virtual const string& parseSubscription(ApiRequest& aRequest); 80 | private: 81 | WebSocketPtr socket = nullptr; 82 | SubscriptionMap subscriptions; 83 | }; 84 | 85 | using HandlerPtr = std::unique_ptr; 86 | } 87 | 88 | #endif -------------------------------------------------------------------------------- /api/common/MessageUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_MESSAGEUTILS_H 20 | #define DCPLUSPLUS_DCPP_MESSAGEUTILS_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | namespace dcpp { 33 | class MessageCache; 34 | } 35 | 36 | namespace webserver { 37 | class MessageUtils { 38 | public: 39 | static json serializeMessageHighlight(const MessageHighlightPtr& aHighlight); 40 | 41 | using MessageHighlightDeserializer = std::function&)>; 42 | static MessageHighlightDeserializer getMessageHookHighlightDeserializer(const string& aMessage); 43 | 44 | static json serializeMessage(const Message& aMessage) noexcept; 45 | static json serializeChatMessage(const ChatMessagePtr& aMessage) noexcept; 46 | static json serializeLogMessage(const LogMessagePtr& aMessageData) noexcept; 47 | 48 | using UnreadSerializerF = std::function; 49 | static json serializeCacheInfo(const MessageCache& aCache, const UnreadSerializerF& unreadF) noexcept; 50 | static json serializeUnreadChat(const MessageCache& aCache) noexcept; 51 | static json serializeUnreadLog(const MessageCache& aCache) noexcept; 52 | 53 | static bool hasMention(const ChatMessagePtr& aMessage) noexcept; 54 | static bool isBot(const ChatMessagePtr& aMessage) noexcept; 55 | static bool isUser(const ChatMessagePtr& aMessage) noexcept; 56 | 57 | static string getMessageSeverity(LogMessage::Severity aSeverity) noexcept; 58 | static string getMessageType(LogMessage::Type aType) noexcept; 59 | 60 | static string getHighlightType(MessageHighlight::HighlightType aType) noexcept; 61 | static json getContentType(const MessageHighlightPtr& aHighlight) noexcept; 62 | 63 | static string parseStatusMessageLabel(const SessionPtr& aSession) noexcept; 64 | private: 65 | static MessageHighlightList deserializeHookMessageHighlights(const json& aData, const ActionHookResultGetter& aResultGetter, const string& aMessageText); 66 | static MessageHighlightPtr deserializeMessageHighlight(const json& aJson, const string& aMessageText, const string& aDefaultDescriptionId); 67 | static MessageHighlight::HighlightType parseHighlightType(const string& aTypeStr); 68 | }; 69 | } 70 | 71 | #endif -------------------------------------------------------------------------------- /api/WebUserUtils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace webserver { 28 | const PropertyList WebUserUtils::properties = { 29 | { PROP_NAME, "username", TYPE_TEXT, SERIALIZE_TEXT, SORT_TEXT }, 30 | { PROP_PERMISSIONS, "permissions", TYPE_LIST_NUMERIC, SERIALIZE_CUSTOM, SORT_CUSTOM }, 31 | { PROP_ACTIVE_SESSIONS, "active_sessions", TYPE_NUMERIC_OTHER, SERIALIZE_NUMERIC, SORT_NUMERIC }, 32 | { PROP_LAST_LOGIN, "last_login", TYPE_TIME, SERIALIZE_NUMERIC, SORT_NUMERIC }, 33 | }; 34 | 35 | const PropertyItemHandler WebUserUtils::propertyHandler = { 36 | properties, 37 | WebUserUtils::getStringInfo, WebUserUtils::getNumericInfo, WebUserUtils::compareItems, WebUserUtils::serializeItem, WebUserUtils::filterItem 38 | }; 39 | 40 | json WebUserUtils::serializeItem(const WebUserPtr& aItem, int aPropertyName) noexcept { 41 | json j; 42 | 43 | switch (aPropertyName) { 44 | case PROP_PERMISSIONS: 45 | { 46 | return Serializer::serializePermissions(aItem->getPermissions()); 47 | } 48 | } 49 | 50 | 51 | return j; 52 | } 53 | 54 | bool WebUserUtils::filterItem(const WebUserPtr& aItem, int aPropertyName, const StringMatch& aStringMatch, double /*aNumericMatcher*/) noexcept { 55 | switch (aPropertyName) { 56 | case PROP_PERMISSIONS: 57 | { 58 | auto i = WebUser::stringToAccess(aStringMatch.pattern); 59 | if (i != Access::LAST) { 60 | return aItem->hasPermission(i); 61 | } 62 | } 63 | } 64 | 65 | return false; 66 | } 67 | 68 | int WebUserUtils::compareItems(const WebUserPtr& a, const WebUserPtr& b, int aPropertyName) noexcept { 69 | switch (aPropertyName) { 70 | case PROP_PERMISSIONS: { 71 | if (a->isAdmin() != b->isAdmin()) { 72 | return a->isAdmin() ? 1 : -1; 73 | } 74 | 75 | return compare(a->countPermissions(), b->countPermissions()); 76 | } 77 | default: 78 | dcassert(0); 79 | } 80 | 81 | return 0; 82 | } 83 | 84 | std::string WebUserUtils::getStringInfo(const WebUserPtr& aItem, int aPropertyName) noexcept { 85 | switch (aPropertyName) { 86 | case PROP_NAME: return aItem->getUserName(); 87 | default: dcassert(0); return 0; 88 | } 89 | } 90 | double WebUserUtils::getNumericInfo(const WebUserPtr& aItem, int aPropertyName) noexcept { 91 | switch (aPropertyName) { 92 | case PROP_LAST_LOGIN: return (double)aItem->getLastLogin(); 93 | case PROP_ACTIVE_SESSIONS: return (double)aItem->getActiveSessions(); 94 | default: dcassert(0); return 0; 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /api/FilelistApi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILELISTAPI_H 20 | #define DCPLUSPLUS_DCPP_FILELISTAPI_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace webserver { 31 | class FilelistApi : public ParentApiModule, private DirectoryListingManagerListener { 32 | public: 33 | static StringList subscriptionList; 34 | 35 | explicit FilelistApi(Session* aSession); 36 | ~FilelistApi() override; 37 | private: 38 | void addList(const DirectoryListingPtr& aList) noexcept; 39 | 40 | api_return handlePostList(ApiRequest& aRequest); 41 | api_return handleDeleteSubmodule(ApiRequest& aRequest) override; 42 | api_return handleOwnList(ApiRequest& aRequest); 43 | 44 | api_return handlePostDirectoryDownload(ApiRequest& aRequest); 45 | api_return handleDeleteDirectoryDownload(ApiRequest& aRequest); 46 | api_return handleGetDirectoryDownloads(ApiRequest& aRequest); 47 | api_return handleGetDirectoryDownload(ApiRequest& aRequest); 48 | 49 | api_return handleMatchQueue(ApiRequest& aRequest); 50 | 51 | void on(DirectoryListingManagerListener::ListingCreated, const DirectoryListingPtr& aList) noexcept override; 52 | void on(DirectoryListingManagerListener::ListingClosed, const DirectoryListingPtr&) noexcept override; 53 | 54 | void on(DirectoryListingManagerListener::DirectoryDownloadAdded, const DirectoryDownloadPtr&) noexcept override; 55 | void on(DirectoryListingManagerListener::DirectoryDownloadRemoved, const DirectoryDownloadPtr&) noexcept override; 56 | void on(DirectoryListingManagerListener::DirectoryDownloadProcessed, const DirectoryDownloadPtr& aDirectoryInfo, const DirectoryBundleAddResult& aQueueInfo, const string& aError) noexcept override; 57 | void on(DirectoryListingManagerListener::DirectoryDownloadFailed, const DirectoryDownloadPtr& aDirectoryInfo, const string& aError) noexcept override; 58 | 59 | static json serializeList(const DirectoryListingPtr& aList) noexcept; 60 | static json serializeShareProfile(const DirectoryListingPtr& aList) noexcept; 61 | 62 | ActionHookResult<> directoryLoadHook(const DirectoryListing::Directory::Ptr& aDirectory, const DirectoryListing& aList, const ActionHookResultGetter<>& aResultGetter) noexcept; 63 | ActionHookResult<> fileLoadHook(const DirectoryListing::File::Ptr& aFile, const DirectoryListing& aList, const ActionHookResultGetter<>& aResultGetter) noexcept; 64 | }; 65 | } 66 | 67 | #endif -------------------------------------------------------------------------------- /web-server/SocketManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_SOCKET_MANAGER_H 20 | #define DCPLUSPLUS_WEBSERVER_SOCKET_MANAGER_H 21 | 22 | #include "forward.h" 23 | #include "stdinc.h" 24 | 25 | #include "SocketManagerListener.h" 26 | #include "WebSocket.h" 27 | #include "WebUserManagerListener.h" 28 | #include "IServerEndpoint.h" 29 | 30 | #include 31 | 32 | 33 | namespace webserver { 34 | class WebServerManager; 35 | class SocketManager : public Speaker, private WebUserManagerListener { 36 | public: 37 | explicit SocketManager(WebServerManager* aWsm) noexcept : wsm(aWsm) {} 38 | 39 | void start(); 40 | void stop() noexcept; 41 | 42 | // Disconnect all sockets 43 | void disconnectSockets(const std::string& aMessage) noexcept; 44 | 45 | // Reset sessions for associated sockets 46 | WebSocketPtr getSocket(LocalSessionId aSessionToken) noexcept; 47 | 48 | SocketManager(SocketManager&) = delete; 49 | SocketManager& operator=(SocketManager&) = delete; 50 | 51 | void setEndpointHandlers(IServerEndpoint& aEndpoint, bool aIsSecure) { 52 | aEndpoint.setMessageHandler(std::bind_front(&SocketManager::handleSocketMessage, this)); 53 | aEndpoint.setCloseHandler(std::bind_front(&SocketManager::handleSocketDisconnected, this)); 54 | aEndpoint.setOpenHandler(std::bind_front(&SocketManager::handleSocketConnected, this, std::ref(aEndpoint), aIsSecure)); 55 | aEndpoint.setPongTimeoutHandler(std::bind_front(&SocketManager::handlePongTimeout, this)); 56 | } 57 | private: 58 | void onAuthenticated(const SessionPtr& aSession, const WebSocketPtr& aSocket) noexcept; 59 | 60 | void handleSocketConnected(IServerEndpoint& ep, bool aIsSecure, ConnectionHdl hdl); 61 | void handleSocketDisconnected(ConnectionHdl hdl); 62 | 63 | void handlePongReceived(ConnectionHdl hdl, const string& aPayload); 64 | void handlePongTimeout(ConnectionHdl hdl, const string& aPayload); 65 | 66 | void handleSocketMessage(ConnectionHdl hdl, const std::string& payload); 67 | 68 | void addSocket(ConnectionHdl hdl, const WebSocketPtr& aSocket) noexcept; 69 | WebSocketPtr getSocket(ConnectionHdl hdl) const noexcept; 70 | 71 | void pingTimer() noexcept; 72 | 73 | mutable SharedMutex cs; 74 | 75 | using WebSocketList = vector; 76 | std::map> sockets; 77 | 78 | TimerPtr socketPingTimer; 79 | WebServerManager* wsm; 80 | 81 | void resetSocketSession(const WebSocketPtr& aSocket) noexcept; 82 | 83 | void on(WebUserManagerListener::SessionRemoved, const SessionPtr& aSession, int aReason) noexcept override; 84 | }; 85 | } 86 | 87 | #endif // DCPLUSPLUS_DCPP_WEBSERVER_H 88 | -------------------------------------------------------------------------------- /web-server/ApiRouter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | 32 | namespace webserver { 33 | api_return ApiRouter::handleRequest(RouterRequest& aRequest) noexcept { 34 | auto& apiRequest = aRequest.apiRequest; 35 | if (apiRequest.getApiVersion() != API_VERSION) { 36 | apiRequest.setResponseErrorStr("Unsupported API version"); 37 | return http::status::precondition_failed; 38 | } 39 | 40 | http::status code; 41 | try { 42 | // Special case because we may not have the session yet 43 | if (apiRequest.getApiModule() == "sessions" && !apiRequest.getSession()) { 44 | return routeAuthRequest(aRequest); 45 | } 46 | 47 | // Require auth for all other modules 48 | if (!apiRequest.getSession()) { 49 | apiRequest.setResponseErrorStr("Not authorized"); 50 | return http::status::unauthorized; 51 | } 52 | 53 | // Require using the same protocol that was used for logging in 54 | if (apiRequest.getSession()->getSessionType() != Session::TYPE_BASIC_AUTH && (apiRequest.getSession()->getSessionType() == Session::TYPE_SECURE) != aRequest.isSecure) { 55 | apiRequest.setResponseErrorStr("Protocol mismatch"); 56 | return http::status::not_acceptable; 57 | } 58 | 59 | apiRequest.getSession()->updateActivity(); 60 | 61 | code = apiRequest.getSession()->handleRequest(apiRequest); 62 | } catch (const ArgumentException& e) { 63 | apiRequest.setResponseErrorJson(e.toJSON()); 64 | code = http::status::unprocessable_entity; 65 | } catch (const RequestException& e) { 66 | apiRequest.setResponseErrorStr(e.what()); 67 | code = e.getCode(); 68 | } catch (const std::exception& e) { 69 | apiRequest.setResponseErrorStr(e.what()); 70 | code = http::status::bad_request; 71 | } 72 | 73 | dcassert(HttpUtil::isStatusOk(code) || code == CODE_DEFERRED || apiRequest.hasErrorMessage()); 74 | return static_cast(code); 75 | } 76 | 77 | api_return ApiRouter::routeAuthRequest(RouterRequest& aRequest) { 78 | auto& apiRequest = aRequest.apiRequest; 79 | if (apiRequest.getPathTokenAt(0) == "authorize" && apiRequest.getMethod() == METHOD_POST) { 80 | return SessionApi::handleLogin(aRequest); 81 | } else if (apiRequest.getPathTokenAt(0) == "socket" && apiRequest.getMethod() == METHOD_POST) { 82 | return SessionApi::handleSocketConnect(aRequest); 83 | } 84 | 85 | apiRequest.setResponseErrorStr("Invalid command/method (not authenticated)"); 86 | return http::status::bad_request; 87 | } 88 | } -------------------------------------------------------------------------------- /web-server/ContextMenuItem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_MENU_ITEM_H 20 | #define DCPLUSPLUS_WEBSERVER_MENU_ITEM_H 21 | 22 | #include "forward.h" 23 | 24 | #include "Access.h" 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | namespace webserver { 34 | 35 | using ContextMenuSupportList = StringList; 36 | 37 | struct ContextMenuItemListData { 38 | ContextMenuItemListData(const ContextMenuSupportList& aSupports, const AccessList aAccess, CallerPtr aCaller) noexcept : 39 | caller(aCaller), supports(aSupports), access(aAccess) {} 40 | 41 | CallerPtr caller; 42 | const ContextMenuSupportList supports; 43 | const AccessList access; 44 | }; 45 | 46 | struct ContextMenuItemClickData { 47 | ContextMenuItemClickData(const string& aHookId, const string& aMenuItemId, const ContextMenuSupportList& aSupports, const AccessList aAccess, const SettingValueMap& aFormValues) noexcept : 48 | hookId(aHookId), menuItemId(aMenuItemId), supports(aSupports), access(aAccess), formValues(aFormValues) {} 49 | 50 | const string hookId; 51 | const string menuItemId; 52 | const ContextMenuSupportList supports; 53 | const AccessList access; 54 | const SettingValueMap formValues; 55 | }; 56 | 57 | class ContextMenuItem { 58 | public: 59 | typedef vector> List; 60 | 61 | ContextMenuItem( 62 | const string& aId, const string& aTitle, const StringMap& aIconInfo, const ActionHookSubscriber& aHook, 63 | const StringList& aUrls, const ExtensionSettingItem::List& aFormFieldDefinitions, const ContextMenuItem::List& aChildren 64 | ) : 65 | id(aId), title(aTitle), iconInfo(aIconInfo), hook(aHook), urls(aUrls), formFieldDefinitions(aFormFieldDefinitions), children(aChildren) { 66 | 67 | } 68 | 69 | GETSET(string, id, Id); 70 | GETSET(string, title, Title); 71 | GETSET(StringMap, iconInfo, IconInfo); 72 | GETSET(ActionHookSubscriber, hook, Hook); 73 | GETSET(StringList, urls, Urls); 74 | GETSET(ExtensionSettingItem::List, formFieldDefinitions, FormFieldDefinitions); 75 | 76 | GETSET(List, children, Children); 77 | }; 78 | 79 | class GroupedContextMenuItem { 80 | public: 81 | GroupedContextMenuItem(const string& aId, const string& aTitle, const StringMap& aIconInfo, const ContextMenuItemList& aItems) : 82 | id(aId), title(aTitle), iconInfo(aIconInfo), items(aItems) { 83 | 84 | } 85 | 86 | GETSET(string, id, Id); 87 | GETSET(string, title, Title); 88 | GETSET(StringMap, iconInfo, IconInfo); 89 | 90 | GETSET(ContextMenuItemList, items, Items); 91 | }; 92 | 93 | } // namespace webserver 94 | 95 | #endif // DCPLUSPLUS_WEBSERVER_MENU_MANAGER_H 96 | -------------------------------------------------------------------------------- /api/SearchEntity.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_SEARCHENTITY_H 20 | #define DCPLUSPLUS_DCPP_SEARCHENTITY_H 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | 32 | namespace webserver { 33 | class SearchEntity : public SubApiModule, private SearchInstanceListener { 34 | public: 35 | static const StringList subscriptionList; 36 | 37 | typedef ParentApiModule ParentType; 38 | typedef shared_ptr Ptr; 39 | 40 | SearchEntity(ParentType* aParentModule, const SearchInstancePtr& aSearch); 41 | ~SearchEntity(); 42 | 43 | const SearchInstancePtr& getSearch() const noexcept { 44 | return search; 45 | } 46 | 47 | SearchInstanceToken getId() const noexcept override; 48 | 49 | void init() noexcept override; 50 | 51 | static json serializeSearchQuery(const SearchPtr& aQuery) noexcept; 52 | static json serializeSearchResult(const SearchResultPtr& aSR) noexcept; 53 | private: 54 | const SearchInstancePtr search; 55 | 56 | GroupedSearchResultList getResultList() noexcept; 57 | 58 | json serializeSearchQueueInfo(uint64_t aQueueItem, size_t aQueueCount) noexcept; 59 | 60 | api_return handlePostHubSearch(ApiRequest& aRequest); 61 | api_return handlePostUserSearch(ApiRequest& aRequest); 62 | api_return handleGetResults(ApiRequest& aRequest); 63 | api_return handleGetResult(ApiRequest& aRequest); 64 | 65 | api_return handleDownload(ApiRequest& aRequest); 66 | api_return handleGetChildren(ApiRequest& aRequest); 67 | 68 | void on(SearchInstanceListener::GroupedResultAdded, const GroupedSearchResultPtr& aResult) noexcept override; 69 | void on(SearchInstanceListener::ChildResultAdded, const GroupedSearchResultPtr& aResult, const SearchResultPtr&) noexcept override; 70 | void on(SearchInstanceListener::UserResult, const SearchResultPtr& aResult, const GroupedSearchResultPtr& aParent) noexcept override; 71 | void on(SearchInstanceListener::Reset) noexcept override; 72 | void on(SearchInstanceListener::HubSearchSent, const string& aSearchToken, int aSent) noexcept override; 73 | void on(SearchInstanceListener::HubSearchQueued, const string& aSearchToken, uint64_t aQueueTime, size_t aQueuedCount) noexcept override; 74 | 75 | typedef ListViewController SearchView; 76 | SearchView searchView; 77 | 78 | GroupedSearchResultPtr parseResultParam(ApiRequest& aRequest); 79 | }; 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /web-server/Session.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_SESSION_H 20 | #define DCPLUSPLUS_WEBSERVER_SESSION_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace webserver { 35 | // Sessions are owned by WebUserManager and WebSockets (websockets are closed when session is removed) 36 | class Session : public Speaker { 37 | public: 38 | enum SessionType { 39 | TYPE_PLAIN, 40 | TYPE_SECURE, 41 | TYPE_BASIC_AUTH, 42 | TYPE_EXTENSION, 43 | }; 44 | 45 | Session(const WebUserPtr& aUser, const std::string& aToken, SessionType aSessionType, WebServerManager* aServer, uint64_t maxInactivityMinutes, const string& aIP); 46 | ~Session() override; 47 | 48 | const std::string& getAuthToken() const noexcept { 49 | return token; 50 | } 51 | 52 | LocalSessionId getId() const noexcept { 53 | return id; 54 | } 55 | 56 | WebUserPtr getUser() const noexcept { 57 | return user; 58 | } 59 | 60 | SessionType getSessionType() const noexcept { 61 | return sessionType; 62 | } 63 | 64 | ApiModule* getModule(const std::string& aApiID); 65 | 66 | http::status handleRequest(ApiRequest& aRequest); 67 | 68 | Session(Session&) = delete; 69 | Session& operator=(Session&) = delete; 70 | 71 | void onSocketConnected(const WebSocketPtr& aSocket) noexcept; 72 | void onSocketDisconnected() noexcept; 73 | 74 | WebServerManager* getServer() noexcept { 75 | return server; 76 | } 77 | 78 | void updateActivity() noexcept; 79 | uint64_t getLastActivity() const noexcept { 80 | return lastActivity; 81 | } 82 | 83 | uint64_t getMaxInactivity() const noexcept { 84 | return maxInactivity; 85 | } 86 | 87 | const string& getIp() const noexcept { 88 | return ip; 89 | } 90 | 91 | void reportError(const string& aError) noexcept; 92 | bool isTimeout(uint64_t aTick) const noexcept; 93 | private: 94 | const uint64_t maxInactivity; 95 | const time_t started; 96 | 97 | uint64_t lastActivity; 98 | bool hasSocket = false; 99 | 100 | const LocalSessionId id; 101 | const std::string token; 102 | const SessionType sessionType; 103 | const string ip; 104 | 105 | WebUserPtr user; 106 | WebServerManager* server; 107 | 108 | mutable CriticalSection cs; 109 | 110 | using LazyModuleWrapper = LazyInitWrapper; 111 | std::map apiHandlers; 112 | }; 113 | } 114 | 115 | #endif -------------------------------------------------------------------------------- /web-server/Timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_TIMER_H 20 | #define DCPLUSPLUS_WEBSERVER_TIMER_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | class Timer : public boost::noncopyable { 30 | public: 31 | using CallbackWrapper = std::function; 32 | 33 | // CallbackWrapper is meant to ensure the lifetime of the timer 34 | // (which necessary only if the timer is called from a class that can be deleted, such as sessions) 35 | Timer(Callback&& aCallback, boost::asio::io_context& aIO, time_t aIntervalMillis, const CallbackWrapper& aWrapper) : 36 | cb(std::move(aCallback)), 37 | cbWrapper(aWrapper), 38 | timer(aIO), 39 | interval(std::chrono::milliseconds(aIntervalMillis)) 40 | { 41 | dcdebug("Timer %p was created\n", this); 42 | } 43 | 44 | ~Timer() { 45 | stop(true); 46 | dcdebug("Timer %p was destroyed\n", this); 47 | } 48 | 49 | bool start(bool aInstantTick) { 50 | if (shutdown) { 51 | return false; 52 | } 53 | 54 | running = true; 55 | scheduleNext(aInstantTick ? std::chrono::milliseconds(0) : interval); 56 | return true; 57 | } 58 | 59 | // Use aShutdown if the timer will be stopped permanently (e.g. the owner is being deleted) 60 | void stop(bool aShutdown) noexcept { 61 | running = false; 62 | shutdown = aShutdown; 63 | timer.cancel(); 64 | } 65 | 66 | bool isRunning() const noexcept { 67 | return running; 68 | } 69 | 70 | void flush() { 71 | timer.cancel(); 72 | scheduleNext(std::chrono::milliseconds(0)); 73 | } 74 | private: 75 | // Static in case the timer has been destructed 76 | static void tick(const boost::system::error_code& error, const CallbackWrapper& cbWrapper, Timer* aTimer) { 77 | if (error == boost::asio::error::operation_aborted) { 78 | return; 79 | } 80 | 81 | if (cbWrapper) { 82 | // We must ensure that the timer still exists when a new start call is performed 83 | cbWrapper(std::bind(&Timer::runTask, aTimer)); 84 | } else { 85 | aTimer->runTask(); 86 | } 87 | } 88 | 89 | void scheduleNext(std::chrono::milliseconds aFromNow) { 90 | if (!running) { 91 | return; 92 | } 93 | 94 | timer.expires_after(aFromNow); 95 | timer.async_wait(std::bind(&Timer::tick, std::placeholders::_1, cbWrapper, this)); 96 | } 97 | 98 | void runTask() { 99 | cb(); 100 | 101 | scheduleNext(interval); 102 | } 103 | 104 | Callback cb; 105 | CallbackWrapper cbWrapper; 106 | 107 | boost::asio::steady_timer timer; 108 | std::chrono::milliseconds interval; 109 | bool running = false; 110 | bool shutdown = false; 111 | }; 112 | 113 | using TimerPtr = shared_ptr; 114 | } 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /api/PrivateChatInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_PRIVATEMESSAGE_H 20 | #define DCPLUSPLUS_DCPP_PRIVATEMESSAGE_H 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace webserver { 34 | class PrivateChatInfo; 35 | 36 | class PrivateChatInfo : public SubApiModule, private PrivateChatListener { 37 | public: 38 | static StringList subscriptionList; 39 | 40 | typedef shared_ptr Ptr; 41 | typedef vector List; 42 | 43 | PrivateChatInfo(ParentType* aParentModule, const PrivateChatPtr& aChat); 44 | ~PrivateChatInfo(); 45 | 46 | const PrivateChatPtr& getChat() const noexcept { return chat; } 47 | 48 | static string formatCCPMState(PrivateChat::CCPMState aState) noexcept; 49 | static json serializeCCPMState(const PrivateChatPtr& aChat) noexcept; 50 | 51 | void init() noexcept override; 52 | CID getId() const noexcept override; 53 | private: 54 | api_return handleUpdateSession(ApiRequest& aRequest); 55 | api_return handleDisconnectCCPM(ApiRequest& aRequest); 56 | api_return handleConnectCCPM(ApiRequest& aRequest); 57 | 58 | api_return handleStartTyping(ApiRequest& aRequest); 59 | api_return handleEndTyping(ApiRequest& aRequest); 60 | 61 | void on(PrivateChatListener::PrivateMessage, PrivateChat*, const ChatMessagePtr& m) noexcept override { 62 | chatHandler.onChatMessage(m); 63 | } 64 | 65 | void on(PrivateChatListener::StatusMessage, PrivateChat*, const LogMessagePtr& m, const string& aOwner) noexcept override { 66 | chatHandler.onStatusMessage(m, aOwner); 67 | } 68 | 69 | void on(PrivateChatListener::Close, PrivateChat*) noexcept override; 70 | void on(PrivateChatListener::UserUpdated, PrivateChat*) noexcept override; 71 | void on(PrivateChatListener::PMStatus, PrivateChat*, uint8_t) noexcept override; 72 | void on(PrivateChatListener::CCPMStatusUpdated, PrivateChat*) noexcept override; 73 | 74 | void on(PrivateChatListener::MessagesRead, PrivateChat*) noexcept override { 75 | chatHandler.onMessagesUpdated(); 76 | } 77 | 78 | void on(PrivateChatListener::MessagesCleared, PrivateChat*) noexcept override { 79 | chatHandler.onMessagesUpdated(); 80 | } 81 | 82 | void on(PrivateChatListener::ChatCommand, PrivateChat*, const OutgoingChatMessage& aMessage) noexcept override { 83 | chatHandler.onChatCommand(aMessage); 84 | } 85 | 86 | void onSessionUpdated(const json& aData) noexcept; 87 | 88 | ChatController chatHandler; 89 | PrivateChatPtr chat; 90 | }; 91 | 92 | typedef PrivateChatInfo::Ptr PrivateChatInfoPtr; 93 | } 94 | 95 | #endif -------------------------------------------------------------------------------- /api/FilelistInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_FILELIST_H 20 | #define DCPLUSPLUS_DCPP_FILELIST_H 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | 33 | namespace webserver { 34 | 35 | class FilelistInfo : public SubApiModule, private DirectoryListingListener { 36 | public: 37 | using Ptr = shared_ptr; 38 | 39 | static const StringList subscriptionList; 40 | 41 | FilelistInfo(ParentType* aParentModule, const DirectoryListingPtr& aFilelist); 42 | ~FilelistInfo() override; 43 | 44 | DirectoryListingPtr getList() const noexcept { return dl; } 45 | 46 | static string formatState(const DirectoryListingPtr& aList) noexcept; 47 | static json serializeState(const DirectoryListingPtr& aList) noexcept; 48 | static json serializeLocation(const DirectoryListingPtr& aListing) noexcept; 49 | 50 | void init() noexcept override; 51 | CID getId() const noexcept override; 52 | private: 53 | api_return handleUpdateList(ApiRequest& aRequest); 54 | api_return handleChangeDirectory(ApiRequest& aRequest); 55 | api_return handleSetRead(ApiRequest& aRequest); 56 | api_return handleGetItems(ApiRequest& aRequest); 57 | api_return handleGetItem(ApiRequest& aRequest); 58 | 59 | DirectoryListing::DirectoryPtr ensureCurrentDirectoryLoaded() const; 60 | 61 | void on(DirectoryListingListener::LoadingFinished, int64_t aStart, const string& aDir, uint8_t aType) noexcept override; 62 | void on(DirectoryListingListener::LoadingFailed, const string& aReason) noexcept override; 63 | void on(DirectoryListingListener::LoadingStarted, bool changeDir) noexcept override; 64 | void on(DirectoryListingListener::ChangeDirectory, const string& aDir, uint8_t aChangeType) noexcept override; 65 | void on(DirectoryListingListener::UpdateStatusMessage, const string& aMessage) noexcept override; 66 | void on(DirectoryListingListener::UserUpdated) noexcept override; 67 | void on(DirectoryListingListener::StateChanged) noexcept override; 68 | void on(DirectoryListingListener::Read) noexcept override; 69 | void on(DirectoryListingListener::ShareProfileChanged) noexcept override; 70 | 71 | void addListTask(Callback&& aTask) noexcept; 72 | 73 | FilelistItemInfo::List getCurrentViewItems(); 74 | 75 | DirectoryListingPtr dl; 76 | 77 | using DirectoryView = ListViewController; 78 | DirectoryView directoryView; 79 | 80 | void onSessionUpdated(const json& aData) noexcept; 81 | 82 | FilelistItemInfo::List currentViewItems; 83 | bool currentViewItemsInitialized = false; 84 | 85 | void updateItems(const string& aPath) noexcept; 86 | 87 | SharedMutex cs; 88 | }; 89 | 90 | using FilelistInfoPtr = FilelistInfo::Ptr; 91 | } 92 | 93 | #endif -------------------------------------------------------------------------------- /api/common/Property.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPP_PROPERTY_H 20 | #define DCPP_PROPERTY_H 21 | 22 | #include 23 | 24 | namespace webserver { 25 | 26 | enum SerializationMethod { 27 | SERIALIZE_TEXT, 28 | SERIALIZE_NUMERIC, 29 | SERIALIZE_BOOL, 30 | SERIALIZE_CUSTOM 31 | }; 32 | 33 | enum FilterPropertyType { 34 | TYPE_TEXT, 35 | TYPE_SIZE, 36 | TYPE_TIME, 37 | TYPE_SPEED, 38 | TYPE_NUMERIC_OTHER, 39 | TYPE_IMAGE, 40 | TYPE_LIST_NUMERIC, 41 | TYPE_LIST_TEXT, 42 | }; 43 | 44 | enum SortMethod { 45 | SORT_TEXT, 46 | SORT_NUMERIC, 47 | SORT_CUSTOM, 48 | SORT_NONE 49 | }; 50 | 51 | struct Property { 52 | const int id; 53 | const std::string name; 54 | const FilterPropertyType filterType; 55 | const SerializationMethod serializationMethod; 56 | const SortMethod sortMethod; 57 | }; 58 | 59 | using PropertyList = vector; 60 | 61 | using PropertyIdSet = std::set; 62 | 63 | // Creates a list of numeric IDs of all properties 64 | static inline PropertyIdSet toPropertyIdSet(const PropertyList& aProperties) { 65 | PropertyIdSet ret; 66 | for (const auto& p : aProperties) 67 | ret.insert(p.id); 68 | 69 | return ret; 70 | } 71 | 72 | static inline int findPropertyByName(const string& aPropertyName, const PropertyList& aProperties) { 73 | auto p = ranges::find_if(aProperties, [&](const Property& aProperty) { return aProperty.name == aPropertyName; }); 74 | if (p == aProperties.end()) { 75 | return -1; 76 | } 77 | 78 | return (*p).id; 79 | } 80 | 81 | template 82 | struct PropertyItemHandler { 83 | using ItemList = vector; 84 | using CustomPropertySerializer = std::function; 85 | using CustomFilterFunction = std::function; 86 | 87 | using SorterFunction = std::function; 88 | using StringFunction = std::function; 89 | using NumberFunction = std::function; 90 | using ItemListFunction = std::function; 91 | 92 | PropertyItemHandler(const PropertyList& aProperties, 93 | StringFunction aStringF, NumberFunction aNumberF, 94 | SorterFunction aSorterF, CustomPropertySerializer aJsonF, 95 | CustomFilterFunction aFilterF = nullptr) : 96 | 97 | properties(aProperties), 98 | stringF(aStringF), numberF(aNumberF), 99 | customSorterF(aSorterF), jsonF(aJsonF), 100 | customFilterF(aFilterF) { } 101 | 102 | // Information about each property 103 | const PropertyList& properties; 104 | 105 | // Return std::string value of the property 106 | const StringFunction stringF; 107 | 108 | // Return double value of the property 109 | const NumberFunction numberF; 110 | 111 | // Compares two items 112 | const SorterFunction customSorterF; 113 | 114 | // Returns JSON for special properties 115 | const CustomPropertySerializer jsonF; 116 | 117 | // Returns true if the item matches filter 118 | const CustomFilterFunction customFilterF; 119 | }; 120 | } 121 | 122 | #endif -------------------------------------------------------------------------------- /api/base/HookApiModule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_HOOK_APIMODULE_H 20 | #define DCPLUSPLUS_DCPP_HOOK_APIMODULE_H 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace webserver { 32 | 33 | #define MODULE_HOOK_HANDLER(func, name, hook, callback) \ 34 | func(name, [this](ActionHookSubscriber&& aSubscriber) { \ 35 | return hook.addSubscriber(std::move(aSubscriber), HOOK_CALLBACK(callback)); \ 36 | }, [](const string& aId) { \ 37 | hook.removeSubscriber(aId); \ 38 | }, [] { \ 39 | return hook.getSubscribers(); \ 40 | }); 41 | 42 | 43 | #define HOOK_HANDLER(name, hook, callback) MODULE_HOOK_HANDLER(HookApiModule::createHook, name, hook, callback) 44 | 45 | class HookApiModule : public SubscribableApiModule { 46 | public: 47 | using HookAddF = std::function; 48 | using HookRemoveF = std::function; 49 | using HookListF = std::function; 50 | 51 | class APIHook { 52 | public: 53 | APIHook(const string& aHookId, HookAddF&& aAddHandlerF, HookRemoveF&& aRemoveF, HookListF&& aListF) : 54 | addHandlerF(std::move(aAddHandlerF)), removeHandlerF(std::move(aRemoveF)), listHandlerF(std::move(aListF)), hookId(aHookId) {} 55 | 56 | bool enable(ActionHookSubscriber&& aHookSubscriber) noexcept; 57 | void disable(const Session* aSession) noexcept; 58 | 59 | ActionHookSubscriberList getSubscribers() const noexcept { 60 | return listHandlerF(); 61 | } 62 | 63 | GETPROP(string, hookId, HookId); 64 | GETPROP(string, hookSubscriberId, HookSubscriberId); 65 | private: 66 | const HookAddF addHandlerF; 67 | const HookRemoveF removeHandlerF; 68 | const HookListF listHandlerF; 69 | }; 70 | 71 | HookApiModule(Session* aSession, Access aSubscriptionAccess, Access aHookAccess); 72 | 73 | virtual void createHook(const string& aSubscription, HookAddF&& aAddHandler, HookRemoveF&& aRemoveF, HookListF&& aListF) noexcept; 74 | 75 | virtual HookCompletionDataPtr maybeFireHook(const string& aSubscription, int aTimeoutSeconds, const JsonCallback& aJsonCallback); 76 | virtual HookCompletionDataPtr fireHook(const string& aSubscription, int aTimeoutSeconds, const json& aJson); 77 | protected: 78 | void addHook(const string& aSubscription, APIHook&& aHook) noexcept; 79 | 80 | HookActionHandler actionHandler; 81 | 82 | APIHook& getAPIHook(ApiRequest& aRequest); 83 | 84 | void on(SessionListener::SocketDisconnected) noexcept override; 85 | 86 | virtual api_return handleSubscribeHook(ApiRequest& aRequest); 87 | virtual api_return handleUnsubscribeHook(ApiRequest& aRequest); 88 | virtual api_return handleListHooks(ApiRequest& aRequest); 89 | 90 | api_return handleResolveHookAction(ApiRequest& aRequest); 91 | api_return handleRejectHookAction(ApiRequest& aRequest); 92 | 93 | static ActionHookSubscriber deserializeActionHookSubscriber(CallerPtr aOwner, Session* aSession, const json& aJson); 94 | private: 95 | map hooks; 96 | }; 97 | } 98 | 99 | #endif -------------------------------------------------------------------------------- /api/base/HookActionHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_DCPP_HOOK_ACTION_HANDLER_H 20 | #define DCPLUSPLUS_DCPP_HOOK_ACTION_HANDLER_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | namespace webserver { 30 | struct HookCompletionData; 31 | using HookCompletionDataPtr = std::shared_ptr; 32 | 33 | class HookActionHandler { 34 | public: 35 | HookCompletionDataPtr runHook(const string& aSubscription, int aTimeoutSeconds, const json& aJson, SubscribableApiModule* aModule); 36 | void stop() noexcept; 37 | 38 | api_return handleResolveHookAction(ApiRequest& aRequest); 39 | api_return handleRejectHookAction(ApiRequest& aRequest); 40 | 41 | static void reportError(const string& aError, SubscribableApiModule* aModule) noexcept; 42 | private: 43 | api_return handleHookAction(ApiRequest& aRequest, bool aRejected); 44 | mutable SharedMutex cs; 45 | 46 | struct PendingAction { 47 | Semaphore& semaphore; 48 | HookCompletionDataPtr completionData; 49 | }; 50 | 51 | using PendingHookActionMap = map; 52 | PendingHookActionMap pendingHookActions; 53 | 54 | static IncrementingIdCounter hookIdCounter; 55 | }; 56 | 57 | class HookActionHandler; 58 | struct HookCompletionData { 59 | HookCompletionData(bool aRejected, const json& aJson); 60 | 61 | json resolveJson; 62 | 63 | string rejectId; 64 | string rejectMessage; 65 | const bool rejected; 66 | 67 | template 68 | using HookDataGetter = std::function& aResultGetter)>; 69 | 70 | template 71 | static ActionHookResult toResult(const HookCompletionDataPtr& aData, const ActionHookResultGetter& aResultGetter, SubscribableApiModule* aModule, const HookDataGetter& aDataGetter = nullptr) noexcept { 72 | if (aData) { 73 | if (aData->rejected) { 74 | return aResultGetter.getRejection(aData->rejectId, aData->rejectMessage); 75 | } else if (aDataGetter) { 76 | try { 77 | const auto data = aResultGetter.getData(aDataGetter(aData->resolveJson, aResultGetter)); 78 | return data; 79 | } catch (const ArgumentException& e) { 80 | dcdebug("Failed to deserialize hook data for subscriber %s: %s (field %s)\n", aResultGetter.getSubscriber().getId().c_str(), e.what(), e.getField().c_str()); 81 | HookActionHandler::reportError("Failed to deserialize hook data for subscriber " + aResultGetter.getSubscriber().getId() + ": " + e.what() + " (field \"" + e.getField() + "\")", aModule); 82 | return aResultGetter.getDataRejection(e); 83 | } catch (const std::exception& e) { 84 | dcdebug("Failed to deserialize hook data for subscriber %s: %s\n", aResultGetter.getSubscriber().getId().c_str(), e.what()); 85 | HookActionHandler::reportError("Failed to deserialize hook data for subscriber " + aResultGetter.getSubscriber().getId() + ": " + e.what(), aModule); 86 | return aResultGetter.getDataRejection(e); 87 | } 88 | } 89 | } 90 | 91 | return { nullptr, nullptr }; 92 | } 93 | }; 94 | } 95 | 96 | #endif -------------------------------------------------------------------------------- /api/EventApi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | namespace webserver { 32 | EventApi::EventApi(Session* aSession) : 33 | SubscribableApiModule(aSession, Access::EVENTS_VIEW) 34 | { 35 | createSubscriptions({ "event_message", "event_counts" }); 36 | 37 | METHOD_HANDLER(Access::EVENTS_VIEW, METHOD_POST, (EXACT_PARAM("read")), EventApi::handleRead); 38 | METHOD_HANDLER(Access::EVENTS_VIEW, METHOD_GET, (EXACT_PARAM("counts")), EventApi::handleGetInfo); 39 | 40 | METHOD_HANDLER(Access::EVENTS_VIEW, METHOD_GET, (RANGE_MAX_PARAM), EventApi::handleGetMessages); 41 | METHOD_HANDLER(Access::EVENTS_EDIT, METHOD_DELETE, (), EventApi::handleClearMessages); 42 | METHOD_HANDLER(Access::EVENTS_EDIT, METHOD_POST, (), EventApi::handlePostMessage); 43 | 44 | LogManager::getInstance()->addListener(this); 45 | } 46 | 47 | EventApi::~EventApi() { 48 | LogManager::getInstance()->removeListener(this); 49 | } 50 | 51 | api_return EventApi::handlePostMessage(ApiRequest& aRequest) { 52 | auto messageInput = Deserializer::deserializeStatusMessage(aRequest.getRequestBody()); 53 | LogManager::getInstance()->message(messageInput.message, messageInput.severity, MessageUtils::parseStatusMessageLabel(aRequest.getSession())); 54 | return http::status::no_content; 55 | } 56 | 57 | api_return EventApi::handleRead(ApiRequest&) { 58 | LogManager::getInstance()->setRead(); 59 | return http::status::no_content; 60 | } 61 | 62 | api_return EventApi::handleClearMessages(ApiRequest&) { 63 | LogManager::getInstance()->clearCache(); 64 | return http::status::no_content; 65 | } 66 | 67 | api_return EventApi::handleGetMessages(ApiRequest& aRequest) { 68 | auto j = Serializer::serializeFromEnd( 69 | aRequest.getRangeParam(MAX_COUNT), 70 | LogManager::getInstance()->getCache().getLogMessages(), 71 | MessageUtils::serializeLogMessage 72 | ); 73 | 74 | aRequest.setResponseBody(j); 75 | return http::status::ok; 76 | } 77 | 78 | api_return EventApi::handleGetInfo(ApiRequest& aRequest) { 79 | aRequest.setResponseBody(MessageUtils::serializeCacheInfo(LogManager::getInstance()->getCache(), MessageUtils::serializeUnreadLog)); 80 | return http::status::ok; 81 | } 82 | 83 | void EventApi::on(LogManagerListener::Message, const LogMessagePtr& aMessageData) noexcept { 84 | // Avoid deadlocks if the event is fired from inside a lock 85 | addAsyncTask([this, aMessageData] { 86 | if (subscriptionActive("event_message")) { 87 | send("event_message", MessageUtils::serializeLogMessage(aMessageData)); 88 | } 89 | 90 | onMessagesChanged(); 91 | }); 92 | } 93 | 94 | void EventApi::onMessagesChanged() noexcept { 95 | if (!subscriptionActive("event_counts")) { 96 | return; 97 | } 98 | 99 | send("event_counts", MessageUtils::serializeCacheInfo(LogManager::getInstance()->getCache(), MessageUtils::serializeUnreadLog)); 100 | } 101 | 102 | void EventApi::on(LogManagerListener::Cleared) noexcept { 103 | onMessagesChanged(); 104 | } 105 | 106 | void EventApi::on(LogManagerListener::MessagesRead) noexcept { 107 | onMessagesChanged(); 108 | } 109 | } -------------------------------------------------------------------------------- /api/base/ApiModule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace webserver { 27 | ApiModule::ApiModule(Session* aSession) : session(aSession) { 28 | 29 | } 30 | 31 | ApiModule::~ApiModule() { 32 | 33 | } 34 | 35 | optional ApiModule::RequestHandler::matchParams(const ApiRequest::PathTokenList& aPathTokens) const noexcept { 36 | if (method == METHOD_FORWARD) { 37 | if (aPathTokens.size() < params.size()) { 38 | return nullopt; 39 | } 40 | } else if (aPathTokens.size() != params.size()) { 41 | return nullopt; 42 | } 43 | 44 | for (auto i = 0; i < static_cast(params.size()); i++) { 45 | try { 46 | if (!boost::regex_search(aPathTokens[i], params[i].reg)) { 47 | return nullopt; 48 | } 49 | } catch (const std::runtime_error&) { 50 | return nullopt; 51 | } 52 | } 53 | 54 | ApiRequest::NamedParamMap paramMap; 55 | for (auto i = 0; i < static_cast(params.size()); i++) { 56 | paramMap[params[i].id] = aPathTokens[i]; 57 | } 58 | 59 | return paramMap; 60 | } 61 | 62 | api_return ApiModule::handleRequest(ApiRequest& aRequest) { 63 | bool hasParamNameMatch = false; // for better error reporting 64 | 65 | // Match parameters 66 | auto handler = find_if(requestHandlers.begin(), requestHandlers.end(), [&](const RequestHandler& aHandler) { 67 | // Regular matching 68 | auto namedParams = aHandler.matchParams(aRequest.getPathTokens()); 69 | if (!namedParams) { 70 | return false; 71 | } 72 | 73 | if (aHandler.method == aRequest.getMethod() || aHandler.method == METHOD_FORWARD) { 74 | aRequest.setNamedParams(*namedParams); 75 | return true; 76 | } 77 | 78 | hasParamNameMatch = true; 79 | return false; 80 | }); 81 | 82 | if (handler == requestHandlers.end()) { 83 | if (hasParamNameMatch) { 84 | aRequest.setResponseErrorStr("Method " + aRequest.getMethodStr() + " is not supported for this handler"); 85 | return http::status::method_not_allowed; 86 | } 87 | 88 | aRequest.setResponseErrorStr("The supplied URL " + aRequest.getRequestPath() + " doesn't match any method in this API module"); 89 | return http::status::bad_request; 90 | } 91 | 92 | // Check permission 93 | if (!session->getUser()->hasPermission(handler->access)) { 94 | aRequest.setResponseErrorStr("The permission " + WebUser::accessToString(handler->access) + " is required for accessing this method"); 95 | return http::status::forbidden; 96 | } 97 | 98 | return handler->f(aRequest); 99 | } 100 | 101 | TimerPtr ApiModule::getTimer(Callback&& aTask, time_t aIntervalMillis) { 102 | return session->getServer()->addTimer(std::move(aTask), aIntervalMillis, 103 | std::bind(&ApiModule::asyncRunWrapper, std::placeholders::_1, session->getId()) 104 | ); 105 | } 106 | 107 | Callback ApiModule::getAsyncWrapper(Callback&& aTask) noexcept { 108 | auto sessionId = session->getId(); 109 | return [task = std::move(aTask), sessionId] { 110 | return asyncRunWrapper(task, sessionId); 111 | }; 112 | } 113 | 114 | void ApiModule::asyncRunWrapper(const Callback& aTask, LocalSessionId aSessionId) { 115 | // Ensure that the session (and socket) won't be deleted 116 | auto s = WebServerManager::getInstance()->getUserManager().getSession(aSessionId); 117 | if (!s) { 118 | return; 119 | } 120 | 121 | aTask(); 122 | } 123 | 124 | void ApiModule::addAsyncTask(Callback&& aTask) { 125 | session->getServer()->addAsyncTask(getAsyncWrapper(std::move(aTask))); 126 | } 127 | } -------------------------------------------------------------------------------- /api/base/SubscribableApiModule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #include "stdinc.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | namespace webserver { 29 | SubscribableApiModule::SubscribableApiModule(Session* aSession, Access aSubscriptionAccess) : ApiModule(aSession), subscriptionAccess(aSubscriptionAccess) { 30 | socket = aSession->getServer()->getSocketManager().getSocket(aSession->getId()); 31 | 32 | aSession->addListener(this); 33 | 34 | METHOD_HANDLER(aSubscriptionAccess, METHOD_POST, (EXACT_PARAM("listeners"), STR_PARAM(LISTENER_PARAM_ID)), SubscribableApiModule::handleSubscribe); 35 | METHOD_HANDLER(aSubscriptionAccess, METHOD_DELETE, (EXACT_PARAM("listeners"), STR_PARAM(LISTENER_PARAM_ID)), SubscribableApiModule::handleUnsubscribe); 36 | } 37 | 38 | SubscribableApiModule::~SubscribableApiModule() { 39 | session->removeListener(this); 40 | socket = nullptr; 41 | } 42 | 43 | void SubscribableApiModule::createSubscriptions(const StringList& aSubscriptions) noexcept { 44 | for (const auto& s : aSubscriptions) { 45 | createSubscription(s); 46 | } 47 | } 48 | 49 | void SubscribableApiModule::createSubscription(const string& aSubscription) noexcept { 50 | dcassert(subscriptions.find(aSubscription) == subscriptions.end()); 51 | subscriptions.emplace(aSubscription, false); 52 | } 53 | 54 | void SubscribableApiModule::on(SessionListener::SocketConnected, const WebSocketPtr& aSocket) noexcept { 55 | socket = aSocket; 56 | } 57 | 58 | void SubscribableApiModule::on(SessionListener::SocketDisconnected) noexcept { 59 | // Disable all subscriptions 60 | for (auto& [_, enabled] : subscriptions) { 61 | enabled = false; 62 | } 63 | 64 | socket = nullptr; 65 | } 66 | 67 | const string& SubscribableApiModule::parseSubscription(ApiRequest& aRequest) { 68 | if (!socket) { 69 | throw RequestException(http::status::precondition_required, "Socket required"); 70 | } 71 | 72 | const auto& subscription = aRequest.getStringParam(LISTENER_PARAM_ID); 73 | if (!subscriptionExists(subscription)) { 74 | throw RequestException(http::status::not_found, "No such subscription: " + subscription); 75 | } 76 | 77 | return subscription; 78 | } 79 | 80 | api_return SubscribableApiModule::handleSubscribe(ApiRequest& aRequest) { 81 | const auto& subscription = parseSubscription(aRequest); 82 | setSubscriptionState(subscription, true); 83 | return http::status::no_content; 84 | } 85 | 86 | api_return SubscribableApiModule::handleUnsubscribe(ApiRequest& aRequest) { 87 | const auto& subscription = parseSubscription(aRequest); 88 | setSubscriptionState(subscription, false); 89 | return http::status::no_content; 90 | } 91 | 92 | bool SubscribableApiModule::send(const json& aJson) { 93 | // Ensure that the socket won't be deleted while sending the message... 94 | auto s = socket; 95 | if (!s) { 96 | return false; 97 | } 98 | 99 | try { 100 | s->sendPlain(aJson); 101 | } catch (const json::exception&) { 102 | // Ignore JSON errors... 103 | return false; 104 | } 105 | 106 | return true; 107 | } 108 | 109 | bool SubscribableApiModule::send(const string& aSubscription, const json& aData) { 110 | return send({ 111 | { "event", aSubscription }, 112 | { "data", aData }, 113 | }); 114 | } 115 | 116 | bool SubscribableApiModule::maybeSend(const string& aSubscription, const JsonCallback& aCallback) { 117 | if (!subscriptionActive(aSubscription)) { 118 | return false; 119 | } 120 | 121 | return send(aSubscription, aCallback()); 122 | } 123 | } -------------------------------------------------------------------------------- /web-server/WebServerSettings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2024 AirDC++ Project 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | #ifndef DCPLUSPLUS_WEBSERVER_SETTINGS_H 20 | #define DCPLUSPLUS_WEBSERVER_SETTINGS_H 21 | 22 | #include "forward.h" 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | namespace webserver { 30 | class WebServerSettings : private WebServerManagerListener { 31 | public: 32 | #ifdef _WIN32 33 | static const string localNodeDirectoryName; 34 | #endif 35 | 36 | explicit WebServerSettings(WebServerManager* aServer); 37 | ~WebServerSettings() override; 38 | 39 | enum ServerSettings { 40 | PLAIN_PORT, 41 | PLAIN_BIND, 42 | 43 | TLS_PORT, 44 | TLS_BIND, 45 | 46 | TLS_CERT_PATH, 47 | TLS_CERT_KEY_PATH, 48 | 49 | SERVER_THREADS, 50 | EXTENSION_ENGINES, 51 | 52 | DEFAULT_SESSION_IDLE_TIMEOUT, 53 | PING_INTERVAL, 54 | PING_TIMEOUT, 55 | 56 | EXTENSIONS_DEBUG_MODE, 57 | EXTENSIONS_INIT_TIMEOUT, 58 | EXTENSIONS_AUTO_UPDATE, 59 | 60 | SHARE_FILE_VALIDATION_HOOK_TIMEOUT, 61 | SHARE_DIRECTORY_VALIDATION_HOOK_TIMEOUT, 62 | NEW_SHARE_FILE_VALIDATION_HOOK_TIMEOUT, 63 | NEW_SHARE_DIRECTORY_VALIDATION_HOOK_TIMEOUT, 64 | 65 | OUTGOING_CHAT_MESSAGE_HOOK_TIMEOUT, 66 | INCOMING_CHAT_MESSAGE_HOOK_TIMEOUT, 67 | 68 | QUEUE_ADD_BUNDLE_FILE_HOOK_TIMEOUT, 69 | QUEUE_ADD_BUNDLE_HOOK_TIMEOUT, 70 | QUEUE_ADD_SOURCE_HOOK_TIMEOUT, 71 | QUEUE_FILE_FINISHED_HOOK_TIMEOUT, 72 | QUEUE_BUNDLE_FINISHED_HOOK_TIMEOUT, 73 | 74 | FILELIST_LOAD_DIRECTORY_HOOK_TIMEOUT, 75 | FILELIST_LOAD_FILE_HOOK_TIMEOUT, 76 | 77 | OUTGOING_HUB_COMMAND_HOOK_TIMEOUT, 78 | OUTGOING_UDP_COMMAND_HOOK_TIMEOUT, 79 | OUTGOING_TCP_COMMAND_HOOK_TIMEOUT, 80 | 81 | SEARCH_INCOMING_USER_RESULT_HOOK_TIMEOUT, 82 | 83 | LIST_MENUITEMS_HOOK_TIMEOUT, 84 | }; 85 | 86 | ServerSettingItem& getSettingItem(ServerSettings aSetting) noexcept { 87 | return settings[aSetting]; 88 | } 89 | 90 | ServerSettingItem* getSettingItem(const string& aKey) noexcept { 91 | return ApiSettingItem::findSettingItem(settings, aKey); 92 | } 93 | 94 | using JsonParseCallback = std::function; 95 | static bool loadSettingFile(AppUtil::Paths aPath, const string& aFileName, const JsonParseCallback& aParseCallback, const MessageCallback& aCustomErrorF, int aMaxConfigVersion) noexcept; 96 | static bool saveSettingFile(const json& aJson, AppUtil::Paths aPath, const string& aFileName, const MessageCallback& aCustomErrorF, int aConfigVersion) noexcept; 97 | 98 | json toJson() const noexcept; 99 | void fromJsonThrow(const json& aJson, int aVersion); 100 | 101 | string getConfigFilePath() const noexcept; 102 | 103 | void setValue(ApiSettingItem& aItem, const json& aJson); 104 | void setDefaultValue(ApiSettingItem& aItem, const json& aJson); 105 | void unset(ApiSettingItem& aItem) noexcept; 106 | 107 | WebServerSettings(WebServerSettings&) = delete; 108 | WebServerSettings& operator=(WebServerSettings&) = delete; 109 | private: 110 | WebServerManager* wsm; 111 | 112 | ServerSettingItem::List settings; 113 | ServerSettingItem::List extensionEngines; 114 | 115 | static json getDefaultExtensionEngines() noexcept; 116 | 117 | bool isDirty = false; 118 | 119 | void setDirty() noexcept; 120 | 121 | void on(WebServerManagerListener::LoadSettings, const MessageCallback& aErrorF) noexcept override; 122 | void on(WebServerManagerListener::SaveSettings, const MessageCallback& aErrorF) noexcept override; 123 | }; 124 | 125 | #define WEBCFG(k) (webserver::WebServerManager::getInstance()->getSettingsManager().getSettingItem(webserver::WebServerSettings::k)) 126 | } 127 | 128 | #endif --------------------------------------------------------------------------------