mirror of
https://github.com/abraunegg/onedrive
synced 2026-03-14 14:35:46 +01:00
Update PR
* Add libcurl check for websocket support
This commit is contained in:
parent
403daca4e7
commit
803c9d3cbd
3 changed files with 100 additions and 0 deletions
|
|
@ -144,6 +144,10 @@ class ApplicationConfig {
|
|||
bool fullScanTrueUpRequired = false;
|
||||
bool suppressLoggingOutput = false;
|
||||
|
||||
// WebSocket Operations
|
||||
bool curlSupportsWebSockets = false;
|
||||
bool websocketsSupportCheckDone = false;
|
||||
|
||||
// Default number of concurrent threads when downloading and uploading data
|
||||
ulong defaultConcurrentThreads = 8;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ import std.stdio;
|
|||
import std.range;
|
||||
import core.memory;
|
||||
import core.sys.posix.signal;
|
||||
// Required for WebSocket Support
|
||||
import core.stdc.stdlib : getenv;
|
||||
import core.stdc.string : strcmp;
|
||||
import core.sys.posix.dlfcn : dlopen, dlsym, dlclose, RTLD_NOW; // Posix elements
|
||||
|
||||
// What other modules that we have created do we need to import?
|
||||
import log;
|
||||
|
|
@ -21,11 +25,83 @@ import util;
|
|||
// Shared pool of CurlEngine instances accessible across all threads
|
||||
__gshared CurlEngine[] curlEnginePool; // __gshared is used to declare a variable that is shared across all threads
|
||||
|
||||
// WebSocket elements
|
||||
enum CURL_WS_MIN_NUM = 0x075600; // 7.86.0 (version which WebSocket support was added to cURL)
|
||||
// Flags (mirror curl/curl.h)
|
||||
enum CURLWS_TEXT = 0x01u;
|
||||
enum CURLWS_BINARY = 0x02u;
|
||||
enum CURLWS_CONT = 0x10u;
|
||||
enum CURLWS_CLOSE = 0x20u;
|
||||
enum CURLWS_PING = 0x40u;
|
||||
enum CURLWS_PONG = 0x80u;
|
||||
|
||||
extern (C) void sigpipeHandler(int signum) {
|
||||
// Custom handler to ignore SIGPIPE signals
|
||||
addLogEntry("ERROR: Handling a cURL SIGPIPE signal despite CURLOPT_NOSIGNAL being set (cURL Operational Bug) ...");
|
||||
}
|
||||
|
||||
// Function pointer types matching libcurl WebSocket (WS) API
|
||||
extern(C) struct curl_ws_frame {
|
||||
uint age;
|
||||
uint flags;
|
||||
size_t len;
|
||||
size_t offset;
|
||||
size_t bytesleft;
|
||||
}
|
||||
|
||||
// WebSocket alias
|
||||
alias PFN_curl_ws_recv =
|
||||
extern(C) CURLcode function(CURL*, void*, size_t, size_t*, const curl_ws_frame**);
|
||||
alias PFN_curl_ws_send =
|
||||
extern(C) CURLcode function(CURL*, const void*, size_t, size_t*, long /*curl_off_t*/, uint);
|
||||
|
||||
private __gshared {
|
||||
void* _curlLib;
|
||||
PFN_curl_ws_recv p_curl_ws_recv;
|
||||
PFN_curl_ws_send p_curl_ws_send;
|
||||
bool _wsSymbolsReady;
|
||||
uint _wsProbeOnce; // 0=not run, 1=success, 2=fail
|
||||
}
|
||||
|
||||
private void* loadCurlLib() {
|
||||
// Respect LD_LIBRARY_PATH etc.
|
||||
auto h = dlopen("libcurl.so.4", RTLD_NOW);
|
||||
if (h is null) h = dlopen("libcurl.so", RTLD_NOW);
|
||||
return h;
|
||||
}
|
||||
|
||||
private void* findSymbol(const(char)* name) {
|
||||
return dlsym(_curlLib, name);
|
||||
}
|
||||
|
||||
private bool probeCurlWsSymbols() {
|
||||
if (_wsProbeOnce == 1) return _wsSymbolsReady;
|
||||
if (_wsProbeOnce == 2) return false;
|
||||
|
||||
// 1) libcurl version check
|
||||
auto vi = curl_version_info(CURLVERSION_NOW);
|
||||
if (vi is null || vi.version_num < CURL_WS_MIN_NUM) {
|
||||
_wsProbeOnce = 2; _wsSymbolsReady = false; return false;
|
||||
}
|
||||
|
||||
// 2) load libcurl and resolve symbols
|
||||
_curlLib = loadCurlLib();
|
||||
if (_curlLib is null) {
|
||||
_wsProbeOnce = 2; _wsSymbolsReady = false; return false;
|
||||
}
|
||||
|
||||
p_curl_ws_recv = cast(PFN_curl_ws_recv) findSymbol("curl_ws_recv");
|
||||
p_curl_ws_send = cast(PFN_curl_ws_send) findSymbol("curl_ws_send");
|
||||
|
||||
_wsSymbolsReady = (p_curl_ws_recv !is null) && (p_curl_ws_send !is null);
|
||||
_wsProbeOnce = _wsSymbolsReady ? 1 : 2;
|
||||
return _wsSymbolsReady;
|
||||
}
|
||||
|
||||
bool curlSupportsWebSockets() {
|
||||
return probeCurlWsSymbols();
|
||||
}
|
||||
|
||||
class CurlResponse {
|
||||
HTTP.Method method;
|
||||
const(char)[] url;
|
||||
|
|
|
|||
|
|
@ -144,6 +144,26 @@ class OneDriveApi {
|
|||
if (curlEngine is null) {
|
||||
curlEngine = getCurlInstance();
|
||||
curlEngine.initialise(appConfig.getValueLong("dns_timeout"), appConfig.getValueLong("connect_timeout"), appConfig.getValueLong("data_timeout"), appConfig.getValueLong("operation_timeout"), appConfig.defaultMaxRedirects, appConfig.getValueBool("debug_https"), appConfig.getValueString("user_agent"), appConfig.getValueBool("force_http_11"), appConfig.getValueLong("rate_limit"), appConfig.getValueLong("ip_protocol_version"), appConfig.getValueLong("max_curl_idle"), keepAlive);
|
||||
|
||||
// WebSocket capability available in OS cURL version
|
||||
if (!appConfig.websocketsSupportCheckDone) {
|
||||
// Check the underlying cURL capability to support websockets
|
||||
if (debugLogging) {addLogEntry("Checking cURL Websocket support ...", ["debug"]);}
|
||||
bool websocketSupport = curlSupportsWebSockets();
|
||||
if (debugLogging) {addLogEntry("Checked cURL Websocket support = " ~ to!string(websocketSupport), ["debug"]);}
|
||||
|
||||
// Update appConfig flags
|
||||
appConfig.curlSupportsWebSockets = websocketSupport;
|
||||
appConfig.websocketsSupportCheckDone = true;
|
||||
|
||||
// Notify user if cURL vesion is too old to support websockets
|
||||
if (!websocketSupport) {
|
||||
addLogEntry();
|
||||
addLogEntry("WARNING: Your libcurl is too old for WebSocket support. Please upgrade to libcurl 7.86.0 or newer.");
|
||||
addLogEntry(" The near real-time processing of online changes cannot be enabled on your system.");
|
||||
addLogEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Authorised value to return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue