Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * URL utility functions
  3.  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22.  
  23. #include "avformat.h"
  24. #include "config.h"
  25. #include "url.h"
  26. #if CONFIG_NETWORK
  27. #include "network.h"
  28. #endif
  29. #include "libavutil/avstring.h"
  30.  
  31. /**
  32.  * @file
  33.  * URL utility functions.
  34.  */
  35.  
  36. int ff_url_join(char *str, int size, const char *proto,
  37.                 const char *authorization, const char *hostname,
  38.                 int port, const char *fmt, ...)
  39. {
  40. #if CONFIG_NETWORK
  41.     struct addrinfo hints = { 0 }, *ai;
  42. #endif
  43.  
  44.     str[0] = '\0';
  45.     if (proto)
  46.         av_strlcatf(str, size, "%s://", proto);
  47.     if (authorization && authorization[0])
  48.         av_strlcatf(str, size, "%s@", authorization);
  49. #if CONFIG_NETWORK && defined(AF_INET6)
  50.     /* Determine if hostname is a numerical IPv6 address,
  51.      * properly escape it within [] in that case. */
  52.     hints.ai_flags = AI_NUMERICHOST;
  53.     if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
  54.         if (ai->ai_family == AF_INET6) {
  55.             av_strlcat(str, "[", size);
  56.             av_strlcat(str, hostname, size);
  57.             av_strlcat(str, "]", size);
  58.         } else {
  59.             av_strlcat(str, hostname, size);
  60.         }
  61.         freeaddrinfo(ai);
  62.     } else
  63. #endif
  64.         /* Not an IPv6 address, just output the plain string. */
  65.         av_strlcat(str, hostname, size);
  66.  
  67.     if (port >= 0)
  68.         av_strlcatf(str, size, ":%d", port);
  69.     if (fmt) {
  70.         va_list vl;
  71.         int len = strlen(str);
  72.  
  73.         va_start(vl, fmt);
  74.         vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
  75.         va_end(vl);
  76.     }
  77.     return strlen(str);
  78. }
  79.  
  80. void ff_make_absolute_url(char *buf, int size, const char *base,
  81.                           const char *rel)
  82. {
  83.     char *sep, *path_query;
  84.     /* Absolute path, relative to the current server */
  85.     if (base && strstr(base, "://") && rel[0] == '/') {
  86.         if (base != buf)
  87.             av_strlcpy(buf, base, size);
  88.         sep = strstr(buf, "://");
  89.         if (sep) {
  90.             /* Take scheme from base url */
  91.             if (rel[1] == '/') {
  92.                 sep[1] = '\0';
  93.             } else {
  94.                 /* Take scheme and host from base url */
  95.                 sep += 3;
  96.                 sep = strchr(sep, '/');
  97.                 if (sep)
  98.                     *sep = '\0';
  99.             }
  100.         }
  101.         av_strlcat(buf, rel, size);
  102.         return;
  103.     }
  104.     /* If rel actually is an absolute url, just copy it */
  105.     if (!base || strstr(rel, "://") || rel[0] == '/') {
  106.         av_strlcpy(buf, rel, size);
  107.         return;
  108.     }
  109.     if (base != buf)
  110.         av_strlcpy(buf, base, size);
  111.  
  112.     /* Strip off any query string from base */
  113.     path_query = strchr(buf, '?');
  114.     if (path_query != NULL)
  115.         *path_query = '\0';
  116.  
  117.     /* Is relative path just a new query part? */
  118.     if (rel[0] == '?') {
  119.         av_strlcat(buf, rel, size);
  120.         return;
  121.     }
  122.  
  123.     /* Remove the file name from the base url */
  124.     sep = strrchr(buf, '/');
  125.     if (sep)
  126.         sep[1] = '\0';
  127.     else
  128.         buf[0] = '\0';
  129.     while (av_strstart(rel, "../", NULL) && sep) {
  130.         /* Remove the path delimiter at the end */
  131.         sep[0] = '\0';
  132.         sep = strrchr(buf, '/');
  133.         /* If the next directory name to pop off is "..", break here */
  134.         if (!strcmp(sep ? &sep[1] : buf, "..")) {
  135.             /* Readd the slash we just removed */
  136.             av_strlcat(buf, "/", size);
  137.             break;
  138.         }
  139.         /* Cut off the directory name */
  140.         if (sep)
  141.             sep[1] = '\0';
  142.         else
  143.             buf[0] = '\0';
  144.         rel += 3;
  145.     }
  146.     av_strlcat(buf, rel, size);
  147. }
  148.