Networking: support Windows

This commit is contained in:
李通洲
2022-10-12 19:35:23 +08:00
parent dfed3812ce
commit b64a234f8a
5 changed files with 65 additions and 24 deletions
+1
View File
@@ -516,6 +516,7 @@ elseif(MSYS)
PRIVATE "opengl32"
PRIVATE "gdi32"
PRIVATE "iphlpapi"
PRIVATE "ws2_32"
)
endif()
+48 -18
View File
@@ -1,13 +1,43 @@
#if defined(_WIN32) || defined(__MSYS__)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <synchapi.h>
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
{
(void)once;
(void)param;
static WSADATA wsaData;
*context = &wsaData;
return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
}
//Types of winsock2 are full of mess. Disable warnings for them and keep clean for posix
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#else
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#define closesocket close
#endif
//Must be included after <winsock2.h>
#include "fastfetch.h"
#include "common/networking.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
{
#if defined(_WIN32) || defined(__MSYS__)
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
WSADATA* pData;
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
return INVALID_SOCKET;
#endif
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
@@ -16,13 +46,13 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
struct addrinfo* addr;
if(getaddrinfo(host, "80", &hints, &addr) != 0)
return -1;
return INVALID_SOCKET;
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(sockfd == -1)
FFSockType sockfd = (FFSockType)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(sockfd == INVALID_SOCKET)
{
freeaddrinfo(addr);
return -1;
return INVALID_SOCKET;
}
if(timeout > 0)
@@ -35,9 +65,9 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
{
close(sockfd);
closesocket(sockfd);
freeaddrinfo(addr);
return -1;
return INVALID_SOCKET;
}
freeaddrinfo(addr);
@@ -55,14 +85,14 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
if(send(sockfd, command.chars, command.length, 0) == -1)
{
ffStrbufDestroy(&command);
close(sockfd);
return -1;
closesocket(sockfd);
return INVALID_SOCKET;
}
ffStrbufDestroy(&command);
return sockfd;
}
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer)
{
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
@@ -72,14 +102,14 @@ bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
buffer->chars[buffer->length] = '\0';
}
close(sockfd);
closesocket(sockfd);
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
}
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
{
int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
if(sockfd > 0)
FFSockType sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
if(sockfd != INVALID_SOCKET)
return ffNetworkingRecvHttpResponse(sockfd, buffer);
return false;
}
+12 -2
View File
@@ -5,8 +5,18 @@
#include "util/FFstrbuf.h"
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer);
#if defined(_WIN32) || defined(__MSYS__)
typedef uintptr_t FFSockType; //SOCKET, unsigned
#ifndef INVALID_SOCKET //Don't conflict with <winsock2.h>
#define INVALID_SOCKET ((uintptr_t)~0)
#endif
#else
typedef int FFSockType; // signed
#define INVALID_SOCKET (-1)
#endif
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer);
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
#endif
+2 -2
View File
@@ -5,7 +5,7 @@
#define FF_PUBLICIP_MODULE_NAME "Public IP"
#define FF_PUBLICIP_NUM_FORMAT_ARGS 1
static int sockfd;
static FFSockType sockfd;
void ffPreparePublicIp(FFinstance* instance)
{
@@ -39,7 +39,7 @@ void ffPrintPublicIp(FFinstance* instance)
if(sockfd == 0)
ffPreparePublicIp(instance);
if(sockfd < 0)
if(sockfd == INVALID_SOCKET)
{
ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server");
return;
+2 -2
View File
@@ -5,7 +5,7 @@
#define FF_WEATHER_MODULE_NAME "Weather"
#define FF_WEATHER_NUM_FORMAT_ARGS 1
static int sockfd;
static FFSockType sockfd;
void ffPrepareWeather(FFinstance* instance)
{
@@ -21,7 +21,7 @@ void ffPrintWeather(FFinstance* instance)
if(sockfd == 0)
ffPrepareWeather(instance);
if(sockfd < 0)
if(sockfd == INVALID_SOCKET)
{
ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'");
return;