lavf/url: add ff_url_decompose().
This commit is contained in:
		
							parent
							
								
									64ff61b3c5
								
							
						
					
					
						commit
						d853293679
					
				@ -21,6 +21,31 @@
 | 
				
			|||||||
#include "libavformat/url.h"
 | 
					#include "libavformat/url.h"
 | 
				
			||||||
#include "libavformat/avformat.h"
 | 
					#include "libavformat/avformat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_decompose(const char *url)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    URLComponents uc;
 | 
				
			||||||
 | 
					    int len, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("%s =>\n", url);
 | 
				
			||||||
 | 
					    ret = ff_url_decompose(&uc, url, NULL);
 | 
				
			||||||
 | 
					    if (ret < 0) {
 | 
				
			||||||
 | 
					        printf("  error: %s\n", av_err2str(ret));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#define PRINT_COMPONENT(comp) \
 | 
				
			||||||
 | 
					    len = uc.url_component_end_##comp - uc.comp; \
 | 
				
			||||||
 | 
					    if (len) printf("  "#comp": %.*s\n", len, uc.comp);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(scheme);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(authority);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(userinfo);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(host);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(port);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(path);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(query);
 | 
				
			||||||
 | 
					    PRINT_COMPONENT(fragment);
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void test(const char *base, const char *rel)
 | 
					static void test(const char *base, const char *rel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char buf[200], buf2[200];
 | 
					    char buf[200], buf2[200];
 | 
				
			||||||
@ -51,6 +76,15 @@ static void test2(const char *url)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int main(void)
 | 
					int main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    printf("Testing ff_url_decompose:\n\n");
 | 
				
			||||||
 | 
					    test_decompose("http://user:pass@ffmpeg:8080/dir/file?query#fragment");
 | 
				
			||||||
 | 
					    test_decompose("http://ffmpeg/dir/file");
 | 
				
			||||||
 | 
					    test_decompose("file:///dev/null");
 | 
				
			||||||
 | 
					    test_decompose("file:/dev/null");
 | 
				
			||||||
 | 
					    test_decompose("http://[::1]/dev/null");
 | 
				
			||||||
 | 
					    test_decompose("http://[::1]:8080/dev/null");
 | 
				
			||||||
 | 
					    test_decompose("//ffmpeg/dev/null");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("Testing ff_make_absolute_url:\n");
 | 
					    printf("Testing ff_make_absolute_url:\n");
 | 
				
			||||||
    test(NULL, "baz");
 | 
					    test(NULL, "baz");
 | 
				
			||||||
    test("/foo/bar", "baz");
 | 
					    test("/foo/bar", "baz");
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@
 | 
				
			|||||||
#if CONFIG_NETWORK
 | 
					#if CONFIG_NETWORK
 | 
				
			||||||
#include "network.h"
 | 
					#include "network.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#include "libavutil/avassert.h"
 | 
				
			||||||
#include "libavutil/avstring.h"
 | 
					#include "libavutil/avstring.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -78,6 +79,76 @@ int ff_url_join(char *str, int size, const char *proto,
 | 
				
			|||||||
    return strlen(str);
 | 
					    return strlen(str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *find_delim(const char *delim, const char *cur, const char *end)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while (cur < end && !strchr(delim, *cur))
 | 
				
			||||||
 | 
					        cur++;
 | 
				
			||||||
 | 
					    return cur;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ff_url_decompose(URLComponents *uc, const char *url, const char *end)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const char *cur, *aend, *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    av_assert0(url);
 | 
				
			||||||
 | 
					    if (!end)
 | 
				
			||||||
 | 
					        end = url + strlen(url);
 | 
				
			||||||
 | 
					    cur = uc->url = url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* scheme */
 | 
				
			||||||
 | 
					    uc->scheme = cur;
 | 
				
			||||||
 | 
					    p = find_delim(":/", cur, end); /* lavf "schemes" can contain options */
 | 
				
			||||||
 | 
					    if (*p == ':')
 | 
				
			||||||
 | 
					        cur = p + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* authority */
 | 
				
			||||||
 | 
					    uc->authority = cur;
 | 
				
			||||||
 | 
					    if (end - cur >= 2 && cur[0] == '/' && cur[1] == '/') {
 | 
				
			||||||
 | 
					        cur += 2;
 | 
				
			||||||
 | 
					        aend = find_delim("/?#", cur, end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* userinfo */
 | 
				
			||||||
 | 
					        uc->userinfo = cur;
 | 
				
			||||||
 | 
					        p = find_delim("@", cur, aend);
 | 
				
			||||||
 | 
					        if (*p == '@')
 | 
				
			||||||
 | 
					            cur = p + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* host */
 | 
				
			||||||
 | 
					        uc->host = cur;
 | 
				
			||||||
 | 
					        if (*cur == '[') { /* hello IPv6, thanks for using colons! */
 | 
				
			||||||
 | 
					            p = find_delim("]", cur, aend);
 | 
				
			||||||
 | 
					            if (*p != ']')
 | 
				
			||||||
 | 
					                return AVERROR(EINVAL);
 | 
				
			||||||
 | 
					            if (p + 1 < aend && p[1] != ':')
 | 
				
			||||||
 | 
					                return AVERROR(EINVAL);
 | 
				
			||||||
 | 
					            cur = p + 1;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            cur = find_delim(":", cur, aend);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* port */
 | 
				
			||||||
 | 
					        uc->port = cur;
 | 
				
			||||||
 | 
					        cur = aend;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        uc->userinfo = uc->host = uc->port = cur;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* path */
 | 
				
			||||||
 | 
					    uc->path = cur;
 | 
				
			||||||
 | 
					    cur = find_delim("?#", cur, end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* query */
 | 
				
			||||||
 | 
					    uc->query = cur;
 | 
				
			||||||
 | 
					    if (*cur == '?')
 | 
				
			||||||
 | 
					        cur = find_delim("#", cur, end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* fragment */
 | 
				
			||||||
 | 
					    uc->fragment = cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uc->end = end;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void trim_double_dot_url(char *buf, const char *rel, int size)
 | 
					static void trim_double_dot_url(char *buf, const char *rel, int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *p = rel;
 | 
					    const char *p = rel;
 | 
				
			||||||
 | 
				
			|||||||
@ -344,4 +344,45 @@ const AVClass *ff_urlcontext_child_class_iterate(void **iter);
 | 
				
			|||||||
const URLProtocol **ffurl_get_protocols(const char *whitelist,
 | 
					const URLProtocol **ffurl_get_protocols(const char *whitelist,
 | 
				
			||||||
                                        const char *blacklist);
 | 
					                                        const char *blacklist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct URLComponents {
 | 
				
			||||||
 | 
					    const char *url;        /**< whole URL, for reference */
 | 
				
			||||||
 | 
					    const char *scheme;     /**< possibly including lavf-specific options */
 | 
				
			||||||
 | 
					    const char *authority;  /**< "//" if it is a real URL */
 | 
				
			||||||
 | 
					    const char *userinfo;   /**< including final '@' if present */
 | 
				
			||||||
 | 
					    const char *host;
 | 
				
			||||||
 | 
					    const char *port;       /**< including initial ':' if present */
 | 
				
			||||||
 | 
					    const char *path;
 | 
				
			||||||
 | 
					    const char *query;      /**< including initial '?' if present */
 | 
				
			||||||
 | 
					    const char *fragment;   /**< including initial '#' if present */
 | 
				
			||||||
 | 
					    const char *end;
 | 
				
			||||||
 | 
					} URLComponents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define url_component_end_scheme      authority
 | 
				
			||||||
 | 
					#define url_component_end_authority   userinfo
 | 
				
			||||||
 | 
					#define url_component_end_userinfo    host
 | 
				
			||||||
 | 
					#define url_component_end_host        port
 | 
				
			||||||
 | 
					#define url_component_end_port        path
 | 
				
			||||||
 | 
					#define url_component_end_path        query
 | 
				
			||||||
 | 
					#define url_component_end_query       fragment
 | 
				
			||||||
 | 
					#define url_component_end_fragment    end
 | 
				
			||||||
 | 
					#define url_component_end_authority_full path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define URL_COMPONENT_HAVE(uc, component) \
 | 
				
			||||||
 | 
					    ((uc).url_component_end_##component > (uc).component)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Parse an URL to find the components.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Each component runs until the start of the next component,
 | 
				
			||||||
 | 
					 * possibly including a mandatory delimiter.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param uc   structure to fill with pointers to the components.
 | 
				
			||||||
 | 
					 * @param url  URL to parse.
 | 
				
			||||||
 | 
					 * @param end  end of the URL, or NULL to parse to the end of string.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return  >= 0 for success or an AVERROR code, especially if the URL is
 | 
				
			||||||
 | 
					 *          malformed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int ff_url_decompose(URLComponents *uc, const char *url, const char *end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* AVFORMAT_URL_H */
 | 
					#endif /* AVFORMAT_URL_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,48 @@
 | 
				
			|||||||
 | 
					Testing ff_url_decompose:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http://user:pass@ffmpeg:8080/dir/file?query#fragment =>
 | 
				
			||||||
 | 
					  scheme: http:
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  userinfo: user:pass@
 | 
				
			||||||
 | 
					  host: ffmpeg
 | 
				
			||||||
 | 
					  port: :8080
 | 
				
			||||||
 | 
					  path: /dir/file
 | 
				
			||||||
 | 
					  query: ?query
 | 
				
			||||||
 | 
					  fragment: #fragment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http://ffmpeg/dir/file =>
 | 
				
			||||||
 | 
					  scheme: http:
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  host: ffmpeg
 | 
				
			||||||
 | 
					  path: /dir/file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file:///dev/null =>
 | 
				
			||||||
 | 
					  scheme: file:
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  path: /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file:/dev/null =>
 | 
				
			||||||
 | 
					  scheme: file:
 | 
				
			||||||
 | 
					  path: /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http://[::1]/dev/null =>
 | 
				
			||||||
 | 
					  scheme: http:
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  host: [::1]
 | 
				
			||||||
 | 
					  path: /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http://[::1]:8080/dev/null =>
 | 
				
			||||||
 | 
					  scheme: http:
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  host: [::1]
 | 
				
			||||||
 | 
					  port: :8080
 | 
				
			||||||
 | 
					  path: /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//ffmpeg/dev/null =>
 | 
				
			||||||
 | 
					  authority: //
 | 
				
			||||||
 | 
					  host: ffmpeg
 | 
				
			||||||
 | 
					  path: /dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Testing ff_make_absolute_url:
 | 
					Testing ff_make_absolute_url:
 | 
				
			||||||
                                            (null) baz                  => baz
 | 
					                                            (null) baz                  => baz
 | 
				
			||||||
                                          /foo/bar baz                  => /foo/baz
 | 
					                                          /foo/bar baz                  => /foo/baz
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user