diff --git a/CMakeLists.txt b/CMakeLists.txt index d343083..331c846 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 5.2.43) +set(BLT_VERSION 5.3.0) set(BLT_TARGET BLT) @@ -108,6 +108,7 @@ endif () #include zlib if the user has it. find_package(ZLIB QUIET) +find_package(CURL QUIET) if (${ZLIB_FOUND}) include_directories(${ZLIB_INCLUDE_DIRS}) @@ -115,6 +116,13 @@ else () message("ZLIB was not found, this is fine however if you wish you use gzip with NBT it is required.") endif () +if (${CURL_FOUND}) + message(STATUS "Linking cURL!") + include_directories(${CURL_INCLUDE_DIRS}) +else () + message(STATUS "cURL not found, some library features will be disabled!") +endif () + include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}/config/) @@ -148,6 +156,11 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libraries/parallel-hashmap) target_include_directories(${BLT_TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libraries/parallel-hashmap) endif () +if (${CURL_FOUND}) + target_include_directories(${BLT_TARGET} PUBLIC ${CURL_INCLUDE_DIRS}) + target_link_libraries(${BLT_TARGET} PUBLIC ${CURL_LIBRARIES}) +endif () + message("BLT ${Yellow}${BLT_VERSION}${ColourReset} Successfully included!") message("Installing to ${CMAKE_INSTALL_LIBDIR} with headers at ${CMAKE_INSTALL_INCLUDEDIR}") diff --git a/include/blt/fs/fwddecl.h b/include/blt/fs/fwddecl.h index 32d395d..ee48357 100644 --- a/include/blt/fs/fwddecl.h +++ b/include/blt/fs/fwddecl.h @@ -86,7 +86,7 @@ namespace blt::fs return 0; } - virtual void seek(i64 offset, seek_origin origin = seek_origin::seek_set) + virtual void seek(i64, seek_origin) { } diff --git a/include/blt/std/requests.h b/include/blt/std/requests.h new file mode 100644 index 0000000..6d7a609 --- /dev/null +++ b/include/blt/std/requests.h @@ -0,0 +1,31 @@ +#pragma once +/* + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_STD_REQUESTS_H +#define BLT_STD_REQUESTS_H + +#include + +namespace blt::requests +{ + + std::string send_get_request(const std::string& url); + +} + +#endif //BLT_STD_REQUESTS_H diff --git a/src/blt/std/requests.cpp b/src/blt/std/requests.cpp new file mode 100644 index 0000000..130e4d6 --- /dev/null +++ b/src/blt/std/requests.cpp @@ -0,0 +1,115 @@ +/* + * + * Copyright (C) 2025 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#if defined(__has_include) && __has_include() +#include +#define BLT_HAS_CURL +#endif + +namespace blt::requests +{ + #ifdef BLT_HAS_CURL + struct curl_init_t + { + curl_init_t() + { + const auto version_data = curl_version_info(CURLVERSION_NOW); + if (!(version_data->features & CURL_VERSION_THREADSAFE)) + { + thread_safe = false; + } + curl_global_init(CURL_GLOBAL_ALL); + } + + ~curl_init_t() + { + curl_global_cleanup(); + } + + bool thread_safe = true; + }; + + struct curl_easy_init_t + { + curl_easy_init_t(): curl(curl_easy_init()) + { + } + + ~curl_easy_init_t() + { + curl_easy_cleanup(curl); + } + + CURL* curl; + }; + + void init() + { + static curl_init_t curl_init_obj; + } + + CURL* easy_init() + { + thread_local curl_easy_init_t curl_easy_init_obj; + return curl_easy_init_obj.curl; + } + + size_t write_to_string_func(const void* data, const size_t size, const size_t nmemb, void* user_data) { + auto& str = *static_cast(user_data); + str.append(static_cast(data), size * nmemb); + return size * nmemb; + }; + #endif + + std::string send_get_request(const std::string& url) + { + #ifdef __EMSCRIPTEN__ + auto* str = static_cast(EM_ASM_PTR( + { const v = await fetch('$0', { 'credentials': 'omit', 'headers': { 'User-Agent': + 'Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0', 'Accept': '/', 'Accept-Language': 'en-US,en;q=0.5', + 'Priority': 'u=4' }, 'method': 'GET', 'mode': 'cors' }); if (!v.ok) { throw v.status; } return stringToNewUTF8(await response.text()); + }, url.c_str())); + std::string str_obj{str}; + free(str); + return str_obj; + #else + init(); + auto curl = easy_init(); + if (!curl) + throw std::runtime_error("Failed to initialize curl"); + std::string response_string; + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast(&response_string)); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_to_string_func); + + const auto res = curl_easy_perform(curl); + if(res != CURLE_OK) + throw std::runtime_error(curl_easy_strerror(res)); + + return response_string; + #endif + } +}