diff options
Diffstat (limited to 'freenect-server--http.c')
-rw-r--r-- | freenect-server--http.c | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/freenect-server--http.c b/freenect-server--http.c deleted file mode 100644 index cda7ae1..0000000 --- a/freenect-server--http.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright 2016 Luke Shumaker */ - -#include <error.h> -#include <errno.h> -#include <netdb.h> /* for {get,free}addrinfo() */ -#include <stdlib.h> /* for EXIT_FAILURE */ -#include <sys/socket.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/stat.h> /* for open */ -#include <fcntl.h> /* for open */ - -#include "util.h" -#include "mpjpeg.h" - -struct httpfile { - char name[256]; - struct mpjpeg_stream *stream; -}; - -size_t filec = 0; -struct httpfile *filev = NULL; - -struct reader_thread_args { - struct mpjpeg_stream *stream; - int fd; - const char *boundary; -}; - -void *reader_thread(void *args_anon) { - struct reader_thread_args *args = args_anon; - mpjpeg_reader(args->stream, args->fd, args->boundary); - error(EXIT_FAILURE, 0, "mpjpeg stream ended"); - return NULL; -} - -void start_mpjpeg_reader(struct mpjpeg_stream *s, int fd, const char *boundary) { - struct reader_thread_args *args = xrealloc(NULL, sizeof(struct reader_thread_args)); - args->stream = s; - args->fd = fd; - args->boundary = boundary; - pthread_t thread; - pthread_create(&thread, NULL, reader_thread, args); -} - -void file_add(const char *filename) { - struct mpjpeg_stream *stream = xrealloc(NULL, sizeof(struct mpjpeg_stream)); - init_mpjpeg_stream(stream); - int fd = open(filename, O_RDONLY); - if (fd < 0) - error(EXIT_FAILURE, errno, "opening file: %s", filename); - filev = xrealloc(filev, (++filec)*sizeof(*filev)); - const char *shortname = strrchr(filename, '/'); - if (shortname == NULL) - shortname = filename; - strncpy(filev[filec-1].name, shortname, sizeof(filev[filec-1].name)); - error(0, 0, "added file #%zd: %s", filec-1, filev[filec-1].name); - filev[filec-1].stream = stream; - start_mpjpeg_reader(stream, fd, "ffserver" /* FIXME */); -} - -struct mpjpeg_stream *file_get(const char *filename) { - for (size_t i = 0; i < filec; i++) { - if (strncmp(filename, filev[i].name, sizeof(filev[i].name)) == 0) { - return filev[i].stream; - } - } - return NULL; -} - -int tcp4_parse_listen(const char *port) { - int r; - struct addrinfo *addr = NULL; - struct addrinfo hints = { 0 }; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - - if ((r = getaddrinfo(NULL, port, &hints, &addr)) != 0) - error(EXIT_FAILURE, r, _("Could not resolve TCP4 port %s"), port); - - int sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (sock < 0) - error(EXIT_FAILURE, errno, _("Could not create a TCP4 socket")); - - int yes = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); - - if (bind(sock, addr->ai_addr, addr->ai_addrlen) < 0) - error(EXIT_FAILURE, errno, _("Could not bind to TCP4 port %s"), port); - - if (listen(sock, 5) < 0) - error(EXIT_FAILURE, errno, _("Could not listen on TCP4 port %s"), port); - - freeaddrinfo(addr); - return sock; -} - -void connection_handler(int fd) { - FILE *netstream = fdopen(fd, "r"); - char *line_buf = NULL; - size_t line_cap = 0; - ssize_t line_len = 0; - - line_len = getline(&line_buf, &line_cap, netstream); - /* expect line to be "GET /path.mjpg HTTP/1.1" */ - if (strncmp(line_buf, "GET ", 4) != 0) { - dprintf(fd, - "HTTP/1.1 405 Method Not Allowed\r\n" - "Allow: GET\r\n" - "\r\n"); - close(fd); - return; - } - char *version = &line_buf[4]; - char *path = strsep(&version, " "); - if (strcmp(version, "HTTP/1.1\r\n") != 0 && strcmp(version, "HTTP/1.0\r\n")) { - close(fd); - return; - } - path = strdupa(path); - - /* run through the rest of the headers */ - while (strcmp(line_buf, "\r\n") != 0 && line_len >= 0) - line_len = getline(&line_buf, &line_cap, netstream); - - struct mpjpeg_stream *vidstream = file_get(path); - if (vidstream == NULL) { - error(0, 0, "404 %s", path); - dprintf(fd, - "HTTP/1.1 404 Not Found\r\n" - "\r\n"); - return; - } - - const char *boundary = "boundary" /* FIXME */; - error(0, 0, "200 %s", path); - dprintf(fd, - "HTTP/1.1 200 OK\r\n" - "Content-Type: multipart/x-mixed-replace;boundary=%s\r\n" - "\r\n", - boundary); - mpjpeg_writer(vidstream, fd, boundary); - close(fd); -} - -void *connection_thread(void *arg_anon) { - int fd = (int)(intptr_t)arg_anon; - error(0, 0, "Connection %d opened", fd); - connection_handler(fd); - error(0, 0, "Connection %d closed", fd); - return NULL; -} - -void usage() { - printf("Usage: %s [-h] PORT [FILENAME...]\n", program_invocation_name); -} - -int main(int argc, char *argv[]) { - if (argc < 2) { - dup2(2, 1); - usage(); - return EXIT_FAILURE; - } - if (strcmp(argv[1], "-h") == 0) { - usage(); - return EXIT_SUCCESS; - } - int sock = tcp4_parse_listen(argv[1]); - - for (int i = 2; i < argc; i++) - file_add(argv[i]); - - signal(SIGPIPE, SIG_IGN); - while (1) { - int conn = accept(sock, NULL, NULL); - if (conn < 0) - continue; - pthread_t thread; - pthread_create(&thread, NULL, connection_thread, (void*)(intptr_t)conn); - } - - return 0; -} |