Bug fixes & cleanups

This commit is contained in:
2025-11-23 23:07:08 +01:00
parent 655289e542
commit 3c0aecb5f0
6 changed files with 69 additions and 54 deletions
+28 -20
View File
@@ -2590,16 +2590,9 @@ int socket_manager_wakeup(SocketManager *sm)
return ret; return ret;
} }
static int socket_manager_register_events_nolock( static void socket_manager_register_events_nolock(
SocketManager *sm, EventRegister *reg) SocketManager *sm, EventRegister *reg)
{ {
// The poll array must be able to hold descriptors
// for a socket manager at full capacity. Note that
// other than having a number of connection sockets,
// the manager also needs 2 for the listeners and
// one for the wakeup self-pipe.
if (reg->max_polled < sm->max_used+3)
return -1;
reg->num_polled = 0; reg->num_polled = 0;
reg->polled[reg->num_polled].fd = sm->wait_sock; reg->polled[reg->num_polled].fd = sm->wait_sock;
@@ -2644,7 +2637,7 @@ static int socket_manager_register_events_nolock(
// empty list. // empty list.
if (s->state == SOCKET_STATE_DIED || s->state == SOCKET_STATE_ESTABLISHED_READY) { if (s->state == SOCKET_STATE_DIED || s->state == SOCKET_STATE_ESTABLISHED_READY) {
reg->num_polled = 0; reg->num_polled = 0;
return 0; return;
} }
if (s->events) { if (s->events) {
@@ -2655,8 +2648,6 @@ static int socket_manager_register_events_nolock(
reg->num_polled++; reg->num_polled++;
} }
} }
return 0;
} }
int socket_manager_register_events(SocketManager *sm, int socket_manager_register_events(SocketManager *sm,
@@ -2665,11 +2656,11 @@ int socket_manager_register_events(SocketManager *sm,
if (mutex_lock(&sm->mutex) < 0) if (mutex_lock(&sm->mutex) < 0)
return -1; return -1;
int ret = socket_manager_register_events_nolock(sm, reg); socket_manager_register_events_nolock(sm, reg);
if (mutex_unlock(&sm->mutex) < 0) if (mutex_unlock(&sm->mutex) < 0)
return -1; return -1;
return ret; return 0;
} }
static SocketHandle static SocketHandle
@@ -2981,6 +2972,7 @@ int socket_connect(SocketManager *sm, int num_targets,
s->state = SOCKET_STATE_PENDING; s->state = SOCKET_STATE_PENDING;
s->sock = NATIVE_SOCKET_INVALID; s->sock = NATIVE_SOCKET_INVALID;
s->events = 0;
s->user = user; s->user = user;
#ifdef HTTPS_ENABLED #ifdef HTTPS_ENABLED
s->server_secure_context = NULL; s->server_secure_context = NULL;
@@ -3659,6 +3651,7 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// src/client.c // src/client.c
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
static void http_client_conn_free(HTTP_ClientConn *conn) static void http_client_conn_free(HTTP_ClientConn *conn)
{ {
byte_queue_free(&conn->output); byte_queue_free(&conn->output);
@@ -3879,19 +3872,31 @@ void http_request_builder_url(HTTP_RequestBuilder builder,
if (conn->state != HTTP_CLIENT_CONN_WAIT_LINE) if (conn->state != HTTP_CLIENT_CONN_WAIT_LINE)
return; // Request line already written return; // Request line already written
// Allocate a copy of the URL string so the parsed URL pointers remain valid // Allocate a copy of the URL string so the parsed
// URL pointers remain valid
char *url_copy = malloc(url.len); char *url_copy = malloc(url.len);
if (url_copy == NULL) if (url_copy == NULL) {
return; // TODO: set error conn->state = HTTP_CLIENT_CONN_COMPLETE;
conn->result = -1;
return;
}
memcpy(url_copy, url.ptr, url.len); memcpy(url_copy, url.ptr, url.len);
conn->url_buffer.ptr = url_copy; conn->url_buffer.ptr = url_copy;
conn->url_buffer.len = url.len; conn->url_buffer.len = url.len;
// Parse the copied URL (all url.* pointers will reference url_buffer) // Parse the copied URL (all url.* pointers will reference url_buffer)
if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) != 1) { if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) {
free(conn->url_buffer.ptr); conn->state = HTTP_CLIENT_CONN_COMPLETE;
return; // TODO: set error conn->result = -1;
return;
}
if (!http_streq(conn->url.scheme, HTTP_STR("http")) &&
!http_streq(conn->url.scheme, HTTP_STR("https"))) {
conn->state = HTTP_CLIENT_CONN_COMPLETE;
conn->result = -1;
return;
} }
// Write method // Write method
@@ -4031,6 +4036,9 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
if (conn == NULL) if (conn == NULL)
return -1; return -1;
if (conn->state == HTTP_CLIENT_CONN_COMPLETE)
goto error; // Early completion due to an error
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
// No body, just end headers // No body, just end headers
byte_queue_write(&conn->output, "\r\n", 2); byte_queue_write(&conn->output, "\r\n", 2);
@@ -4537,7 +4545,7 @@ http_server_conn_process_events(HTTP_Server *server, HTTP_ServerConn *conn)
byte_queue_write_ack(&conn->input, num); byte_queue_write_ack(&conn->input, num);
if (byte_queue_error(&conn->output)) { if (byte_queue_error(&conn->input)) {
socket_close(&server->sockets, conn->handle); socket_close(&server->sockets, conn->handle);
} else { } else {
check_request_buffer(server, conn); check_request_buffer(server, conn);
+5 -6
View File
@@ -824,6 +824,11 @@ int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
#define HTTP_CLIENT_CAPACITY (1<<7) #define HTTP_CLIENT_CAPACITY (1<<7)
#endif #endif
// Maximum number of descriptors the client will want
// to wait on. It's one per connection plus the wakeup
// self-pipe.
#define HTTP_CLIENT_POLL_CAPACITY (HTTP_CLIENT_CAPACITY+1)
#ifndef HTTP_COOKIE_JAR_CAPACITY #ifndef HTTP_COOKIE_JAR_CAPACITY
// Maximum number of cookies that can be associated to a // Maximum number of cookies that can be associated to a
// single client. // single client.
@@ -862,11 +867,6 @@ typedef struct {
HTTP_CookieJarEntry items[HTTP_COOKIE_JAR_CAPACITY]; HTTP_CookieJarEntry items[HTTP_COOKIE_JAR_CAPACITY];
} HTTP_CookieJar; } HTTP_CookieJar;
// Maximum number of descriptors the client will want
// to wait on. It's one per connection plus the wakeup
// self-pipe.
#define HTTP_CLIENT_POLL_CAPACITY (HTTP_CLIENT_CAPACITY+1)
typedef enum { typedef enum {
HTTP_CLIENT_CONN_FREE, HTTP_CLIENT_CONN_FREE,
HTTP_CLIENT_CONN_WAIT_LINE, HTTP_CLIENT_CONN_WAIT_LINE,
@@ -953,7 +953,6 @@ struct HTTP_Client {
// allocating the exact number of sockets we // allocating the exact number of sockets we
// will need. // will need.
Socket socket_pool[HTTP_CLIENT_CAPACITY]; Socket socket_pool[HTTP_CLIENT_CAPACITY];
}; };
// Initialize an HTTP client object. This allows one to // Initialize an HTTP client object. This allows one to
+6 -4
View File
@@ -14,6 +14,8 @@ int main(void)
HTTP_RequestBuilder builder = http_client_get_builder(&client); HTTP_RequestBuilder builder = http_client_get_builder(&client);
http_request_builder_set_trace_bytes(builder, true);
http_request_builder_url(builder, http_request_builder_url(builder,
HTTP_METHOD_GET, HTTP_METHOD_GET,
HTTP_STR("http://coz.is") HTTP_STR("http://coz.is")
@@ -27,14 +29,14 @@ int main(void)
for (;;) { for (;;) {
void *ptrs[HTTP_CLIENT_CAPACITY+1]; void *ptrs[HTTP_CLIENT_POLL_CAPACITY];
struct pollfd polled[HTTP_CLIENT_CAPACITY+1]; struct pollfd polled[HTTP_CLIENT_POLL_CAPACITY];
EventRegister reg = { EventRegister reg = {
.ptrs=ptrs, .ptrs=ptrs,
.polled=polled, .polled=polled,
.num_polled=0, .num_polled=0,
.max_polled=HTTP_CLIENT_CAPACITY+1, .max_polled=HTTP_CLIENT_POLL_CAPACITY,
}; };
if (http_client_register_events(&client, &reg) < 0) if (http_client_register_events(&client, &reg) < 0)
@@ -49,7 +51,7 @@ int main(void)
HTTP_Response *response; HTTP_Response *response;
void *user; void *user;
while (http_client_next_response(&client, &response, &user)) { while (http_client_next_response(&client, &response, &user)) {
// TODO printf("Received response\n");
http_free_response(response); http_free_response(response);
} }
} }
+22 -6
View File
@@ -1,3 +1,4 @@
static void http_client_conn_free(HTTP_ClientConn *conn) static void http_client_conn_free(HTTP_ClientConn *conn)
{ {
byte_queue_free(&conn->output); byte_queue_free(&conn->output);
@@ -218,19 +219,31 @@ void http_request_builder_url(HTTP_RequestBuilder builder,
if (conn->state != HTTP_CLIENT_CONN_WAIT_LINE) if (conn->state != HTTP_CLIENT_CONN_WAIT_LINE)
return; // Request line already written return; // Request line already written
// Allocate a copy of the URL string so the parsed URL pointers remain valid // Allocate a copy of the URL string so the parsed
// URL pointers remain valid
char *url_copy = malloc(url.len); char *url_copy = malloc(url.len);
if (url_copy == NULL) if (url_copy == NULL) {
return; // TODO: set error conn->state = HTTP_CLIENT_CONN_COMPLETE;
conn->result = -1;
return;
}
memcpy(url_copy, url.ptr, url.len); memcpy(url_copy, url.ptr, url.len);
conn->url_buffer.ptr = url_copy; conn->url_buffer.ptr = url_copy;
conn->url_buffer.len = url.len; conn->url_buffer.len = url.len;
// Parse the copied URL (all url.* pointers will reference url_buffer) // Parse the copied URL (all url.* pointers will reference url_buffer)
if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) != 1) { if (http_parse_url(conn->url_buffer.ptr, conn->url_buffer.len, &conn->url) < 0) {
free(conn->url_buffer.ptr); conn->state = HTTP_CLIENT_CONN_COMPLETE;
return; // TODO: set error conn->result = -1;
return;
}
if (!http_streq(conn->url.scheme, HTTP_STR("http")) &&
!http_streq(conn->url.scheme, HTTP_STR("https"))) {
conn->state = HTTP_CLIENT_CONN_COMPLETE;
conn->result = -1;
return;
} }
// Write method // Write method
@@ -370,6 +383,9 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
if (conn == NULL) if (conn == NULL)
return -1; return -1;
if (conn->state == HTTP_CLIENT_CONN_COMPLETE)
goto error; // Early completion due to an error
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) { if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
// No body, just end headers // No body, just end headers
byte_queue_write(&conn->output, "\r\n", 2); byte_queue_write(&conn->output, "\r\n", 2);
-1
View File
@@ -134,7 +134,6 @@ struct HTTP_Client {
// allocating the exact number of sockets we // allocating the exact number of sockets we
// will need. // will need.
Socket socket_pool[HTTP_CLIENT_CAPACITY]; Socket socket_pool[HTTP_CLIENT_CAPACITY];
}; };
// Initialize an HTTP client object. This allows one to // Initialize an HTTP client object. This allows one to
+4 -13
View File
@@ -620,16 +620,9 @@ int socket_manager_wakeup(SocketManager *sm)
return ret; return ret;
} }
static int socket_manager_register_events_nolock( static void socket_manager_register_events_nolock(
SocketManager *sm, EventRegister *reg) SocketManager *sm, EventRegister *reg)
{ {
// The poll array must be able to hold descriptors
// for a socket manager at full capacity. Note that
// other than having a number of connection sockets,
// the manager also needs 2 for the listeners and
// one for the wakeup self-pipe.
if (reg->max_polled < sm->max_used+3)
return -1;
reg->num_polled = 0; reg->num_polled = 0;
reg->polled[reg->num_polled].fd = sm->wait_sock; reg->polled[reg->num_polled].fd = sm->wait_sock;
@@ -674,7 +667,7 @@ static int socket_manager_register_events_nolock(
// empty list. // empty list.
if (s->state == SOCKET_STATE_DIED || s->state == SOCKET_STATE_ESTABLISHED_READY) { if (s->state == SOCKET_STATE_DIED || s->state == SOCKET_STATE_ESTABLISHED_READY) {
reg->num_polled = 0; reg->num_polled = 0;
return 0; return;
} }
if (s->events) { if (s->events) {
@@ -685,8 +678,6 @@ static int socket_manager_register_events_nolock(
reg->num_polled++; reg->num_polled++;
} }
} }
return 0;
} }
int socket_manager_register_events(SocketManager *sm, int socket_manager_register_events(SocketManager *sm,
@@ -695,11 +686,11 @@ int socket_manager_register_events(SocketManager *sm,
if (mutex_lock(&sm->mutex) < 0) if (mutex_lock(&sm->mutex) < 0)
return -1; return -1;
int ret = socket_manager_register_events_nolock(sm, reg); socket_manager_register_events_nolock(sm, reg);
if (mutex_unlock(&sm->mutex) < 0) if (mutex_unlock(&sm->mutex) < 0)
return -1; return -1;
return ret; return 0;
} }
static SocketHandle static SocketHandle