threads in main.c, handling video

This commit is contained in:
Micah Moore 2022-12-07 19:10:50 -05:00
parent 6b84d45674
commit 45517a03cf
2 changed files with 91 additions and 7 deletions

View File

@ -19,6 +19,8 @@
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/limits.h> #include <linux/limits.h>
#include <dirent.h>
#include <jansson.h>
#include "http.h" #include "http.h"
#include "hexdump.h" #include "hexdump.h"
@ -376,6 +378,46 @@ static bool get_handle_login(struct http_transaction *ta) {
return send_response(ta); return send_response(ta);
} }
/* Lists the .mp4 files in the given directory in the proper format. */
static char *list_videos(DIR* dir) {
json_t *list = json_array();
struct dirent *file;
while ((file = readdir(dir)) != NULL) {
char *suffix = strrchr(file->d_name, '.');
if (suffix != NULL && !strcmp(suffix, ".mp4")) {
// stat the file
char fname[PATH_MAX];
struct stat st;
snprintf(fname, sizeof(fname), "%s/%s", server_root, file->d_name);
int rc = stat(fname, &st);
if (rc == -1)
perror("Could not list videos.");
// json components
json_t *entry = json_object();
json_t *size = json_integer(st.st_size);
json_t *name = json_string(file->d_name);
rc = json_object_set(entry, "size", size);
if (rc)
perror("JSON append failed.");
rc = json_object_set(entry, "name", name);
if (rc)
perror("JSON append failed.");
// add entry
rc = json_array_append_new(list, entry);
if (rc)
perror("JSON append failed.");
}
}
return json_dumps(list, 0);
}
static int val_api_url(struct http_transaction *ta) { static int val_api_url(struct http_transaction *ta) {
char *req_path = bufio_offset2ptr(ta->client->bufio, ta->req_path); char *req_path = bufio_offset2ptr(ta->client->bufio, ta->req_path);
if (!strcmp(req_path, "/api/login")) { if (!strcmp(req_path, "/api/login")) {
@ -413,7 +455,20 @@ handle_api(struct http_transaction *ta)
} }
else { else {
// Handle video api DIR* dir = opendir(server_root);
char *json = list_videos(dir);
fprintf(stderr, "json: %s\n", json);
http_add_header(&ta->resp_headers, "Content-Type", "application/json");
char *body = buffer_ensure_capacity(&ta->resp_body, MAX_HEADER_LEN);
int len = snprintf(body, strlen(json) + 2, "%s\n", json);
int length = len > MAX_HEADER_LEN ? MAX_HEADER_LEN - 1 : len;
ta->resp_body.len += length;
ta->resp_status = HTTP_OK;
return send_response(ta);
} }
return false; return false;

View File

@ -9,6 +9,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <pthread.h>
#include "buffer.h" #include "buffer.h"
#include "hexdump.h" #include "hexdump.h"
#include "http.h" #include "http.h"
@ -34,6 +35,17 @@ int token_expiration_time = 24 * 60 * 60;
// root from which static files are served // root from which static files are served
char * server_root; char * server_root;
static void *thr_func(void *c) {
struct http_client *client = c;
while (http_handle_transaction(client));
bufio_close(client->bufio);
return NULL;
}
/* /*
* A non-concurrent, iterative server that serves one client at a time. * A non-concurrent, iterative server that serves one client at a time.
* For each client, it handles exactly 1 HTTP transaction. * For each client, it handles exactly 1 HTTP transaction.
@ -41,18 +53,35 @@ char * server_root;
static void static void
server_loop(char *port_string) server_loop(char *port_string)
{ {
int max_clients = 16;
int num_clients = 0;
pthread_t *threads = malloc(max_clients * sizeof(pthread_t));
int accepting_socket = socket_open_bind_listen(port_string, 10000); int accepting_socket = socket_open_bind_listen(port_string, 10000);
while (accepting_socket != -1) { while (accepting_socket != -1) {
fprintf(stderr, "Waiting for client...\n"); fprintf(stderr, "Waiting for client...\n");
int client_socket = socket_accept_client(accepting_socket); int client_socket = socket_accept_client(accepting_socket);
if (client_socket == -1)
return;
struct http_client client; if (client_socket == -1){
http_setup_client(&client, bufio_create(client_socket)); return;
http_handle_transaction(&client);
bufio_close(client.bufio);
} }
struct http_client *client = malloc(sizeof(struct http_client));
http_setup_client(client, bufio_create(client_socket));
int rc = pthread_create(&threads[num_clients++], NULL, thr_func, client);
if (rc) {
perror(NULL);
} else if (num_clients >= max_clients) {
max_clients *= 2;
threads = realloc(threads, max_clients * sizeof(pthread_t));
}
}
for (int i = 0; i < num_clients; i++) {
pthread_join(threads[i], NULL);
}
} }
static void static void