diff mbox series

[FFmpeg-devel,3/5] Merge IPNS and IPFS handling.

Message ID 20220131135116.14035-4-markg85@gmail.com
State New
Headers show
Series Add IPFS and IPNS protocol support | expand

Checks

Context Check Description
andriy/commit_msg_x86 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/commit_msg_ppc warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Mark Gaiser Jan. 31, 2022, 1:51 p.m. UTC
Only the open function needs to detect which one is used.

Signed-off-by: Mark Gaiser <markg85@gmail.com>
---
 libavformat/ipfs.c | 99 +++++++++++-----------------------------------
 1 file changed, 22 insertions(+), 77 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/ipfs.c b/libavformat/ipfs.c
index 8daf032dd2..22487c6cc8 100644
--- a/libavformat/ipfs.c
+++ b/libavformat/ipfs.c
@@ -1,6 +1,6 @@ 
 /*
  * IPFS protocol.
- * Copyright (c) 2021 Mark Gaiser
+ * Copyright (c) 2022 Mark Gaiser
  *
  * This file is part of FFmpeg.
  *
@@ -47,23 +47,30 @@  typedef struct Context {
 static int ipfs_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
 {
     const char *gatewaysuffix;
+    const char *protocolPathSuffix = "ipfs/";
     int ret = 0;
     Context *c = h->priv_data;
+    int isIpfs = (av_strstart(uri, "ipfs://", &gatewaysuffix) || av_strstart(uri, "ipfs:", &gatewaysuffix));
+    int isIpns = (av_strstart(uri, "ipns://", &gatewaysuffix) || av_strstart(uri, "ipns:", &gatewaysuffix));
     
-    if (!av_strstart(uri, "ipfs://", &gatewaysuffix) &&
-        !av_strstart(uri, "ipfs:", &gatewaysuffix)) {
-        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
+    if (!isIpfs && !isIpns) {
         ret = AVERROR(EINVAL);
+        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
         goto err;
     }
-    
-    char* ipfs_gateway = "http://localhost:8080/";
-    
-    c->fulluri = malloc(strlen(ipfs_gateway)+strlen(gatewaysuffix) + 1);
-    
-    strcpy(c->fulluri, ipfs_gateway);
+
+    // If we have IPNS, update the protocol
+    if (isIpns) {
+        protocolPathSuffix = "ipns/";
+    }
+
+    // Concatenate the url. This ends up with something like: http://localhost:8080/ipfs/Qm.....
+    c->fulluri = malloc(strlen(c->gateway) + strlen(protocolPathSuffix) + strlen(gatewaysuffix) + 1);
+    strcpy(c->fulluri, c->gateway);
+    strcat(c->fulluri, protocolPathSuffix);
     strcat(c->fulluri, gatewaysuffix);
     
+    // Pass the URL back to FFMpeg's protocol handler.
     if ((ret = ffurl_open_whitelist(&c->inner, c->fulluri, flags,
                                     &h->interrupt_callback, options,
                                     h->protocol_whitelist, h->protocol_blacklist, h)) < 0) {
@@ -105,72 +112,10 @@  static int ipfs_close(URLContext *h)
     return ret;
 }
 
-static int ipns_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
-{
-    const char *gatewaysuffix;
-    int ret = 0;
-    Context *c = h->priv_data;
-    
-    if (!av_strstart(uri, "ipns://", &gatewaysuffix) &&
-        !av_strstart(uri, "ipns:", &gatewaysuffix)) {
-        av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
-        ret = AVERROR(EINVAL);
-        goto err;
-    }
-    
-    char* ipfs_gateway = "https://ipfs.io/ipns/";
-    
-    c->fulluri = malloc(strlen(ipfs_gateway)+strlen(gatewaysuffix) + 1);
-    
-    strcpy(c->fulluri, ipfs_gateway);
-    strcat(c->fulluri, gatewaysuffix);
-    
-    if ((ret = ffurl_open_whitelist(&c->inner, c->fulluri, flags,
-                                    &h->interrupt_callback, options,
-                                    h->protocol_whitelist, h->protocol_blacklist, h)) < 0) {
-        av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", c->fulluri);
-        goto err;
-    }
-    
-err:
-    return ret;
-}
-
-static int ipns_read(URLContext *h, unsigned char *buf, int size)
-{
-    Context *c = h->priv_data;
-    int ret;
-
-    ret = ffurl_read(c->inner, buf, size);
-
-    return ret;
-}
-
-static int64_t ipns_seek(URLContext *h, int64_t pos, int whence)
-{
-    Context *c = h->priv_data;
-    int64_t ret;
-
-    ret = ffurl_seek(c->inner, pos, whence);
-
-    return ret;
-}
-
-static int ipns_close(URLContext *h)
-{
-    Context *c = h->priv_data;
-    int ret;
-
-    ret = ffurl_closep(&c->inner);
-
-    return ret;
-}
-
 #define OFFSET(x) offsetof(Context, x)
-#define D AV_OPT_FLAG_DECODING_PARAM
 
 static const AVOption options[] = {
-    {"gateway", "The gateway to ask for IPFS data.", OFFSET(gateway), AV_OPT_TYPE_BINARY, .flags = D },
+    {"gateway", "The gateway to ask for IPFS data.", OFFSET(gateway), AV_OPT_TYPE_STRING, {.str = "http://localhost:8080/"}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
     {NULL},
 };
 
@@ -193,10 +138,10 @@  const URLProtocol ff_ipfs_protocol = {
 
 const URLProtocol ff_ipns_protocol = {
     .name                = "ipns",
-    .url_open2           = ipns_open,
-    .url_read            = ipns_read,
-    .url_seek            = ipns_seek,
-    .url_close           = ipns_close,
+    .url_open2           = ipfs_open,
+    .url_read            = ipfs_read,
+    .url_seek            = ipfs_seek,
+    .url_close           = ipfs_close,
     .priv_data_size      = sizeof(Context),
     .priv_data_class     = &ipfs_context_class,
 };