mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 10:52:08 +02:00
Networking: report detailed error messages; support --thread false for debugging
This commit is contained in:
+2
-10
@@ -22,13 +22,5 @@ typedef struct FFNetworkingState {
|
||||
#endif
|
||||
} FFNetworkingState;
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
|
||||
|
||||
static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
FFNetworkingState state;
|
||||
if(ffNetworkingSendHttpRequest(&state, host, path, headers))
|
||||
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
|
||||
return false;
|
||||
}
|
||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
|
||||
|
||||
@@ -6,22 +6,25 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
static void connectAndSend(FFNetworkingState* state)
|
||||
static const char* connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
const char* ret = NULL;
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
|
||||
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
}, &addr) != 0)
|
||||
{
|
||||
ret = "getaddrinfo() failed";
|
||||
goto error;
|
||||
}
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
ret = "socket() failed";
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -29,6 +32,7 @@ static void connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
close(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
ret = "connect() failed";
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -37,6 +41,7 @@ static void connectAndSend(FFNetworkingState* state)
|
||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||
{
|
||||
close(state->sockfd);
|
||||
ret = "send() failed";
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -48,11 +53,13 @@ error:
|
||||
exit:
|
||||
ffStrbufDestroy(&state->host);
|
||||
ffStrbufDestroy(&state->command);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
ffStrbufInitS(&state->host, host);
|
||||
|
||||
@@ -66,22 +73,28 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
if (instance.config.general.multithreading)
|
||||
{
|
||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||
return !!state->thread;
|
||||
#else
|
||||
connectAndSend(state);
|
||||
return state->sockfd != -1;
|
||||
return state->thread ? NULL : "ffThreadCreate(connectAndSend) failed";
|
||||
}
|
||||
#endif
|
||||
|
||||
return connectAndSend(state);
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
if (instance.config.general.multithreading)
|
||||
{
|
||||
if (!ffThreadJoin(state->thread, timeout))
|
||||
return false;
|
||||
return "ffThreadJoin() failed or timeout";
|
||||
}
|
||||
#endif
|
||||
|
||||
if(state->sockfd == -1)
|
||||
return false;
|
||||
return "ffNetworkingSendHttpRequest() failed";
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
@@ -100,5 +113,5 @@ bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, ui
|
||||
}
|
||||
|
||||
close(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "publicip.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
|
||||
static FFNetworkingState state;
|
||||
static int status = -1;
|
||||
static const char* status = FF_UNITIALIZED;
|
||||
|
||||
void ffPreparePublicIp(FFPublicIpOptions* options)
|
||||
{
|
||||
if (status != -1)
|
||||
if (status != FF_UNITIALIZED)
|
||||
{
|
||||
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
|
||||
exit(1);
|
||||
@@ -41,18 +42,21 @@ static inline void wrapYyjsonFree(yyjson_doc** doc)
|
||||
|
||||
const char* ffDetectPublicIp(FFPublicIpOptions* options, FFPublicIpResult* result)
|
||||
{
|
||||
if (status == -1)
|
||||
if (status == FF_UNITIALIZED)
|
||||
ffPreparePublicIp(options);
|
||||
|
||||
if (status == 0)
|
||||
return "Failed to connect to an IP detection server";
|
||||
if (status != NULL)
|
||||
return status;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY response = ffStrbufCreateA(4096);
|
||||
bool success = ffNetworkingRecvHttpResponse(&state, &response, options->timeout);
|
||||
if (success) ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
|
||||
const char* error = ffNetworkingRecvHttpResponse(&state, &response, options->timeout);
|
||||
if (error == NULL)
|
||||
ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
|
||||
else
|
||||
return error;
|
||||
|
||||
if (!success || response.length == 0)
|
||||
return "Failed to receive the server response";
|
||||
if (response.length == 0)
|
||||
return "Empty server response received";
|
||||
|
||||
if (options->url.length == 0)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "weather.h"
|
||||
|
||||
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
|
||||
static FFNetworkingState state;
|
||||
static int status = -1;
|
||||
static const char* status = FF_UNITIALIZED;
|
||||
|
||||
void ffPrepareWeather(FFWeatherOptions* options)
|
||||
{
|
||||
if (status != -1)
|
||||
if (status != FF_UNITIALIZED)
|
||||
{
|
||||
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
|
||||
exit(1);
|
||||
@@ -21,22 +22,24 @@ void ffPrepareWeather(FFWeatherOptions* options)
|
||||
|
||||
const char* ffDetectWeather(FFWeatherOptions* options, FFstrbuf* result)
|
||||
{
|
||||
if(status == -1)
|
||||
if(status == FF_UNITIALIZED)
|
||||
ffPrepareWeather(options);
|
||||
|
||||
if(status == 0)
|
||||
return "Failed to connect to 'wttr.in'";
|
||||
if(status != NULL)
|
||||
return status;
|
||||
|
||||
ffStrbufEnsureFree(result, 4095);
|
||||
bool success = ffNetworkingRecvHttpResponse(&state, result, options->timeout);
|
||||
if (success)
|
||||
const char* error = ffNetworkingRecvHttpResponse(&state, result, options->timeout);
|
||||
if (error == NULL)
|
||||
{
|
||||
ffStrbufSubstrAfterFirstS(result, "\r\n\r\n");
|
||||
ffStrbufTrimRightSpace(result);
|
||||
}
|
||||
else
|
||||
return error;
|
||||
|
||||
if(!success || result->length == 0)
|
||||
return "Failed to receive the server response";
|
||||
if(result->length == 0)
|
||||
return "Empty server response received";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user