/** * @file src/confighttp.h * @brief Declarations for the Web UI Config HTTP server. */ #pragma once // standard includes #include #include #include // lib includes #include #include // local includes #include "thread_safe.h" /** * @def WEB_DIR * @brief Macro for WEB DIR. */ #define WEB_DIR SUNSHINE_ASSETS_DIR "/web/" namespace confighttp { constexpr auto PORT_HTTPS = 1; ///< GameStream port offset for port https. // Type aliases for HTTPS server components using https_server_t = SimpleWeb::Server; using resp_https_t = std::shared_ptr::Response>; using req_https_t = std::shared_ptr::Request>; // Main server start function void start(); void print_req(const req_https_t &request); void send_response(const resp_https_t &response, const nlohmann::json &output_tree); void send_unauthorized(const resp_https_t &response, const req_https_t &request); void send_redirect(const resp_https_t &response, const req_https_t &request, const char *path); bool authenticate(const resp_https_t &response, const req_https_t &request); void not_found(const resp_https_t &response, const req_https_t &request, const std::string &error_message = "Not Found"); void bad_request(const resp_https_t &response, const req_https_t &request, const std::string &error_message = "Bad Request"); /** * @brief Check content type. * * @param response HTTP response object to populate. * @param request HTTP request data from the client. * @param contentType Expected HTTP content type. * @return True when the request passes validation and processing may continue. */ bool check_content_type(const resp_https_t &response, const req_https_t &request, const std::string_view &contentType); std::string generate_csrf_token(const std::string &client_id); /** * @brief Validate CSRF token. * * @param response HTTP response object to populate. * @param request HTTP request data from the client. * @param client_id Client identifier used to look up the CSRF token. * @return True when the request passes validation and processing may continue. */ bool validate_csrf_token(const resp_https_t &response, const req_https_t &request, const std::string &client_id); std::string get_client_id(const req_https_t &request); /** * @brief Check app index. * * @param response HTTP response object to populate. * @param request HTTP request data from the client. * @param index Zero-based index of the item being addressed. * @return True when the request passes validation and processing may continue. */ bool check_app_index(const resp_https_t &response, const req_https_t &request, int index); void getPage(const resp_https_t &response, const req_https_t &request, const char *html_file, bool require_auth = true, bool redirect_if_username = false); void getAsset(const resp_https_t &response, const req_https_t &request); void browseDirectory(const resp_https_t &response, const req_https_t &request); void getLocale(const resp_https_t &response, const req_https_t &request); void getCSRFToken(const resp_https_t &response, const req_https_t &request); // Browse helper functions (also exposed for unit testing) /** * @brief Checks whether a directory entry qualifies as an executable file. * @param entry The directory entry to check. * @param status The cached file status for the entry. * @return True if the file should be included in an executable-type listing. */ bool is_browsable_executable(const std::filesystem::directory_entry &entry, const std::filesystem::file_status &status); /** * @brief Lists, filters, and sorts the entries of a directory for the browse API. * @param dir_path The directory to list. * @param type_str Filter type: "directory", "executable", "file", or "any". * @return Sorted JSON array of entry objects with name/type/path fields. */ nlohmann::json build_browse_entries(const std::filesystem::path &dir_path, const std::string &type_str); #ifdef _WIN32 /** * @brief Builds a JSON array of available Windows drive letters. * @return JSON array of drive-letter entries. */ nlohmann::json get_windows_drives(); #endif } // namespace confighttp // mime types map /** * @brief File-extension to MIME-type mapping used when serving the Web UI. */ const std::map mime_types = { {"css", "text/css"}, {"gif", "image/gif"}, {"htm", "text/html"}, {"html", "text/html"}, {"ico", "image/x-icon"}, {"jpeg", "image/jpeg"}, {"jpg", "image/jpeg"}, {"js", "application/javascript"}, {"json", "application/json"}, {"png", "image/png"}, {"svg", "image/svg+xml"}, {"ttf", "font/ttf"}, {"txt", "text/plain"}, {"woff2", "font/woff2"}, {"xml", "text/xml"}, };