mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Networking: support nowait connection (Posix)
Thread was used for now. It's possible to do nonblocking connect & send with io_uring on Linux, but it requires newer kernel and linking to liburing. I don't think it is worth the effort.
This commit is contained in:
+10
-3
@@ -3,6 +3,7 @@
|
||||
#ifndef FF_INCLUDED_common_networking
|
||||
#define FF_INCLUDED_common_networking
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -11,10 +12,16 @@
|
||||
|
||||
typedef struct FFNetworkingState {
|
||||
#ifdef _WIN32
|
||||
uintptr_t sockfd;
|
||||
OVERLAPPED overlapped;
|
||||
uintptr_t sockfd;
|
||||
OVERLAPPED overlapped;
|
||||
#else
|
||||
int sockfd;
|
||||
int sockfd;
|
||||
FFstrbuf host;
|
||||
FFstrbuf command;
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
FFThreadType thread;
|
||||
#endif
|
||||
#endif
|
||||
} FFNetworkingState;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
static void connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
@@ -15,47 +15,73 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return false;
|
||||
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
|
||||
goto error;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
FFstrbuf command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(state->sockfd, command.chars, command.length, 0) < 0)
|
||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
close(state->sockfd);
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return true;
|
||||
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
state->sockfd = -1;
|
||||
|
||||
exit:
|
||||
ffStrbufDestroy(&state->host);
|
||||
ffStrbufDestroy(&state->command);
|
||||
}
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
ffStrbufInitS(&state->host, host);
|
||||
|
||||
ffStrbufInitA(&state->command, 64);
|
||||
ffStrbufAppendS(&state->command, "GET ");
|
||||
ffStrbufAppendS(&state->command, path);
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&state->command, host);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
ffStrbufAppendS(&state->command, headers);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||
return state->thread != NULL;
|
||||
#else
|
||||
connectAndSend(state);
|
||||
return state->sockfd != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
ffThreadJoin(state->thread);
|
||||
#endif
|
||||
if(state->sockfd == -1)
|
||||
return false;
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
|
||||
Reference in New Issue
Block a user