[PATCH 45/45] Emscripten JS FETCH API plugin and websocket_to_posix_proxy support.

Gokhan Poyraz <[email protected]>
Newsgroups gmane.comp.video.videolan.vlc.devel
Message-ID <[email protected]>
---
 .../0082-emscripten_js_fetch_api_plugin.patch | 152 +++++++++++++++
 ..._sockets_over_websocket_proxy_server.patch | 183 ++++++++++++++++++
 2 files changed, 335 insertions(+)
 create mode 100644 vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
 create mode 100644 vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch

diff --git a/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch b/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
new file mode 100644
index 0000000..b1afadc
--- /dev/null
+++ b/vlc_patches/aug/0082-emscripten_js_fetch_api_plugin.patch
@@ -0,0 +1,152 @@
+diff -Nuar vlc.original/modules/access/Makefile.am vlc/modules/access/Makefile.am
+--- vlc.original/modules/access/Makefile.am	2022-12-15 20:28:36.000000000 +0300
++++ vlc/modules/access/Makefile.am	2022-12-12 13:59:11.000000000 +0300
+@@ -29,6 +29,9 @@
+ if HAVE_EMSCRIPTEN
+ libemjsfile_plugin_la_SOURCES = access/emjsfile.c
+ access_LTLIBRARIES += libemjsfile_plugin.la
++
++libemjsfetch_plugin_la_SOURCES = access/emjsfetch.c
++access_LTLIBRARIES += libemjsfetch_plugin.la
+ endif
+ 
+ libidummy_plugin_la_SOURCES = access/idummy.c
+diff -Nuar vlc.original/modules/access/emjsfetch.c vlc/modules/access/emjsfetch.c
+--- vlc.original/modules/access/emjsfetch.c	1970-01-01 02:00:00.000000000 +0200
++++ vlc/modules/access/emjsfetch.c	2022-12-15 20:24:49.000000000 +0300
+@@ -0,0 +1,135 @@
++/*****************************************************************************
++ * emjsfetch.c: emscripten js fetch api plugin
++ *****************************************************************************
++ * Copyright (C) 2022 VLC authors Videolabs, and VideoLAN
++ *
++ *
++ * 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 <vlc_common.h>
++#include <vlc_plugin.h>
++#include <vlc_access.h>
++#include <vlc_threads.h>
++#include <stdalign.h>
++
++#include <emscripten.h>
++
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <unistd.h>
++
++typedef struct
++{   
++    char *url;
++} access_sys_t;
++
++static block_t *BlockFetch(stream_t *p_access, bool *restrict eof)
++{
++    access_sys_t *p_sys = p_access->p_sys;
++    int rc, fz;
++    void *ebuf;
++    block_t *pkt = NULL;
++
++    msg_Dbg( p_access, "fetch: start(%s)", p_sys->url);
++    emscripten_wget_data(p_sys->url, &ebuf, &fz, &rc);
++    if (rc != 0) {
++       msg_Dbg( p_access, "fetch: unable to fetch(%s), err: %d", p_sys->url, rc);
++       return pkt;
++    }
++
++    msg_Dbg( p_access, "fetch: %d byte(s)", fz);
++
++    pkt = block_Alloc( fz );
++    if ( unlikely( pkt == NULL ) ) {   
++       msg_Dbg( p_access, "fetch: block_Alloc(%s) failed", p_sys->url);
++       return NULL;
++    }
++    memcpy(pkt->p_buffer, ebuf, fz);
++    pkt->i_buffer = fz;
++
++    free(ebuf);
++    *eof = true;
++    return pkt;
++}
++
++static int Control( stream_t *p_access, int i_query, va_list args )
++{
++    int i_ret = VLC_SUCCESS;
++
++    switch( i_query )
++    {
++        case STREAM_CAN_SEEK:
++        case STREAM_CAN_FASTSEEK:
++        case STREAM_CAN_PAUSE:
++        case STREAM_CAN_CONTROL_PACE:
++            *va_arg( args, bool * ) = false;
++            break;
++        case STREAM_GET_PTS_DELAY:
++            *va_arg( args, vlc_tick_t * ) = VLC_TICK_FROM_MS(
++                   var_InheritInteger(p_access, "network-caching") );
++            break;
++        default:
++            i_ret = VLC_EGENERIC;
++            break;
++    }
++
++    return i_ret;
++}
++
++static void EmFetchClose (vlc_object_t * p_this) {
++    stream_t *p_access = (stream_t*)p_this;
++    access_sys_t *p_sys = p_access->p_sys;
++    free(p_sys->url);
++}
++
++static int EmFetchOpen( vlc_object_t *p_this ) {
++    stream_t *p_access = (stream_t*)p_this;
++
++    access_sys_t *p_sys = vlc_obj_malloc(p_this, sizeof (*p_sys));
++    if (unlikely(p_sys == NULL))
++        return VLC_ENOMEM;
++
++    msg_Dbg( p_access, "fetch: base url='%s'", p_access->psz_url);
++
++    if (p_access->psz_url[0] == 'f') {
++       p_sys->url = strdup(p_access->psz_url + 8);
++    } else {
++       p_sys->url = strdup(p_access->psz_url);
++    }
++    p_access->p_sys = p_sys;
++    
++    msg_Dbg( p_access, "fetch: url='%s'", p_sys->url);
++
++    p_access->pf_block = BlockFetch;
++    p_access->pf_control = Control;
++
++    return VLC_SUCCESS;
++}
++
++vlc_module_begin ()
++    set_shortname( N_("Fetch API") )
++    set_description( N_("Emscripten module to allow fetching remote resources") )
++    set_capability( "access", 0 )
++    //set_category( CAT_INPUT )
++    set_subcategory( SUBCAT_INPUT_ACCESS )
++    add_shortcut( "fetch", "https", "http" )
++    set_callbacks( EmFetchOpen, EmFetchClose )
++vlc_module_end()
diff --git a/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch b/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch
new file mode 100644
index 0000000..a75c368
--- /dev/null
+++ b/vlc_patches/aug/0083-emscripten_posix_sockets_over_websocket_proxy_server.patch
@@ -0,0 +1,183 @@
+diff -Nuar vlc.original/modules/access/http/h1conn.c vlc/modules/access/http/h1conn.c
+--- vlc.original/modules/access/http/h1conn.c	2022-12-11 22:19:02.000000000 +0300
++++ vlc/modules/access/http/h1conn.c	2022-12-15 23:05:13.000000000 +0300
+@@ -387,7 +387,13 @@
+ 
+     for (const struct addrinfo *p = res; p != NULL; p = p->ai_next)
+     {
+-        vlc_tls_t *tcp = vlc_tls_SocketOpenAddrInfo(p, idempotent);
++        vlc_tls_t *tcp = vlc_tls_SocketOpenAddrInfo(p,
++#ifdef __EMSCRIPTEN__
++              false
++#else
++              idempotent
++#endif
++              );
+         if (tcp == NULL)
+         {
+             vlc_http_err(ctx, "socket error: %s", vlc_strerror_c(errno));
+@@ -418,7 +424,9 @@
+ 
+         vlc_http_conn_release(conn);
+ 
++#ifndef __EMSCRIPTEN__
+         if (!idempotent)
++#endif
+             break; /* If the request is nonidempotent, it cannot be resent. */
+     }
+ 
+diff -Nuar vlc.original/modules/access/http/resource.c vlc/modules/access/http/resource.c
+--- vlc.original/modules/access/http/resource.c	2022-12-11 22:19:02.000000000 +0300
++++ vlc/modules/access/http/resource.c	2022-12-15 20:16:28.000000000 +0300
+@@ -182,7 +182,11 @@
+     }
+ 
+     if (!vlc_ascii_strcasecmp(url.psz_protocol, "https"))
++#ifdef __EMSCRIPTEN__
++        secure = false;
++#else
+         secure = true;
++#endif
+     else if (!vlc_ascii_strcasecmp(url.psz_protocol, "http"))
+         secure = false;
+     else
+diff -Nuar vlc.original/src/network/stream.c vlc/src/network/stream.c
+--- vlc.original/src/network/stream.c	2022-12-11 22:19:03.000000000 +0300
++++ vlc/src/network/stream.c	2022-12-19 17:19:03.000000000 +0300
+@@ -183,6 +183,9 @@
+                                   unsigned count)
+ {
+     vlc_tls_socket_t *sock = (struct vlc_tls_socket *)tls;
++#ifdef __EMSCRIPTEN__
++    return recv(sock->fd, iov->iov_base, iov->iov_len, 0);
++#else
+     struct msghdr msg =
+     {
+         .msg_iov = iov,
+@@ -190,6 +193,7 @@
+     };
+ 
+     return recvmsg(sock->fd, &msg, 0);
++#endif
+ }
+ 
+ static ssize_t vlc_tls_SocketWrite(vlc_tls_t *tls, const struct iovec *iov,
+diff -Nuar vlc.original/src/posix/filesystem.c vlc/src/posix/filesystem.c
+--- vlc.original/src/posix/filesystem.c	2022-12-11 22:20:21.000000000 +0300
++++ vlc/src/posix/filesystem.c	2022-12-15 22:00:46.000000000 +0300
+@@ -48,7 +48,9 @@
+ #if !defined(HAVE_ACCEPT4)
+ static inline void vlc_cloexec(int fd)
+ {
++#ifndef __EMSCRIPTEN__
+     fcntl(fd, F_SETFD, FD_CLOEXEC | fcntl(fd, F_GETFD));
++#endif
+ }
+ #endif
+ #if !defined(MSG_NOSIGNAL) && defined(SO_NOSIGPIPE)
+@@ -112,6 +114,9 @@
+     if (unlikely(ret != 0) && unlikely(errno == EINTR))
+         errno = EINPROGRESS;
+ #endif
++#ifdef __EMSCRIPTEN__
++    ret = 0;
++#endif
+     assert(ret == 0 || errno != EBADF); /* something is corrupt? */
+     return ret;
+ }
+@@ -256,8 +261,10 @@
+ {
+     vlc_cloexec(fd);
+ 
++#ifndef __EMSCRIPTEN__
+     if (nonblock)
+         fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
++#endif
+ 
+ #ifdef SO_NOSIGPIPE
+     setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){ 1 }, sizeof (int));
+@@ -267,7 +274,7 @@
+ 
+ int vlc_socket (int pf, int type, int proto, bool nonblock)
+ {
+-#ifdef SOCK_CLOEXEC
++#if defined(SOCK_CLOEXEC) && !defined(__EMSCRIPTEN__)
+     if (nonblock)
+         type |= SOCK_NONBLOCK;
+ 
+@@ -286,7 +293,7 @@
+ 
+ int vlc_socketpair(int pf, int type, int proto, int fds[2], bool nonblock)
+ {
+-#ifdef SOCK_CLOEXEC
++#if defined(SOCK_CLOEXEC) && !defined(__EMSCRIPTEN__)
+     if (nonblock)
+         type |= SOCK_NONBLOCK;
+ 
+@@ -313,7 +320,7 @@
+ 
+ int vlc_accept (int lfd, struct sockaddr *addr, socklen_t *alen, bool nonblock)
+ {
+-#ifdef HAVE_ACCEPT4
++#if defined(HAVE_ACCEPT4) && !defined(__EMSCRIPTEN__)
+     int flags = SOCK_CLOEXEC;
+     if (nonblock)
+         flags |= SOCK_NONBLOCK;
+@@ -333,12 +340,19 @@
+ 
+ ssize_t vlc_send(int fd, const void *buf, size_t len, int flags)
+ {
+-    return vlc_sendto(fd, buf, len, flags, NULL, 0);
++#ifdef __EMSCRIPTEN__
++   return send(fd, buf, len, flags | MSG_NOSIGNAL);
++#else
++   return vlc_sendto(fd, buf, len, flags, NULL, 0);
++#endif
+ }
+ 
+ ssize_t vlc_sendto(int fd, const void *buf, size_t len, int flags,
+                    const struct sockaddr *dst, socklen_t dstlen)
+ {
++#ifdef __EMSCRIPTEN__
++    return vlc_send(fd, buf, len, flags);
++#else
+     struct iovec iov = {
+         .iov_base = (void *)buf,
+         .iov_len = len,
+@@ -351,9 +365,14 @@
+     };
+ 
+     return vlc_sendmsg(fd, &msg, flags);
++#endif
+ }
+ 
+ ssize_t vlc_sendmsg(int fd, const struct msghdr *msg, int flags)
+ {
++#ifdef __EMSCRIPTEN__
++    return vlc_send(fd, msg->msg_iov->iov_base, msg->msg_iov->iov_len, flags);
++#else
+     return sendmsg(fd, msg, flags | MSG_NOSIGNAL);
++#endif
+ }
+diff -Nuar vlc.original/src/posix/getaddrinfo.c vlc/src/posix/getaddrinfo.c
+--- vlc.original/src/posix/getaddrinfo.c	2022-12-11 22:20:21.000000000 +0300
++++ vlc/src/posix/getaddrinfo.c	2022-12-15 21:46:22.000000000 +0300
+@@ -73,6 +73,10 @@
+         req.service = portbuf;
+     }
+ 
++#ifdef __EMSCRIPTEN__
++    req.error = EAI_SYSTEM;
++    req.error = getaddrinfo(req.name, req.service, req.hints, req.result);
++#else
+     vlc_sem_init(&req.done, 0);
+ 
+     if (vlc_clone(&th, vlc_gai_thread, &req, VLC_THREAD_PRIORITY_LOW))
+@@ -82,6 +86,6 @@
+ 
+     vlc_cancel(th);
+     vlc_join(th, NULL);
+-
++#endif
+     return req.error;
+ }
-- 
2.24.3 (Apple Git-128)

_______________________________________________
vlc-devel mailing list
To unsubscribe or modify your subscription options:
https://mailman.videolan.org/listinfo/vlc-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.