[vlc-commits] HTTP/2 over TLS access

Rémi Denis-Courmont git at videolan.org
Sun Dec 13 17:20:30 CET 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Dec  7 22:03:59 2015 +0200| [aa78e9d3e1e9c2ade56064d84eb62ab6d11deeba] | committer: Rémi Denis-Courmont

HTTP/2 over TLS access

This adds a new plugin for HTTPS supporting HTTP version 2.0
(IETF RFC 7540), and based on the latest version of HTTP protocol
semantics (IETF RFC7230-9 series).

It provides support for seeking in a single round trip time by
reusing the same TCP connection and TLS session. It could be further
extended to reusing connections over multiple access instances,
e.g. to support segmented streaming.

It also addresses a number of protocol bugs in the existing HTTP
stack, such as handling of HTTP 100, 201 and 416 codes. It also adds
automatic safe reconnection.

Currently, the old HTTP access is favored due to a few missing
features:
- HTTP 1.1 fallback - work in progress,
- proxies (i.e. HTTP CONNECT) - work in progress,
- authentication,
- cookies.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=aa78e9d3e1e9c2ade56064d84eb62ab6d11deeba
---

 modules/access/http/Makefile.am |   22 +++++
 modules/access/http/access.c    |  191 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 213 insertions(+)

diff --git a/modules/access/http/Makefile.am b/modules/access/http/Makefile.am
index 84f4446..35f0020 100644
--- a/modules/access/http/Makefile.am
+++ b/modules/access/http/Makefile.am
@@ -1,3 +1,25 @@
+libhttps_plugin_la_SOURCES = access/http/access.c
+libhttps_plugin_la_LIBADD = libvlc_http.la
+access_LTLIBRARIES += libhttps_plugin.la
+
+libvlc_http_la_SOURCES = \
+	access/http/transport.c access/http/transport.h \
+	access/http/message.c access/http/message.h \
+	access/http/file.c access/http/file.h \
+	access/http/hpack.c access/http/hpack.h access/http/hpackenc.c \
+	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/connmgr.c access/http/connmgr.h
+libvlc_http_la_CPPFLAGS = -Dneedsomethinghere
+libvlc_http_la_LIBADD = \
+	$(LTLIBVLCCORE) ../compat/libcompat.la \
+	$(SOCKET_LIBS) $(LIBPTHREAD)
+#libvlc_http_la_LDFLAGS = -no-undefined -export-symbols-regex ^vlc_http_
+#pkglib_LTLIBRARIES += libvlc_http.la
+libvlc_http_la_LDFLAGS = -static
+noinst_LTLIBRARIES += libvlc_http.la
+
 hpack_test_SOURCES = access/http/hpack.c access/http/hpack.h
 hpack_test_CFLAGS = -DDEC_TEST
 hpackenc_test_SOURCES = $(hpack_test_SOURCES) access/http/hpackenc.c
diff --git a/modules/access/http/access.c b/modules/access/http/access.c
new file mode 100644
index 0000000..77fb3fc
--- /dev/null
+++ b/modules/access/http/access.c
@@ -0,0 +1,191 @@
+/*****************************************************************************
+ * access.c: HTTP/TLS VLC access plug-in
+ *****************************************************************************
+ * 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 <stdint.h>
+
+#include <vlc_common.h>
+#include <vlc_access.h>
+#include <vlc_plugin.h>
+
+#include "connmgr.h"
+#include "file.h"
+
+struct access_sys_t
+{
+    struct vlc_http_mgr *manager;
+    struct vlc_http_file *file;
+};
+
+static block_t *Read(access_t *access)
+{
+    access_sys_t *sys = access->p_sys;
+
+    block_t *b = vlc_http_file_read(sys->file);
+    if (b == NULL)
+        access->info.b_eof = true;
+    return b;
+}
+
+static int Seek(access_t *access, uint64_t pos)
+{
+    access_sys_t *sys = access->p_sys;
+    access->info.b_eof = false;
+
+    if (vlc_http_file_seek(sys->file, pos))
+        return VLC_EGENERIC;
+    return VLC_SUCCESS;
+}
+
+static int Control(access_t *access, int query, va_list args)
+{
+    access_sys_t *sys = access->p_sys;
+
+    switch (query)
+    {
+        case ACCESS_CAN_SEEK:
+            *va_arg(args, bool *) = vlc_http_file_can_seek(sys->file);
+            break;
+
+        case ACCESS_CAN_FASTSEEK:
+            *va_arg(args, bool *) = false;
+            break;
+
+        case ACCESS_CAN_PAUSE:
+        case ACCESS_CAN_CONTROL_PACE:
+            *va_arg(args, bool *) = true;
+            break;
+
+        case ACCESS_GET_SIZE:
+        {
+            uintmax_t val = vlc_http_file_get_size(sys->file);
+            if (val >= UINT64_MAX)
+                return VLC_EGENERIC;
+
+            *va_arg(args, uint64_t *) = val;
+            break;
+        }
+
+        case ACCESS_GET_PTS_DELAY:
+            *va_arg(args, int64_t *) = var_InheritInteger(access,
+                                                          "network-caching");
+            break;
+
+        case ACCESS_GET_CONTENT_TYPE:
+            *va_arg(args, char **) = vlc_http_file_get_type(sys->file);
+            break;
+
+        case ACCESS_SET_PAUSE_STATE:
+            break;
+
+        default:
+            return VLC_EGENERIC;
+
+    }
+    return VLC_SUCCESS;
+}
+
+static int Open(vlc_object_t *obj)
+{
+    access_t *access = (access_t *)obj;
+    access_sys_t *sys = malloc(sizeof (*sys));
+    int ret = VLC_ENOMEM;
+
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    sys->manager = NULL;
+    sys->file = NULL;
+
+    sys->manager = vlc_http_mgr_create(obj);
+    if (sys->manager == NULL)
+        goto error;
+
+    char *ua = var_InheritString(obj, "http-user-agent");
+    char *ref = var_InheritString(obj, "http-referrer");
+
+    sys->file = vlc_http_file_create(sys->manager, access->psz_url, ua, ref);
+    free(ref);
+    free(ua);
+    if (sys->file == NULL)
+        goto error;
+
+    char *redir = vlc_http_file_get_redirect(sys->file);
+    if (redir != NULL)
+    {
+        access->psz_url = redir;
+        ret = VLC_ACCESS_REDIRECT;
+        goto error;
+    }
+
+    ret = VLC_EGENERIC;
+
+    int status = vlc_http_file_get_status(sys->file);
+    if (status < 0)
+    {
+        msg_Err(access, "HTTP connection failure");
+        goto error;
+    }
+    if (status >= 300)
+    {
+        msg_Err(access, "HTTP %d error", status);
+        goto error;
+    }
+
+    access->info.b_eof = false;
+    access->pf_read = NULL;
+    access->pf_block = Read;
+    access->pf_seek = Seek;
+    access->pf_control = Control;
+    access->p_sys = sys;
+    return VLC_SUCCESS;
+
+error:
+    if (sys->file != NULL)
+        vlc_http_file_destroy(sys->file);
+    if (sys->manager != NULL)
+        vlc_http_mgr_destroy(sys->manager);
+    free(sys);
+    return ret;
+}
+
+static void Close(vlc_object_t *obj)
+{
+    access_t *access = (access_t *)obj;
+    access_sys_t *sys = access->p_sys;
+
+    vlc_http_file_destroy(sys->file);
+    vlc_http_mgr_destroy(sys->manager);
+    free(sys);
+}
+
+vlc_module_begin()
+    set_description(N_("HTTP/TLS input"))
+    set_shortname(N_("HTTPS"))
+    set_category(CAT_INPUT)
+    set_subcategory(SUBCAT_INPUT_ACCESS)
+    set_capability("access", 0)
+    add_shortcut("https")
+    set_callbacks(Open, Close)
+vlc_module_end()



More information about the vlc-commits mailing list