Add global state initialization functions

This commit is contained in:
2025-07-21 21:37:02 +02:00
parent a2912b5191
commit 58f8ace725
17 changed files with 242 additions and 94 deletions
+113 -37
View File
@@ -40,6 +40,9 @@ typedef struct {
#endif
void secure_context_global_init(void);
void secure_context_global_free(void);
int secure_context_init_as_client(SecureContext *sec);
int secure_context_init_as_server(SecureContext *sec,
@@ -86,6 +89,9 @@ void secure_context_free(SecureContext *sec);
#include "basic.h"
#endif
int socket_raw_global_init(void);
void socket_raw_global_free(void);
int set_socket_blocking(RAW_SOCKET sock, bool value);
RAW_SOCKET listen_socket(HTTP_String addr, uint16_t port, bool reuse_addr, int backlog);
@@ -204,6 +210,9 @@ typedef struct {
void *user_data;
} SocketEvent;
int socket_pool_global_init(void);
void socket_pool_global_free(void);
SocketPool *socket_pool_init(HTTP_String addr,
uint16_t port, uint16_t secure_port, int max_socks,
bool reuse_addr, int backlog, HTTP_String cert_file,
@@ -1371,24 +1380,6 @@ int http_parse_response(char *src, int len, HTTP_Response *res)
return ret;
}
HTTP_String http_getqueryparam(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
HTTP_String http_getbodyparam(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
HTTP_String http_getcookie(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
////////////////////////////////////////////////////////////////////////////////////////
// src/engine.c
////////////////////////////////////////////////////////////////////////////////////////
@@ -1474,12 +1465,6 @@ byte_queue_error(HTTP_ByteQueue *queue)
return queue->flags & BYTE_QUEUE_ERROR;
}
static void
byte_queue_setlimit(HTTP_ByteQueue *queue, unsigned int value)
{
queue->limit = value;
}
static int
byte_queue_empty(HTTP_ByteQueue *queue)
{
@@ -2572,6 +2557,14 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
#ifndef HTTPS_ENABLED
void secure_context_global_init(void)
{
}
void secure_context_global_free(void)
{
}
int secure_context_init_as_client(SecureContext *sec)
{
(void) sec;
@@ -2611,6 +2604,19 @@ void secure_context_free(SecureContext *sec)
#else
void secure_context_global_init(void)
{
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
void secure_context_global_free(void)
{
EVP_cleanup();
ERR_free_strings();
}
int secure_context_init_as_client(SecureContext *sec)
{
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
@@ -2792,6 +2798,24 @@ int secure_context_add_cert(SecureContext *sec,
#include "socket_raw.h"
#endif
int socket_raw_global_init(void)
{
#ifdef _WIN32
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
return 1;
#endif
return 0;
}
void socket_raw_global_free(void)
{
#ifdef _WIN32
WSACleanup();
#endif
}
int set_socket_blocking(RAW_SOCKET sock, bool value)
{
#ifdef _WIN32
@@ -2994,7 +3018,9 @@ void socket_connect(Socket *sock, SecureContext *sec,
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *res = NULL;
if (getaddrinfo(pending_connect->hostname, portstr, &hints, &res) != 0) {
int ret = getaddrinfo(pending_connect->hostname, portstr, &hints, &res);
if (ret != 0) {
printf("ret=%d\n", ret); // TODO: remove
pending_connect_free(pending_connect);
sock->state = SOCKET_STATE_DIED;
sock->events = 0;
@@ -3016,6 +3042,7 @@ void socket_connect(Socket *sock, SecureContext *sec,
sock->state = SOCKET_STATE_PENDING;
sock->events = 0;
sock->raw = BAD_SOCKET;
sock->user_data = user_data;
sock->pending_connect = pending_connect;
sock->sec = sec;
@@ -3266,7 +3293,7 @@ void socket_update(Socket *sock)
// ready for output. This means the operation is complete.
int err = 0;
int len = sizeof(err);
socklen_t len = sizeof(err);
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
@@ -3635,12 +3662,20 @@ struct SocketPool {
Socket socks[];
};
void socket_pool_global_init(void)
int socket_pool_global_init(void)
{
int ret = socket_raw_global_init();
if (ret < 0)
return -1;
secure_context_global_init();
return 0;
}
void socket_pool_global_free(void)
{
secure_context_global_free();
socket_raw_global_free();
}
SocketPool *socket_pool_init(HTTP_String addr,
@@ -3698,6 +3733,9 @@ SocketPool *socket_pool_init(HTTP_String addr,
#endif
}
for (int i = 0; i < max_socks; i++)
pool->socks[i].state = SOCKET_STATE_FREE;
return pool;
}
@@ -3969,6 +4007,7 @@ int socket_pool_write(SocketPool *pool, SocketHandle handle, char *src, int len)
typedef enum {
CLIENT_CONNECTION_FREE,
CLIENT_CONNECTION_INIT,
CLIENT_CONNECTION_INIT_ERROR,
CLIENT_CONNECTION_WAIT,
CLIENT_CONNECTION_DONE,
} ClientConnectionState;
@@ -3994,6 +4033,19 @@ struct HTTP_Client {
int ready[CLIENT_MAX_CONNS];
};
int http_global_init(void)
{
int ret = socket_pool_global_init();
if (ret < 0)
return -1;
return 0;
}
void http_global_free(void)
{
socket_pool_global_free();
}
// Rename the memory function
static void* client_memfunc(HTTP_MemoryFuncTag tag, void *ptr, int len, void *data) {
(void)data;
@@ -4057,6 +4109,7 @@ int http_client_get_builder(HTTP_Client *client, HTTP_RequestBuilder *builder)
while (client->conns[i].state != CLIENT_CONNECTION_FREE)
i++;
client->conns[i].sock = -1;
client->conns[i].user_data = NULL;
client->conns[i].trace = false;
client->conns[i].state = CLIENT_CONNECTION_INIT;
@@ -4078,6 +4131,8 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
case SOCKET_EVENT_DIED:
{
ClientConnection *conn = event.user_data;
conn->state = CLIENT_CONNECTION_DONE;
int tail = (client->ready_head + client->ready_count) % CLIENT_MAX_CONNS;
client->ready[tail] = conn - client->conns;
client->ready_count++;
@@ -4088,6 +4143,9 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
{
ClientConnection *conn = event.user_data;
if (conn->sock == -1)
conn->sock = event.handle;
HTTP_EngineState engine_state;
engine_state = http_engine_state(&conn->eng);
@@ -4147,6 +4205,8 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
http_engine_free(&conn->eng);
conn->state = CLIENT_CONNECTION_FREE;
client->num_conns--;
} else {
result2->context = client;
}
return 0;
@@ -4205,7 +4265,7 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
HTTP_URL parsed_url;
int ret = http_parse_url(url.ptr, url.len, &parsed_url);
if (ret != url.len) {
// TODO
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -4213,7 +4273,7 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
if (http_streq(parsed_url.scheme, HTTP_STR("https"))) {
secure = true;
} else if (!http_streq(parsed_url.scheme, HTTP_STR("http"))) {
// TODO
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -4226,12 +4286,14 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
}
switch (parsed_url.authority.host.mode) {
case HTTP_HOST_MODE_IPV4: socket_pool_connect_ipv4(client->socket_pool, secure, parsed_url.authority.host.ipv4, port, conn->user_data); break;
case HTTP_HOST_MODE_IPV6: socket_pool_connect_ipv6(client->socket_pool, secure, parsed_url.authority.host.ipv6, port, conn->user_data); break;
case HTTP_HOST_MODE_NAME: socket_pool_connect (client->socket_pool, secure, parsed_url.authority.host.name, port, conn->user_data); break;
case HTTP_HOST_MODE_IPV4: ret = socket_pool_connect_ipv4(client->socket_pool, secure, parsed_url.authority.host.ipv4, port, conn); break;
case HTTP_HOST_MODE_IPV6: ret = socket_pool_connect_ipv6(client->socket_pool, secure, parsed_url.authority.host.ipv6, port, conn); break;
case HTTP_HOST_MODE_NAME: ret = socket_pool_connect (client->socket_pool, secure, parsed_url.authority.host.name, port, conn); break;
case HTTP_HOST_MODE_VOID: ret = -1; return;
}
case HTTP_HOST_MODE_VOID:
// TODO
if (ret < 0) {
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -4262,20 +4324,34 @@ void http_request_builder_body(HTTP_RequestBuilder handle, HTTP_String str)
void http_request_builder_submit(HTTP_RequestBuilder handle)
{
HTTP_Client *client = handle.data0;
ClientConnection *conn = builder2conn(handle);
if (conn == NULL)
return;
if (conn->state != CLIENT_CONNECTION_INIT)
if (conn->state != CLIENT_CONNECTION_INIT &&
conn->state != CLIENT_CONNECTION_INIT_ERROR)
return;
// TODO: invalidate the handle
if (conn->state == CLIENT_CONNECTION_INIT_ERROR) {
conn->state = CLIENT_CONNECTION_DONE;
int tail = (client->ready_head + client->ready_count) % CLIENT_MAX_CONNS;
client->ready[tail] = conn - client->conns;
client->ready_count++;
} else {
http_engine_done(&conn->eng);
conn->state = CLIENT_CONNECTION_WAIT;
}
}
void http_response_free(HTTP_Client *client, HTTP_Response *res)
void http_response_free(HTTP_Response *res)
{
HTTP_Client *client = res->context;
ClientConnection *conn = NULL;
for (int i = 0, j = 0; j < client->num_conns; i++) {
@@ -4752,7 +4828,7 @@ void http_router_func(HTTP_Router *router, HTTP_Method method,
if (router->num_routes == router->max_routes)
abort();
Route *route = &router->routes[router->num_routes++];
// TODO: Don't ignore the method
(void) method; // TODO: Don't ignore the method
route->type = ROUTE_DYNAMIC;
route->endpoint = endpoint;
route->func = func;
+3 -5
View File
@@ -171,6 +171,7 @@ typedef struct {
} HTTP_Request;
typedef struct {
void* context;
int minor;
int status;
HTTP_String reason;
@@ -186,9 +187,6 @@ int http_parse_request (char *src, int len, HTTP_Request *req);
int http_parse_response (char *src, int len, HTTP_Response *res);
int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name);
HTTP_String http_getqueryparam (HTTP_Request *req, HTTP_String name);
HTTP_String http_getbodyparam (HTTP_Request *req, HTTP_String name);
HTTP_String http_getcookie (HTTP_Request *req, HTTP_String name);
#endif // PARSE_INCLUDED
@@ -370,7 +368,7 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
// cHTTP tries to avoid global state. What this function
// does is call the global initialization functions of
// its dependencies (OpenSSL and Winsock)
void http_global_init(void);
int http_global_init(void);
// Free the global state of cHTTP.
void http_global_free(void);
@@ -429,7 +427,7 @@ void http_request_builder_submit(HTTP_RequestBuilder builder);
// after the request has completed.
//
// TODO: allow aborting pending requests
void http_response_free(HTTP_Client *client, HTTP_Response *res);
void http_response_free(HTTP_Response *res);
// Wait for the completion of one request associated to
// the client. The handle of the resolved request is returned
+2 -2
View File
@@ -16,7 +16,7 @@ int main(void)
// Perform the request. This will block the thread
// until an error occurs or the request completes.
HTTP_Response *res = http_get(
HTTP_STR("http://example.com/index.html"),
HTTP_STR("http://coz.is/index.html"),
headers, HTTP_COUNT(headers)
);
@@ -45,7 +45,7 @@ int main(void)
// When we are done reading from the response object
// we must free the request's resources.
http_request_free(res);
http_response_free(res);
// All done. Deinitialize the library.
http_global_free();
+4 -4
View File
@@ -3,7 +3,8 @@
#include <string.h>
#include <chttp.h>
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
if (argc < 2) {
printf("Usage: %s <url1> [url2 ...]\n", argv[0]);
return 1;
@@ -13,13 +14,12 @@ int main(int argc, char **argv) {
HTTP_Client *client = http_client_init();
for (int i = 1; i < argc; i++) {
int k = i-1;
HTTP_RequestBuilder builder;
if (http_client_get_builder(client, &builder) < 0) {
printf("request creation error\n");
return -1;
}
http_request_builer_line(builder, HTTP_METHOD_GET, (HTTP_String) { argv[i], strlen(argv[i]) });
http_request_builder_line(builder, HTTP_METHOD_GET, (HTTP_String) { argv[i], strlen(argv[i]) });
http_request_builder_submit(builder);
printf("request submitted\n");
}
@@ -35,7 +35,7 @@ int main(int argc, char **argv) {
printf("Status: %d\n", res->status);
printf("Body: %.*s\n", HTTP_UNPACK(res->body));
http_request_free(res);
http_response_free(res);
}
http_client_free(client);
+47 -9
View File
@@ -25,6 +25,7 @@
typedef enum {
CLIENT_CONNECTION_FREE,
CLIENT_CONNECTION_INIT,
CLIENT_CONNECTION_INIT_ERROR,
CLIENT_CONNECTION_WAIT,
CLIENT_CONNECTION_DONE,
} ClientConnectionState;
@@ -50,6 +51,19 @@ struct HTTP_Client {
int ready[CLIENT_MAX_CONNS];
};
int http_global_init(void)
{
int ret = socket_pool_global_init();
if (ret < 0)
return -1;
return 0;
}
void http_global_free(void)
{
socket_pool_global_free();
}
// Rename the memory function
static void* client_memfunc(HTTP_MemoryFuncTag tag, void *ptr, int len, void *data) {
(void)data;
@@ -113,6 +127,7 @@ int http_client_get_builder(HTTP_Client *client, HTTP_RequestBuilder *builder)
while (client->conns[i].state != CLIENT_CONNECTION_FREE)
i++;
client->conns[i].sock = -1;
client->conns[i].user_data = NULL;
client->conns[i].trace = false;
client->conns[i].state = CLIENT_CONNECTION_INIT;
@@ -134,6 +149,8 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
case SOCKET_EVENT_DIED:
{
ClientConnection *conn = event.user_data;
conn->state = CLIENT_CONNECTION_DONE;
int tail = (client->ready_head + client->ready_count) % CLIENT_MAX_CONNS;
client->ready[tail] = conn - client->conns;
client->ready_count++;
@@ -144,6 +161,9 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
{
ClientConnection *conn = event.user_data;
if (conn->sock == -1)
conn->sock = event.handle;
HTTP_EngineState engine_state;
engine_state = http_engine_state(&conn->eng);
@@ -203,6 +223,8 @@ int http_client_wait(HTTP_Client *client, HTTP_Response **result, void **user_da
http_engine_free(&conn->eng);
conn->state = CLIENT_CONNECTION_FREE;
client->num_conns--;
} else {
result2->context = client;
}
return 0;
@@ -261,7 +283,7 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
HTTP_URL parsed_url;
int ret = http_parse_url(url.ptr, url.len, &parsed_url);
if (ret != url.len) {
// TODO
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -269,7 +291,7 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
if (http_streq(parsed_url.scheme, HTTP_STR("https"))) {
secure = true;
} else if (!http_streq(parsed_url.scheme, HTTP_STR("http"))) {
// TODO
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -282,12 +304,14 @@ void http_request_builder_line(HTTP_RequestBuilder builder, HTTP_Method method,
}
switch (parsed_url.authority.host.mode) {
case HTTP_HOST_MODE_IPV4: socket_pool_connect_ipv4(client->socket_pool, secure, parsed_url.authority.host.ipv4, port, conn->user_data); break;
case HTTP_HOST_MODE_IPV6: socket_pool_connect_ipv6(client->socket_pool, secure, parsed_url.authority.host.ipv6, port, conn->user_data); break;
case HTTP_HOST_MODE_NAME: socket_pool_connect (client->socket_pool, secure, parsed_url.authority.host.name, port, conn->user_data); break;
case HTTP_HOST_MODE_IPV4: ret = socket_pool_connect_ipv4(client->socket_pool, secure, parsed_url.authority.host.ipv4, port, conn); break;
case HTTP_HOST_MODE_IPV6: ret = socket_pool_connect_ipv6(client->socket_pool, secure, parsed_url.authority.host.ipv6, port, conn); break;
case HTTP_HOST_MODE_NAME: ret = socket_pool_connect (client->socket_pool, secure, parsed_url.authority.host.name, port, conn); break;
case HTTP_HOST_MODE_VOID: ret = -1; return;
}
case HTTP_HOST_MODE_VOID:
// TODO
if (ret < 0) {
conn->state = CLIENT_CONNECTION_INIT_ERROR;
return;
}
@@ -318,20 +342,34 @@ void http_request_builder_body(HTTP_RequestBuilder handle, HTTP_String str)
void http_request_builder_submit(HTTP_RequestBuilder handle)
{
HTTP_Client *client = handle.data0;
ClientConnection *conn = builder2conn(handle);
if (conn == NULL)
return;
if (conn->state != CLIENT_CONNECTION_INIT)
if (conn->state != CLIENT_CONNECTION_INIT &&
conn->state != CLIENT_CONNECTION_INIT_ERROR)
return;
// TODO: invalidate the handle
if (conn->state == CLIENT_CONNECTION_INIT_ERROR) {
conn->state = CLIENT_CONNECTION_DONE;
int tail = (client->ready_head + client->ready_count) % CLIENT_MAX_CONNS;
client->ready[tail] = conn - client->conns;
client->ready_count++;
} else {
http_engine_done(&conn->eng);
conn->state = CLIENT_CONNECTION_WAIT;
}
}
void http_response_free(HTTP_Client *client, HTTP_Response *res)
void http_response_free(HTTP_Response *res)
{
HTTP_Client *client = res->context;
ClientConnection *conn = NULL;
for (int i = 0, j = 0; j < client->num_conns; i++) {
+2 -2
View File
@@ -12,7 +12,7 @@
// cHTTP tries to avoid global state. What this function
// does is call the global initialization functions of
// its dependencies (OpenSSL and Winsock)
void http_global_init(void);
int http_global_init(void);
// Free the global state of cHTTP.
void http_global_free(void);
@@ -71,7 +71,7 @@ void http_request_builder_submit(HTTP_RequestBuilder builder);
// after the request has completed.
//
// TODO: allow aborting pending requests
void http_response_free(HTTP_Client *client, HTTP_Response *res);
void http_response_free(HTTP_Response *res);
// Wait for the completion of one request associated to
// the client. The handle of the resolved request is returned
-6
View File
@@ -78,12 +78,6 @@ byte_queue_error(HTTP_ByteQueue *queue)
return queue->flags & BYTE_QUEUE_ERROR;
}
static void
byte_queue_setlimit(HTTP_ByteQueue *queue, unsigned int value)
{
queue->limit = value;
}
static int
byte_queue_empty(HTTP_ByteQueue *queue)
{
-18
View File
@@ -1020,21 +1020,3 @@ int http_parse_response(char *src, int len, HTTP_Response *res)
return s.cur;
return ret;
}
HTTP_String http_getqueryparam(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
HTTP_String http_getbodyparam(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
HTTP_String http_getcookie(HTTP_Request *req, HTTP_String name)
{
// TODO
return (HTTP_String) {NULL, 0};
}
+1 -3
View File
@@ -74,6 +74,7 @@ typedef struct {
} HTTP_Request;
typedef struct {
void* context;
int minor;
int status;
HTTP_String reason;
@@ -89,8 +90,5 @@ int http_parse_request (char *src, int len, HTTP_Request *req);
int http_parse_response (char *src, int len, HTTP_Response *res);
int http_find_header (HTTP_Header *headers, int num_headers, HTTP_String name);
HTTP_String http_getqueryparam (HTTP_Request *req, HTTP_String name);
HTTP_String http_getbodyparam (HTTP_Request *req, HTTP_String name);
HTTP_String http_getcookie (HTTP_Request *req, HTTP_String name);
#endif // PARSE_INCLUDED
+1 -1
View File
@@ -79,7 +79,7 @@ void http_router_func(HTTP_Router *router, HTTP_Method method,
if (router->num_routes == router->max_routes)
abort();
Route *route = &router->routes[router->num_routes++];
// TODO: Don't ignore the method
(void) method; // TODO: Don't ignore the method
route->type = ROUTE_DYNAMIC;
route->endpoint = endpoint;
route->func = func;
+21
View File
@@ -4,6 +4,14 @@
#ifndef HTTPS_ENABLED
void secure_context_global_init(void)
{
}
void secure_context_global_free(void)
{
}
int secure_context_init_as_client(SecureContext *sec)
{
(void) sec;
@@ -43,6 +51,19 @@ void secure_context_free(SecureContext *sec)
#else
void secure_context_global_init(void)
{
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
void secure_context_global_free(void)
{
EVP_cleanup();
ERR_free_strings();
}
int secure_context_init_as_client(SecureContext *sec)
{
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
+3
View File
@@ -33,6 +33,9 @@ typedef struct {
#endif
void secure_context_global_init(void);
void secure_context_global_free(void);
int secure_context_init_as_client(SecureContext *sec);
int secure_context_init_as_server(SecureContext *sec,
+5 -2
View File
@@ -122,7 +122,9 @@ void socket_connect(Socket *sock, SecureContext *sec,
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *res = NULL;
if (getaddrinfo(pending_connect->hostname, portstr, &hints, &res) != 0) {
int ret = getaddrinfo(pending_connect->hostname, portstr, &hints, &res);
if (ret != 0) {
printf("ret=%d\n", ret); // TODO: remove
pending_connect_free(pending_connect);
sock->state = SOCKET_STATE_DIED;
sock->events = 0;
@@ -144,6 +146,7 @@ void socket_connect(Socket *sock, SecureContext *sec,
sock->state = SOCKET_STATE_PENDING;
sock->events = 0;
sock->raw = BAD_SOCKET;
sock->user_data = user_data;
sock->pending_connect = pending_connect;
sock->sec = sec;
@@ -394,7 +397,7 @@ void socket_update(Socket *sock)
// ready for output. This means the operation is complete.
int err = 0;
int len = sizeof(err);
socklen_t len = sizeof(err);
if (getsockopt(sock->raw, SOL_SOCKET, SO_ERROR, (void*) &err, &len) < 0 || err != 0) {
+12 -1
View File
@@ -25,12 +25,20 @@ struct SocketPool {
Socket socks[];
};
void socket_pool_global_init(void)
int socket_pool_global_init(void)
{
int ret = socket_raw_global_init();
if (ret < 0)
return -1;
secure_context_global_init();
return 0;
}
void socket_pool_global_free(void)
{
secure_context_global_free();
socket_raw_global_free();
}
SocketPool *socket_pool_init(HTTP_String addr,
@@ -88,6 +96,9 @@ SocketPool *socket_pool_init(HTTP_String addr,
#endif
}
for (int i = 0; i < max_socks; i++)
pool->socks[i].state = SOCKET_STATE_FREE;
return pool;
}
+3
View File
@@ -24,6 +24,9 @@ typedef struct {
void *user_data;
} SocketEvent;
int socket_pool_global_init(void);
void socket_pool_global_free(void);
SocketPool *socket_pool_init(HTTP_String addr,
uint16_t port, uint16_t secure_port, int max_socks,
bool reuse_addr, int backlog, HTTP_String cert_file,
+18
View File
@@ -14,6 +14,24 @@
#include "socket_raw.h"
#endif
int socket_raw_global_init(void)
{
#ifdef _WIN32
WSADATA wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
return 1;
#endif
return 0;
}
void socket_raw_global_free(void)
{
#ifdef _WIN32
WSACleanup();
#endif
}
int set_socket_blocking(RAW_SOCKET sock, bool value)
{
#ifdef _WIN32
+3
View File
@@ -25,6 +25,9 @@
#include "basic.h"
#endif
int socket_raw_global_init(void);
void socket_raw_global_free(void);
int set_socket_blocking(RAW_SOCKET sock, bool value);
RAW_SOCKET listen_socket(HTTP_String addr, uint16_t port, bool reuse_addr, int backlog);