[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