diff options
Diffstat (limited to 'mpjpeg.c')
-rw-r--r-- | mpjpeg.c | 43 |
1 files changed, 30 insertions, 13 deletions
@@ -4,12 +4,11 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <error.h> #include "mpjpeg.h" #include "util.h" -#define STARTS_WITH(str, prefix) strncmp(str, prefix, sizeof(prefix)-1) - static char *boundary_line(const char *old) { size_t len = strlen(old); @@ -23,6 +22,21 @@ char *boundary_line(const char *old) { return new; } +static +ssize_t safe_atoi(char *str) { + while (*str == ' ') + str++; + size_t len = 0; + while ('0' <= str[len] && str[len] <= '9') + len++; + size_t i = len; + while (str[i] == ' ') + i++; + if (len < 1 || strcmp(&str[i], "\r\n") != 0) + return -1; + return atoi(str); +} + void mpjpeg_reader(struct mpjpeg_stream *s, int fd, const char *boundary) { FILE *stream = fdopen(fd, "r"); boundary = boundary_line(boundary); @@ -32,30 +46,33 @@ void mpjpeg_reader(struct mpjpeg_stream *s, int fd, const char *boundary) { ssize_t line_len = 0; while (1) { - printf("getting frame\n"); s->back->len = -1; /* read the frame header (MIME headers) */ - line_len = getline(&line_buf, &line_cap, stream); - if (strcmp(line_buf, boundary) != 0) + do { + line_len = getline(&line_buf, &line_cap, stream); + } while (line_len >= 0 && strcmp(line_buf, "\r\n") == 0); + if (strcmp(line_buf, boundary) != 0) { + error(0, 0, "line does not match boundary: \"%s\"", line_buf); return; - ssize_t framelen = -1; + } while (strcmp(line_buf, "\r\n") != 0 && line_len >= 0) { line_len = getline(&line_buf, &line_cap, stream); - if (STARTS_WITH(line_buf, "Content-Type:") == 0) { - printf("line: <%s>\n", line_buf); - s->back->len = atoi(&line_buf[strlen("Content-Type:")]); + if (strncasecmp(line_buf, "Content-length:", strlen("Content-length:")) == 0) { + s->back->len = safe_atoi(&line_buf[strlen("Content-length:")]); } } - if (s->back->len < 0) + if (s->back->len < 0) { + error(0, 0, "did not get frame length"); return; + } /* read the frame contents (JPEG) */ if (s->back->cap < (size_t)s->back->len) s->back->data = xrealloc(s->back->data, s->back->cap = s->back->len); - if (fread(line_buf, framelen, 1, stream) != 1) + if (fread(s->back->data, s->back->len, 1, stream) != 1) { + error(0, ferror(stream), "fread(%zd)", s->back->len); return; - - printf("got frame on fd %d\n", fd); + } /* swap the frames */ pthread_mutex_lock(&s->frontlock); |