Fix windows compilation errors
This commit is contained in:
@@ -62,6 +62,27 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#define SOCKET_TYPE SOCKET
|
||||
#define BAD_SOCKET INVALID_SOCKET
|
||||
#define POLL WSAPoll
|
||||
#define CLOSE_SOCKET closesocket
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#define SOCKET_TYPE int
|
||||
#define BAD_SOCKET -1
|
||||
#define POLL poll
|
||||
#define CLOSE_SOCKET close
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HTTPS_ENABLED
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -100,7 +121,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
SocketState state;
|
||||
SocketWantEvent event;
|
||||
int fd;
|
||||
SOCKET_TYPE fd;
|
||||
#if HTTPS_ENABLED
|
||||
SSL *ssl;
|
||||
SSL_CTX *ssl_ctx;
|
||||
@@ -128,6 +149,9 @@ typedef struct {
|
||||
#endif
|
||||
} SocketGroup;
|
||||
|
||||
SOCKET_TYPE listen_socket(HTTP_String addr, uint16_t port, bool reuse_addr, int backlog);
|
||||
|
||||
|
||||
void socket_global_init (void);
|
||||
void socket_global_free (void);
|
||||
int socket_group_init (SocketGroup *group);
|
||||
@@ -135,7 +159,7 @@ int socket_group_init_server(SocketGroup *group, HTTP_String cert_file,
|
||||
int socket_group_add_domain(SocketGroup *group, HTTP_String domain, HTTP_String cert_key, HTTP_String private_key);
|
||||
void socket_group_free (SocketGroup *group);
|
||||
SocketState socket_state (Socket *sock);
|
||||
void socket_accept (Socket *sock, SocketGroup *group, int fd);
|
||||
void socket_accept (Socket *sock, SocketGroup *group, SOCKET_TYPE fd);
|
||||
void socket_connect (Socket *sock, SocketGroup *group, HTTP_String host, uint16_t port);
|
||||
void socket_connect_ipv4 (Socket *sock, SocketGroup *group, HTTP_IPv4 addr, uint16_t port);
|
||||
void socket_connect_ipv6 (Socket *sock, SocketGroup *group, HTTP_IPv6 addr, uint16_t port);
|
||||
@@ -2491,11 +2515,15 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define POLL WSAPoll
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <poll.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#define POLL poll
|
||||
#endif
|
||||
|
||||
#ifdef HTTPS_ENABLED
|
||||
@@ -2511,6 +2539,71 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
|
||||
#include "socket.h"
|
||||
#endif
|
||||
|
||||
static int set_socket_blocking(SOCKET_TYPE sock, bool value)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
u_long mode = !value;
|
||||
if (ioctlsocket(sock, FIONBIO, &mode) == SOCKET_ERROR)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
int flags = fcntl(listen_fd, F_GETFL, 0);
|
||||
if (flags < 0)
|
||||
return -1;
|
||||
if (fcntl(listen_fd, F_SETFL, flags | O_NONBLOCK) < 0)
|
||||
return BAD_SOCKET;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SOCKET_TYPE listen_socket(HTTP_String addr, uint16_t port, bool reuse_addr, int backlog)
|
||||
{
|
||||
SOCKET_TYPE listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listen_fd == BAD_SOCKET)
|
||||
return BAD_SOCKET;
|
||||
|
||||
if (set_socket_blocking(listen_fd, false) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return BAD_SOCKET;
|
||||
}
|
||||
|
||||
if (reuse_addr) {
|
||||
int one = 1;
|
||||
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &one, sizeof(one));
|
||||
}
|
||||
|
||||
struct in_addr addr_buf;
|
||||
if (addr.len == 0)
|
||||
addr_buf.s_addr = htonl(INADDR_ANY);
|
||||
else {
|
||||
|
||||
_Static_assert(sizeof(struct in_addr) == sizeof(HTTP_IPv4));
|
||||
if (http_parse_ipv4(addr.ptr, addr.len, (HTTP_IPv4*) &addr_buf) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return BAD_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in bind_buf;
|
||||
bind_buf.sin_family = AF_INET;
|
||||
bind_buf.sin_addr = addr_buf;
|
||||
bind_buf.sin_port = htons(port);
|
||||
if (bind(listen_fd, (struct sockaddr*) &bind_buf, sizeof(bind_buf)) < 0) { // TODO: how does bind fail on windows?
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return BAD_SOCKET;
|
||||
}
|
||||
|
||||
if (listen(listen_fd, backlog) < 0) { // TODO: how does listen fail on windows?
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return BAD_SOCKET;
|
||||
}
|
||||
|
||||
return listen_fd;
|
||||
}
|
||||
|
||||
|
||||
void socket_global_init(void)
|
||||
{
|
||||
#ifdef HTTPS_ENABLED
|
||||
@@ -2764,7 +2857,7 @@ SocketState socket_state(Socket *sock)
|
||||
return sock->state;
|
||||
}
|
||||
|
||||
void socket_accept(Socket *sock, SocketGroup *group, int fd)
|
||||
void socket_accept(Socket *sock, SocketGroup *group, SOCKET_TYPE fd)
|
||||
{
|
||||
#ifdef HTTPS_ENABLED
|
||||
sock->ssl = NULL;
|
||||
@@ -2785,13 +2878,12 @@ void socket_accept(Socket *sock, SocketGroup *group, int fd)
|
||||
sock->addr_cursor = 0;
|
||||
sock->hostname = NULL;
|
||||
sock->port = 0;
|
||||
|
||||
// Set non-blocking mode for the accepted socket
|
||||
int flags = fcntl(fd, F_GETFL, 0); // TODO: fail on error
|
||||
if (flags >= 0) {
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
if (set_socket_blocking(fd, false) < 0) {
|
||||
sock->state = SOCKET_STATE_DIED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Start the TLS handshake process
|
||||
socket_update(sock);
|
||||
}
|
||||
@@ -2946,8 +3038,8 @@ void socket_update(Socket *sock)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sock->fd != -1)
|
||||
close(sock->fd);
|
||||
if (sock->fd != BAD_SOCKET)
|
||||
CLOSE_SOCKET(sock->fd);
|
||||
|
||||
// If cursor reached the end, die
|
||||
if (sock->addr_cursor >= sock->addr_count) {
|
||||
@@ -2959,8 +3051,8 @@ void socket_update(Socket *sock)
|
||||
// Take current address
|
||||
AddrInfo *ai = &sock->addr_list[sock->addr_cursor];
|
||||
int family = ai->is_ipv6 ? AF_INET6 : AF_INET;
|
||||
int fd = socket(family, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
SOCKET_TYPE fd = socket(family, SOCK_STREAM, 0);
|
||||
if (fd == BAD_SOCKET) {
|
||||
// Try next address
|
||||
sock->addr_cursor++;
|
||||
sock->event = SOCKET_WANT_NONE;
|
||||
@@ -2969,9 +3061,12 @@ void socket_update(Socket *sock)
|
||||
break;
|
||||
}
|
||||
|
||||
// Set non-blocking
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
if (flags >= 0) fcntl(fd, F_SETFL, flags | O_NONBLOCK); // TODO: Handle error by setting the socket to DIED
|
||||
if (set_socket_blocking(fd, false) < 0) {
|
||||
CLOSE_SOCKET(fd);
|
||||
sock->event = SOCKET_WANT_NONE;
|
||||
sock->state = SOCKET_STATE_DIED;
|
||||
break;
|
||||
}
|
||||
|
||||
// Prepare sockaddr
|
||||
int ret;
|
||||
@@ -2998,7 +3093,7 @@ void socket_update(Socket *sock)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0 && errno == EINPROGRESS) {
|
||||
if (ret < 0 && errno == EINPROGRESS) { // TODO: I'm pretty sure all the error numbers need to be changed for windows
|
||||
// Connection pending
|
||||
sock->fd = fd;
|
||||
sock->event = SOCKET_WANT_WRITE;
|
||||
@@ -3025,7 +3120,7 @@ void socket_update(Socket *sock)
|
||||
// Check connect result
|
||||
int err = 0;
|
||||
socklen_t len = sizeof(err);
|
||||
if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0 || err != 0) {
|
||||
if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
|
||||
close(sock->fd);
|
||||
// If remote peer not working, try next address
|
||||
if (err == ECONNREFUSED || err == ETIMEDOUT || err == ENETUNREACH || err == EHOSTUNREACH) {
|
||||
@@ -3302,9 +3397,9 @@ void socket_free(Socket *sock)
|
||||
SSL_free(sock->ssl);
|
||||
#endif
|
||||
|
||||
if (sock->fd >= 0) {
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
if (sock->fd != BAD_SOCKET) {
|
||||
CLOSE_SOCKET(sock->fd);
|
||||
sock->fd = BAD_SOCKET;
|
||||
}
|
||||
|
||||
if (sock->hostname) {
|
||||
@@ -3344,7 +3439,7 @@ int socket_wait(Socket **socks, int num_socks) // TODO: is this used?
|
||||
polled[i].revents = 0;
|
||||
}
|
||||
|
||||
int ret = poll(polled, num_socks, -1);
|
||||
int ret = POLL(polled, num_socks, -1);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
@@ -3842,23 +3937,6 @@ HTTP_Response *http_post(HTTP_String url, HTTP_String *headers, int num_headers,
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#define POLL WSAPoll
|
||||
#define CLOSE_SOCKET closesocket
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#define POLL poll
|
||||
#define CLOSE_SOCKET close
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_AMALGAMATION
|
||||
#include "engine.h"
|
||||
#include "socket.h"
|
||||
@@ -3877,8 +3955,8 @@ typedef struct {
|
||||
struct HTTP_Server {
|
||||
SocketGroup group;
|
||||
|
||||
int listen_fd;
|
||||
int secure_fd;
|
||||
SOCKET_TYPE listen_fd;
|
||||
SOCKET_TYPE secure_fd;
|
||||
|
||||
int num_conns;
|
||||
Connection conns[MAX_CONNS];
|
||||
@@ -3888,59 +3966,6 @@ struct HTTP_Server {
|
||||
int ready[MAX_CONNS];
|
||||
};
|
||||
|
||||
static int listen_socket(HTTP_String addr, uint16_t port, bool reuse_addr, int backlog)
|
||||
{
|
||||
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listen_fd < 0)
|
||||
return -1;
|
||||
|
||||
{
|
||||
int flags = fcntl(listen_fd, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl(listen_fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (reuse_addr) {
|
||||
int one = 1;
|
||||
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
}
|
||||
|
||||
struct in_addr addr_buf;
|
||||
if (addr.len == 0)
|
||||
addr_buf.s_addr = htonl(INADDR_ANY);
|
||||
else {
|
||||
|
||||
_Static_assert(sizeof(struct in_addr) == sizeof(HTTP_IPv4));
|
||||
if (http_parse_ipv4(addr.ptr, addr.len, (HTTP_IPv4*) &addr_buf) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in bind_buf;
|
||||
bind_buf.sin_family = AF_INET;
|
||||
bind_buf.sin_addr = addr_buf;
|
||||
bind_buf.sin_port = htons(port);
|
||||
if (bind(listen_fd, (struct sockaddr*) &bind_buf, sizeof(bind_buf)) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(listen_fd, backlog) < 0) {
|
||||
CLOSE_SOCKET(listen_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return listen_fd;
|
||||
}
|
||||
|
||||
HTTP_Server *http_server_init(HTTP_String addr, uint16_t port)
|
||||
{
|
||||
return http_server_init_ex(addr, port, 0, HTTP_STR(""), HTTP_STR(""));
|
||||
@@ -3963,17 +3988,17 @@ HTTP_Server *http_server_init_ex(HTTP_String addr, uint16_t port,
|
||||
}
|
||||
|
||||
if (port == 0)
|
||||
server->listen_fd = -1;
|
||||
server->listen_fd = BAD_SOCKET;
|
||||
else {
|
||||
server->listen_fd = listen_socket(addr, port, reuse_addr, backlog);
|
||||
if (server->listen_fd < 0) {
|
||||
if (server->listen_fd == BAD_SOCKET) {
|
||||
free(server);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (secure_port == 0)
|
||||
server->secure_fd = -1;
|
||||
server->secure_fd = BAD_SOCKET;
|
||||
else {
|
||||
|
||||
if (socket_group_init_server(&server->group, cert_key, private_key) < 0) {
|
||||
@@ -3983,7 +4008,7 @@ HTTP_Server *http_server_init_ex(HTTP_String addr, uint16_t port,
|
||||
}
|
||||
|
||||
server->secure_fd = listen_socket(addr, secure_port, reuse_addr, backlog);
|
||||
if (server->secure_fd < 0) {
|
||||
if (server->secure_fd == BAD_SOCKET) {
|
||||
socket_group_free(&server->group);
|
||||
CLOSE_SOCKET(server->listen_fd);
|
||||
free(server);
|
||||
@@ -4016,7 +4041,7 @@ void http_server_free(HTTP_Server *server)
|
||||
|
||||
CLOSE_SOCKET(server->secure_fd);
|
||||
CLOSE_SOCKET(server->listen_fd);
|
||||
if (server->secure_fd != -1)
|
||||
if (server->secure_fd != BAD_SOCKET)
|
||||
socket_group_free(&server->group);
|
||||
free(server);
|
||||
}
|
||||
@@ -4048,7 +4073,7 @@ int http_server_wait(HTTP_Server *server, HTTP_Request **req, HTTP_ResponseHandl
|
||||
|
||||
if (server->num_conns < MAX_CONNS) {
|
||||
|
||||
if (server->listen_fd != -1) {
|
||||
if (server->listen_fd != BAD_SOCKET) {
|
||||
polled[num_polled].fd = server->listen_fd;
|
||||
polled[num_polled].events = POLLIN;
|
||||
polled[num_polled].revents = 0;
|
||||
@@ -4056,7 +4081,7 @@ int http_server_wait(HTTP_Server *server, HTTP_Request **req, HTTP_ResponseHandl
|
||||
num_polled++;
|
||||
}
|
||||
|
||||
if (server->secure_fd != -1) {
|
||||
if (server->secure_fd != BAD_SOCKET) {
|
||||
polled[num_polled].fd = server->secure_fd;
|
||||
polled[num_polled].events = POLLIN;
|
||||
polled[num_polled].revents = 0;
|
||||
@@ -4102,7 +4127,10 @@ int http_server_wait(HTTP_Server *server, HTTP_Request **req, HTTP_ResponseHandl
|
||||
|
||||
if ((polled[i].revents & POLLIN) && server->num_conns < MAX_CONNS) {
|
||||
|
||||
int new_fd = accept(polled[i].fd, NULL, NULL);
|
||||
SOCKET_TYPE new_fd = accept(polled[i].fd, NULL, NULL);
|
||||
if (new_fd == BAD_SOCKET) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int k = 0;
|
||||
while (server->conns[k].used)
|
||||
@@ -4211,16 +4239,13 @@ void http_response_status(HTTP_ResponseHandle res, int status)
|
||||
http_engine_status(&conn->engine, status);
|
||||
}
|
||||
|
||||
void http_response_header(HTTP_ResponseHandle res, const char *fmt, ...)
|
||||
void http_response_header(HTTP_ResponseHandle res, HTTP_String str)
|
||||
{
|
||||
Connection *conn = handle2conn(res);
|
||||
if (conn == NULL)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
http_engine_header_fmt2(&conn->engine, fmt, args);
|
||||
va_end(args);
|
||||
http_engine_header(&conn->engine, str);
|
||||
}
|
||||
|
||||
void http_response_body(HTTP_ResponseHandle res, HTTP_String str)
|
||||
|
||||
Reference in New Issue
Block a user