init upl
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
#include "hygate.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
static config_t g_cfg;
|
||||
static sem_t g_conn_sem;
|
||||
|
||||
static void *worker(void *arg) {
|
||||
int fd = (int)(intptr_t)arg;
|
||||
handle_connection(fd, &g_cfg);
|
||||
close(fd);
|
||||
sem_post(&g_conn_sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
config_t cfg;
|
||||
cfg.port = DEFAULT_PORT;
|
||||
cfg.endpoint = DEFAULT_ENDPOINT;
|
||||
cfg.model = DEFAULT_MODEL;
|
||||
cfg.user_agent = "";
|
||||
cfg.max_body_bytes = (long)MAX_BODY_BYTES;
|
||||
cfg.max_connections = MAX_CONCURRENT_THREADS;
|
||||
|
||||
/* Simple flag parsing: -key value or -key=value */
|
||||
for (int i = 1; i < argc; i++) {
|
||||
char *a = argv[i];
|
||||
char *val = NULL;
|
||||
if (a[0] == '-') {
|
||||
char *eq = strchr(a, '=');
|
||||
if (eq) {
|
||||
*eq = 0;
|
||||
val = eq + 1;
|
||||
} else if (i + 1 < argc) {
|
||||
val = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
if (strcmp(a, "-port") == 0) cfg.port = val;
|
||||
else if (strcmp(a, "-endpoint") == 0) cfg.endpoint = val;
|
||||
else if (strcmp(a, "-model") == 0) cfg.model = val;
|
||||
else if (strcmp(a, "-user-agent") == 0) cfg.user_agent = val;
|
||||
else if (strcmp(a, "-ua") == 0) cfg.user_agent = val;
|
||||
else if (strcmp(a, "-max-body") == 0) {
|
||||
if (val) {
|
||||
long v = (long)strtoul(val, NULL, 10);
|
||||
if (v > 0) cfg.max_body_bytes = v;
|
||||
}
|
||||
} else if (strcmp(a, "-max-conn") == 0) {
|
||||
if (val) {
|
||||
int v = atoi(val);
|
||||
if (v > 0) cfg.max_connections = v;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "unknown flag: %s\n", a);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_cfg = cfg;
|
||||
|
||||
if (sem_init(&g_conn_sem, 0, (unsigned int)cfg.max_connections) != 0) {
|
||||
perror("sem_init");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
int srv = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (srv < 0) { perror("socket"); return 1; }
|
||||
int one = 1;
|
||||
setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons((uint16_t)atoi(cfg.port));
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(srv, (struct sockaddr *)&addr, sizeof addr) < 0) { perror("bind"); return 1; }
|
||||
if (listen(srv, 128) < 0) { perror("listen"); return 1; }
|
||||
|
||||
printf("hygate starting on port %s...\n", cfg.port);
|
||||
printf("Target Endpoint: %s\n", cfg.endpoint);
|
||||
printf("Model Name: %s\n", cfg.model);
|
||||
printf("User-Agent: %s\n", cfg.user_agent && cfg.user_agent[0] ? cfg.user_agent : DEFAULT_UA);
|
||||
printf("Max request body: %ld bytes\n", cfg.max_body_bytes);
|
||||
printf("Max concurrent connections: %d\n", cfg.max_connections);
|
||||
printf("Endpoints:\n");
|
||||
printf(" GET http://localhost:%s/v1/models\n", cfg.port);
|
||||
printf(" POST http://localhost:%s/v1/chat/completions\n", cfg.port);
|
||||
|
||||
for (;;) {
|
||||
/* Wait for a free worker slot before accepting, so the number of
|
||||
in-flight connections (and thus worker threads) is capped at
|
||||
cfg.max_connections. Excess connections queue in the kernel
|
||||
listen backlog. */
|
||||
while (sem_wait(&g_conn_sem) != 0) {
|
||||
if (errno == EINTR) continue;
|
||||
perror("sem_wait");
|
||||
break;
|
||||
}
|
||||
int cfd = accept(srv, NULL, NULL);
|
||||
if (cfd < 0) {
|
||||
if (errno == EINTR) { sem_post(&g_conn_sem); continue; }
|
||||
perror("accept");
|
||||
sem_post(&g_conn_sem);
|
||||
continue;
|
||||
}
|
||||
pthread_t tid;
|
||||
if (pthread_create(&tid, NULL, worker, (void *)(intptr_t)cfd) == 0) {
|
||||
pthread_detach(tid);
|
||||
} else {
|
||||
handle_connection(cfd, &g_cfg);
|
||||
close(cfd);
|
||||
sem_post(&g_conn_sem);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user