summaryrefslogtreecommitdiff
path: root/freenect-server--http.c
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-03-15 17:47:59 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-03-15 17:47:59 -0400
commit116c393eb5a770988bf1abf0be8f24d0e29748b1 (patch)
treed28786975421e96dba2d276d61188002394346b3 /freenect-server--http.c
parent9853745525fc736a4a0323588437b77120b1fcb6 (diff)
http server: don't assume multipart/x-mixed-replace streams are JPEGs
Diffstat (limited to 'freenect-server--http.c')
-rw-r--r--freenect-server--http.c184
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;
-}