[vlc-commits] https: partial tunnel test case

Rémi Denis-Courmont git at videolan.org
Tue Jan 5 17:11:19 CET 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jan  5 17:43:31 2016 +0200| [1674b861cbd5c092eb0c300c35849642e607894e] | committer: Rémi Denis-Courmont

https: partial tunnel test case

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

 modules/access/http/Makefile.am   |    6 +-
 modules/access/http/tunnel_test.c |  144 +++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/modules/access/http/Makefile.am b/modules/access/http/Makefile.am
index 18d5a0c..d447a42 100644
--- a/modules/access/http/Makefile.am
+++ b/modules/access/http/Makefile.am
@@ -44,9 +44,11 @@ http_file_test_SOURCES = access/http/file_test.c \
 	access/http/message.c access/http/message.h \
 	access/http/resource.c access/http/resource.h \
 	access/http/file.c access/http/file.h
+http_tunnel_test_SOURCES = access/http/tunnel_test.c
+http_tunnel_test_LDADD = libvlc_http.la
 check_PROGRAMS += hpack_test hpackenc_test \
 	h2frame_test h2output_test h2conn_test h1conn_test h1chunked_test \
-	http_msg_test http_file_test
+	http_msg_test http_file_test http_tunnel_test
 TESTS += hpack_test hpackenc_test \
 	h2frame_test h2output_test h2conn_test h1conn_test h1chunked_test \
-	http_msg_test http_file_test
+	http_msg_test http_file_test http_tunnel_test
diff --git a/modules/access/http/tunnel_test.c b/modules/access/http/tunnel_test.c
new file mode 100644
index 0000000..d4fe87e
--- /dev/null
+++ b/modules/access/http/tunnel_test.c
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * tunnel_test.c: HTTP CONNECT
+ *****************************************************************************
+ * Copyright (C) 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
+
+#undef NDEBUG
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#ifndef SOCK_CLOEXEC
+# define SOCK_CLOEXEC 0
+# define accept4(a,b,c,d) accept(a,b,c)
+#endif
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <vlc_common.h>
+#include <vlc_tls.h>
+#include "transport.h"
+
+static void proxy_client_process(int fd)
+{
+    char buf[1024];
+    size_t buflen = 0;
+    ssize_t val;
+
+    /* Read request (and possibly more) */
+    while (strnstr(buf, "\r\n\r\n", buflen) == NULL)
+    {
+        val = recv(fd, buf + buflen, sizeof (buf) - buflen - 1, 0);
+        if (val <= 0)
+            assert(!"Incomplete request");
+        buflen += val;
+    }
+
+    buf[buflen] = '\0';
+
+    char host[64];
+    unsigned port, ver;
+    int offset;
+
+    assert(sscanf(buf, "CONNECT %63[^:]:%u HTTP/1.%1u%n", host, &port, &ver,
+                  &offset) == 3);
+    assert(!strcmp(host, "www.example.com"));
+    assert(port == 443);
+    assert(ver == 1);
+
+    assert(sscanf(buf + offset + 2, "Host: %63[^:]:%u", host, &port) == 2);
+    assert(!strcmp(host, "www.example.com"));
+    assert(port == 443);
+
+    const char resp[] = "HTTP/1.1 500 Failure\r\n\r\n";
+
+    val = write(fd, resp, strlen(resp));
+    assert((size_t)val == strlen(resp));
+    shutdown(fd, SHUT_WR);
+}
+
+static void *proxy_thread(void *data)
+{
+    int lfd = (intptr_t)data;
+
+    for (;;)
+    {
+        int cfd = accept4(lfd, NULL, NULL, SOCK_CLOEXEC);
+        if (cfd == -1)
+            continue;
+
+        int canc = vlc_savecancel();
+        proxy_client_process(cfd);
+        close(cfd);
+        vlc_restorecancel(canc);
+    }
+    vlc_assert_unreachable();
+}
+
+int main(void)
+{
+    int lfd = socket(PF_INET6, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP);
+    if (lfd == -1)
+        return 77;
+
+    struct sockaddr_in6 addr = {
+        .sin6_family = AF_INET6,
+#ifdef HAVE_SA_LEN
+        .sin6_len = sizeof (addr),
+#endif
+        .sin6_addr = in6addr_loopback,
+    };
+    socklen_t addrlen = sizeof (addr);
+
+    if (bind(lfd, (struct sockaddr *)&addr, addrlen)
+     || listen(lfd, 255))
+    {
+        close(lfd);
+        return 77;
+    }
+
+    char *url;
+    bool two;
+
+    getsockname(lfd, &addr, &addrlen);
+    if (asprintf(&url, "https://[::1]:%u", ntohs(addr.sin6_port)) < 0)
+        url = NULL;
+    assert(url != NULL);
+
+    vlc_thread_t th;
+
+    if (vlc_clone(&th, proxy_thread, (void*)(intptr_t)lfd,
+                  VLC_THREAD_PRIORITY_LOW))
+        assert(!"Thread error");
+
+    vlc_https_connect_proxy(NULL, "www.example.com", 0, &two, url);
+
+    vlc_cancel(th);
+    vlc_join(th, NULL);
+    free(url);
+    close(lfd);
+}



More information about the vlc-commits mailing list