vlc_url.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * vlc_url.h: URL related macros
00003  *****************************************************************************
00004  * Copyright (C) 2002-2006 VLC authors and VideoLAN
00005  * $Id: 994d8ff24e3e897bc19e02476842b3d4cd29a336 $
00006  *
00007  * Authors: Christophe Massiot <massiot@via.ecp.fr>
00008  *          Rémi Denis-Courmont <rem # videolan.org>
00009  *
00010  * This program is free software; you can redistribute it and/or modify it
00011  * under the terms of the GNU Lesser General Public License as published by
00012  * the Free Software Foundation; either version 2.1 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018  * GNU Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public License
00021  * along with this program; if not, write to the Free Software Foundation,
00022  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
00023  *****************************************************************************/
00024 
00025 #ifndef VLC_URL_H
00026 # define VLC_URL_H
00027 
00028 /**
00029  * \file
00030  * This file defines functions for manipulating URL in vlc
00031  */
00032 
00033 struct vlc_url_t
00034 {
00035     char *psz_protocol;
00036     char *psz_username;
00037     char *psz_password;
00038     char *psz_host;
00039     int  i_port;
00040 
00041     char *psz_path;
00042 
00043     char *psz_option;
00044 
00045     char *psz_buffer; /* to be freed */
00046 };
00047 
00048 VLC_API char * decode_URI_duplicate( const char *psz );
00049 VLC_API char * decode_URI( char *psz );
00050 VLC_API char * encode_URI_component( const char *psz );
00051 VLC_API char * make_URI( const char *path, const char *scheme );
00052 VLC_API char * make_path( const char *url );
00053 
00054 /*****************************************************************************
00055  * vlc_UrlParse:
00056  *****************************************************************************
00057  * option : if != 0 then path is split at this char
00058  *
00059  * format [protocol://[login[:password]@]][host[:port]]/path[OPTIONoption]
00060  *****************************************************************************/
00061 static inline void vlc_UrlParse( vlc_url_t *url, const char *psz_url,
00062                                  char option )
00063 {
00064     char *psz_dup;
00065     char *psz_parse;
00066     char *p;
00067     char *p2;
00068 
00069     url->psz_protocol = NULL;
00070     url->psz_username = NULL;
00071     url->psz_password = NULL;
00072     url->psz_host     = NULL;
00073     url->i_port       = 0;
00074     url->psz_path     = NULL;
00075     url->psz_option   = NULL;
00076 
00077     if( psz_url == NULL )
00078     {
00079         url->psz_buffer = NULL;
00080         return;
00081     }
00082     url->psz_buffer = psz_parse = psz_dup = strdup( psz_url );
00083 
00084     /* Search a valid protocol */
00085     p  = strstr( psz_parse, ":/" );
00086     if( p != NULL )
00087     {
00088         for( p2 = psz_parse; p2 < p; p2++ )
00089         {
00090 #define I(i,a,b) ( (a) <= (i) && (i) <= (b) )
00091             if( !I(*p2, 'a', 'z' ) && !I(*p2, 'A', 'Z') && !I(*p2, '0', '9') && *p2 != '+' && *p2 != '-' && *p2 != '.' )
00092             {
00093                 p = NULL;
00094                 break;
00095             }
00096 #undef I
00097         }
00098     }
00099 
00100     if( p != NULL )
00101     {
00102         /* we have a protocol */
00103 
00104         /* skip :// */
00105         *p++ = '\0';
00106         if( p[1] == '/' )
00107             p += 2;
00108         url->psz_protocol = psz_parse;
00109         psz_parse = p;
00110     }
00111     p = strchr( psz_parse, '@' );
00112     p2 = strchr( psz_parse, '/' );
00113     if( p != NULL && ( p2 != NULL ? p < p2 : 1 ) )
00114     {
00115         /* We have a login */
00116         url->psz_username = psz_parse;
00117         *p++ = '\0';
00118 
00119         psz_parse = strchr( psz_parse, ':' );
00120         if( psz_parse != NULL )
00121         {
00122             /* We have a password */
00123             *psz_parse++ = '\0';
00124             url->psz_password = psz_parse;
00125             decode_URI( url->psz_password );
00126         }
00127         decode_URI( url->psz_username );
00128         psz_parse = p;
00129     }
00130 
00131     p = strchr( psz_parse, '/' );
00132     if( !p || psz_parse < p )
00133     {
00134         /* We have a host[:port] */
00135         url->psz_host = strdup( psz_parse );
00136         if( p )
00137         {
00138             url->psz_host[p - psz_parse] = '\0';
00139         }
00140 
00141         if( *url->psz_host == '[' )
00142         {
00143             /* Ipv6 address */
00144             p2 = strchr( url->psz_host, ']' );
00145             if( p2 )
00146             {
00147                 p2 = strchr( p2, ':' );
00148             }
00149         }
00150         else
00151         {
00152             p2 = strchr( url->psz_host, ':' );
00153         }
00154         if( p2 )
00155         {
00156             *p2++ = '\0';
00157             url->i_port = atoi( p2 );
00158         }
00159     }
00160     psz_parse = p;
00161 
00162     /* Now parse psz_path and psz_option */
00163     if( psz_parse )
00164     {
00165         url->psz_path = psz_parse;
00166         if( option != '\0' )
00167         {
00168             p = strchr( url->psz_path, option );
00169             if( p )
00170             {
00171                 *p++ = '\0';
00172                 url->psz_option = p;
00173             }
00174         }
00175     }
00176 }
00177 
00178 /*****************************************************************************
00179  * vlc_UrlClean:
00180  *****************************************************************************/
00181 static inline void vlc_UrlClean( vlc_url_t *url )
00182 {
00183     free( url->psz_buffer );
00184     free( url->psz_host );
00185 
00186     url->psz_protocol = NULL;
00187     url->psz_username = NULL;
00188     url->psz_password = NULL;
00189     url->psz_host     = NULL;
00190     url->i_port       = 0;
00191     url->psz_path     = NULL;
00192     url->psz_option   = NULL;
00193 
00194     url->psz_buffer   = NULL;
00195 }
00196 
00197 #include <ctype.h>
00198 
00199 /** Check whether a given string is not a valid URL and must hence be
00200  *  encoded */
00201 static inline int vlc_UrlIsNotEncoded( const char *psz_url )
00202 {
00203     const char *ptr;
00204 
00205     for( ptr = psz_url; *ptr; ptr++ )
00206     {
00207         unsigned char c = *ptr;
00208 
00209         if( c == '%' )
00210         {
00211             if( !isxdigit( (unsigned char)ptr[1] )
00212              || !isxdigit( (unsigned char)ptr[2] ) )
00213                 return 1; /* not encoded */
00214             ptr += 2;
00215         }
00216         else
00217         if(  ( (unsigned char)( c - 'a' ) < 26 )
00218           || ( (unsigned char)( c - 'A' ) < 26 )
00219           || ( (unsigned char)( c - '0' ) < 10 )
00220           || ( strchr( "-_.", c ) != NULL ) )
00221             return 1;
00222     }
00223     return 0; /* looks fine - but maybe it is not encoded */
00224 }
00225 
00226 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines