[vlc-commits] HTTP chunked transfer encoding "decoder"
Rémi Denis-Courmont
git at videolan.org
Wed Dec 16 21:31:19 CET 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Dec 14 23:11:53 2015 +0200| [6ce7b4500c038a53a5f570a3cbacb6b3ffd4cad4] | committer: Rémi Denis-Courmont
HTTP chunked transfer encoding "decoder"
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6ce7b4500c038a53a5f570a3cbacb6b3ffd4cad4
---
modules/access/http/Makefile.am | 1 +
modules/access/http/chunked.c | 160 +++++++++++++++++++++++++++++++++++++++
modules/access/http/h1conn.h | 25 ++++++
3 files changed, 186 insertions(+)
diff --git a/modules/access/http/Makefile.am b/modules/access/http/Makefile.am
index 35f0020..e2628af 100644
--- a/modules/access/http/Makefile.am
+++ b/modules/access/http/Makefile.am
@@ -10,6 +10,7 @@ libvlc_http_la_SOURCES = \
access/http/h2frame.c access/http/h2frame.h \
access/http/h2output.c access/http/h2output.h \
access/http/h2conn.c access/http/h2conn.h \
+ access/http/h1conn.h access/http/chunked.c \
access/http/connmgr.c access/http/connmgr.h
libvlc_http_la_CPPFLAGS = -Dneedsomethinghere
libvlc_http_la_LIBADD = \
diff --git a/modules/access/http/chunked.c b/modules/access/http/chunked.c
new file mode 100644
index 0000000..d7ed54c
--- /dev/null
+++ b/modules/access/http/chunked.c
@@ -0,0 +1,160 @@
+/*****************************************************************************
+ * chunked.c: HTTP 1.1 chunked encoding
+ *****************************************************************************
+ * Copyright © 2015 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vlc_common.h>
+#include <vlc_block.h>
+#include <vlc_tls.h> /* FIXME: remove this and test */
+
+#include "message.h"
+#include "transport.h"
+#include "h1conn.h"
+
+struct vlc_chunked_stream
+{
+ struct vlc_http_stream stream;
+ struct vlc_http_stream *parent;
+ struct vlc_tls *tls;
+ uintmax_t chunk_length;
+ bool eof;
+ bool error;
+};
+
+static_assert(offsetof(struct vlc_chunked_stream, stream) == 0, "Cast error");
+
+static void *vlc_chunked_fatal(struct vlc_chunked_stream *s)
+{
+ assert(!s->error);
+ s->error = true;
+ return NULL;
+}
+
+static struct vlc_http_msg *vlc_chunked_wait(struct vlc_http_stream *stream)
+{
+ /* Request trailers are not supported so far.
+ * There cannot be headers during chunked encoding. */
+ (void) stream;
+ return NULL;
+}
+
+static block_t *vlc_chunked_read(struct vlc_http_stream *stream)
+{
+ struct vlc_chunked_stream *s = (struct vlc_chunked_stream *)stream;
+ block_t *block = NULL;
+
+ if (s->eof || s->error)
+ return NULL;
+
+ /* Read chunk size (hexadecimal length) */
+ if (s->chunk_length == 0)
+ { /* NOTE: This accepts LF in addition to CRLF. No big deal. */
+ char *line = vlc_tls_GetLine(s->tls);
+ if (line == NULL)
+ return vlc_chunked_fatal(s);
+
+ int end;
+
+ if (sscanf(line, "%jx%n", &s->chunk_length, &end) < 1
+ || (line[end] != '\0' && line[end] != ';' /* ignore extension(s) */))
+ s->chunk_length = UINTMAX_MAX;
+
+ free(line);
+
+ if (s->chunk_length == UINTMAX_MAX)
+ return vlc_chunked_fatal(s);
+ }
+
+ /* Read chunk data */
+ if (s->chunk_length > 0)
+ {
+ size_t size = 1536; /* arbitrary */
+ if (size > s->chunk_length)
+ size = s->chunk_length;
+
+ block = block_Alloc(size);
+ if (unlikely(block == NULL))
+ return NULL;
+
+ ssize_t val = vlc_tls_Read(s->tls, block->p_buffer, size, false);
+ if (val <= 0)
+ { /* Connection error (-) or unexpected end of connection (0) */
+ block_Release(block);
+ return vlc_chunked_fatal(s);
+ }
+
+ block->i_buffer = val;
+ s->chunk_length -= val;
+ }
+ else
+ s->eof = true;
+
+ /* Read chunk end (CRLF) */
+ if (s->chunk_length == 0)
+ {
+ char crlf[2];
+
+ if (vlc_https_recv(s->tls, crlf, 2) < 2 || memcmp(crlf, "\r\n", 2))
+ vlc_chunked_fatal(s);
+ }
+ return block;
+}
+
+static void vlc_chunked_close(struct vlc_http_stream *stream, bool abort)
+{
+ struct vlc_chunked_stream *s = (struct vlc_chunked_stream *)stream;
+
+ if (!s->eof) /* Abort connection if stream is closed before end */
+ vlc_chunked_fatal(s);
+
+ vlc_http_stream_close(s->parent, abort || s->error);
+ free(s);
+}
+
+static struct vlc_http_stream_cbs vlc_chunked_callbacks =
+{
+ vlc_chunked_wait,
+ vlc_chunked_read,
+ vlc_chunked_close,
+};
+
+struct vlc_http_stream *vlc_chunked_open(struct vlc_http_stream *parent,
+ struct vlc_tls *tls)
+{
+ struct vlc_chunked_stream *s = malloc(sizeof (*s));
+ if (unlikely(s == NULL))
+ return NULL;
+
+ s->stream.cbs = &vlc_chunked_callbacks;
+ s->parent = parent;
+ s->tls = tls;
+ s->chunk_length = 0;
+ s->eof = false;
+ s->error = false;
+ return &s->stream;
+}
diff --git a/modules/access/http/h1conn.h b/modules/access/http/h1conn.h
new file mode 100644
index 0000000..491a43b
--- /dev/null
+++ b/modules/access/http/h1conn.h
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * h1conn.h: HTTP 1.x connection handling
+ *****************************************************************************
+ * Copyright © 2015 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+struct vlc_http_stream;
+struct vlc_tls;
+
+struct vlc_http_stream *vlc_chunked_open(struct vlc_http_stream *,
+ struct vlc_tls *);
More information about the vlc-commits
mailing list