This commit deletes the complete implementation of the agent loop, authentication module, web browsing utilities, chat prompt builder, database helper, and HTTP client. All corresponding header files and test harnesses are also removed. The diff shows the deletion of 6 source files and 6 header files totaling over 1000 lines of code, including the agent state machine, API key resolution logic, curl-based HTTP functions, SQLite database initialization and CRUD operations, and the JSON chat prompt construction.
165 lines
4.8 KiB
C
165 lines
4.8 KiB
C
#include "http.h"
|
|
#include <curl/curl.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct http_client_t {
|
|
CURL *curl;
|
|
char *base_url;
|
|
char *bearer_token;
|
|
long timeout;
|
|
long connect_timeout;
|
|
};
|
|
|
|
static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
|
|
size_t total_size = size * nmemb;
|
|
struct {
|
|
char *data;
|
|
size_t size;
|
|
} *buffer = userp;
|
|
|
|
char *ptr = realloc(buffer->data, buffer->size + total_size + 1);
|
|
if (!ptr) return 0;
|
|
|
|
buffer->data = ptr;
|
|
memcpy(&(buffer->data[buffer->size]), contents, total_size);
|
|
buffer->size += total_size;
|
|
buffer->data[buffer->size] = '\0';
|
|
|
|
return total_size;
|
|
}
|
|
|
|
http_client_handle http_create(const char *base_url) {
|
|
struct http_client_t *client = calloc(1, sizeof(struct http_client_t));
|
|
if (!client) return NULL;
|
|
|
|
client->curl = curl_easy_init();
|
|
if (!client->curl) {
|
|
free(client);
|
|
return NULL;
|
|
}
|
|
|
|
client->base_url = base_url ? strdup(base_url) : NULL;
|
|
client->bearer_token = NULL;
|
|
client->timeout = 0;
|
|
client->connect_timeout = 0;
|
|
|
|
curl_easy_setopt(client->curl, CURLOPT_WRITEFUNCTION, write_callback);
|
|
|
|
return client;
|
|
}
|
|
|
|
void http_destroy(http_client_handle client) {
|
|
if (!client) return;
|
|
|
|
if (client->curl) curl_easy_cleanup(client->curl);
|
|
if (client->base_url) free(client->base_url);
|
|
if (client->bearer_token) free(client->bearer_token);
|
|
free(client);
|
|
}
|
|
|
|
void http_set_bearer_token(http_client_handle client, const char *token) {
|
|
if (!client) return;
|
|
|
|
if (client->bearer_token) free(client->bearer_token);
|
|
client->bearer_token = token ? strdup(token) : NULL;
|
|
}
|
|
|
|
void http_set_timeout(http_client_handle client, long timeout_seconds) {
|
|
if (!client) return;
|
|
client->timeout = timeout_seconds;
|
|
}
|
|
|
|
void http_set_connect_timeout(http_client_handle client, long timeout_seconds) {
|
|
if (!client) return;
|
|
client->connect_timeout = timeout_seconds;
|
|
}
|
|
|
|
static const char *method_string(http_method_t method) {
|
|
switch (method) {
|
|
case HTTP_METHOD_GET: return "GET";
|
|
case HTTP_METHOD_POST: return "POST";
|
|
case HTTP_METHOD_PUT: return "PUT";
|
|
case HTTP_METHOD_DELETE: return "DELETE";
|
|
default: return "GET";
|
|
}
|
|
}
|
|
|
|
r_status_t http_request(http_client_handle client, http_method_t method,
|
|
const char *path, const void *body, size_t body_size,
|
|
char **response, int *response_code) {
|
|
if (!client || !client->curl) return R_ERROR_INVALID_ARG;
|
|
|
|
struct {
|
|
char *data;
|
|
size_t size;
|
|
} buffer = {NULL, 0};
|
|
|
|
curl_easy_setopt(client->curl, CURLOPT_WRITEDATA, &buffer);
|
|
|
|
char url[4096];
|
|
if (client->base_url) {
|
|
snprintf(url, sizeof(url), "%s%s", client->base_url, path);
|
|
} else {
|
|
strncpy(url, path, sizeof(url) - 1);
|
|
url[sizeof(url) - 1] = '\0';
|
|
}
|
|
|
|
curl_easy_setopt(client->curl, CURLOPT_URL, url);
|
|
curl_easy_setopt(client->curl, CURLOPT_CUSTOMREQUEST, method_string(method));
|
|
|
|
if (client->bearer_token) {
|
|
char auth_header[512];
|
|
snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", client->bearer_token);
|
|
struct curl_slist *headers = NULL;
|
|
headers = curl_slist_append(headers, auth_header);
|
|
curl_easy_setopt(client->curl, CURLOPT_HTTPHEADER, headers);
|
|
}
|
|
|
|
if (client->timeout > 0) {
|
|
curl_easy_setopt(client->curl, CURLOPT_TIMEOUT, client->timeout);
|
|
}
|
|
if (client->connect_timeout > 0) {
|
|
curl_easy_setopt(client->curl, CURLOPT_CONNECTTIMEOUT, client->connect_timeout);
|
|
}
|
|
|
|
if (body && body_size > 0) {
|
|
curl_easy_setopt(client->curl, CURLOPT_POSTFIELDSIZE, (long)body_size);
|
|
curl_easy_setopt(client->curl, CURLOPT_POSTFIELDS, body);
|
|
}
|
|
|
|
CURLcode res = curl_easy_perform(client->curl);
|
|
|
|
if (res != CURLE_OK) {
|
|
if (buffer.data) free(buffer.data);
|
|
return R_ERROR_HTTP_CONNECTION;
|
|
}
|
|
|
|
long code;
|
|
curl_easy_getinfo(client->curl, CURLINFO_RESPONSE_CODE, &code);
|
|
if (response_code) *response_code = (int)code;
|
|
|
|
if (response) {
|
|
*response = buffer.data ? buffer.data : strdup("");
|
|
} else {
|
|
if (buffer.data) free(buffer.data);
|
|
}
|
|
|
|
return R_SUCCESS;
|
|
}
|
|
|
|
r_status_t http_get(http_client_handle client, const char *path, char **response) {
|
|
int code;
|
|
return http_request(client, HTTP_METHOD_GET, path, NULL, 0, response, &code);
|
|
}
|
|
|
|
r_status_t http_post(http_client_handle client, const char *path, const char *body, char **response) {
|
|
int code;
|
|
size_t body_size = body ? strlen(body) : 0;
|
|
return http_request(client, HTTP_METHOD_POST, path, body, body_size, response, &code);
|
|
}
|
|
|
|
r_status_t http_post_json(http_client_handle client, const char *path, const char *json, char **response) {
|
|
return http_post(client, path, json, response);
|
|
}
|