Changeset fe927c0f058f3f9b27a48524ff9471ae1082f1bc

Show
Ignore:
Timestamp:
08/26/05 20:15:21 (3 years ago)
Author:
Christophe Massiot <massiot@videolan.org>
git-committer:
Christophe Massiot <massiot@videolan.org> 1125080121 +0000
git-parent:

[375abfbdd16fa92a9a23f94a87d1b6ce0ca48c25]

git-author:
Christophe Massiot <massiot@videolan.org> 1125080121 +0000
Message:
  • src/extras/libc.c: Implemented a wrapper around fork() and execve()
    to spawn an external process and get its output. Only implemented for
    UNIX-style systems at present.
  • src/misc/httpd.c: New "handler" node type which bypasses the internal
    HTTPD behaviour.
  • modules/control/http: New --http-handlers option to dedicate
    particular extensions to external programs (PHP or Perl for instance).
    This is in accordance with the CGI/1.1 specification.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • configure.ac

    ra84ef62 rfe927c0  
    326326need_libc=false 
    327327 
    328 AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol strtof strtoll strtoull strsep isatty vasprintf asprintf swab sigrelse getpwuid memalign posix_memalign if_nametoindex atoll getenv putenv setenv gmtime_r ctime_r localtime_r lrintf daemon scandir
     328AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol strtof strtoll strtoull strsep isatty vasprintf asprintf swab sigrelse getpwuid memalign posix_memalign if_nametoindex atoll getenv putenv setenv gmtime_r ctime_r localtime_r lrintf daemon scandir fork
    329329 
    330330dnl Check for usual libc functions 
     
    18831883  AC_CHECK_LIB(resolv,inet_pton, 
    18841884    [have_ipv6=yes 
    1885      VLC_ADD_LDFLAGS([ipv6],[-lresolv])]) 
     1885     VLC_ADD_LDFLAGS([ipv6 vlc],[-lresolv])]) 
    18861886]) 
    18871887 
  • include/vlc_common.h

    r74764fb rfe927c0  
    379379typedef struct httpd_file_t     httpd_file_t; 
    380380typedef struct httpd_file_sys_t httpd_file_sys_t; 
    381 typedef int (*httpd_file_callback_t)( httpd_file_sys_t*, httpd_file_t *, uint8_t *psz_request, uint8_t **pp_data, int *pi_data ); 
     381typedef int (*httpd_file_callback_t)( httpd_file_sys_t *, httpd_file_t *, uint8_t *psz_request, uint8_t **pp_data, int *pi_data ); 
     382typedef struct httpd_handler_t  httpd_handler_t; 
     383typedef struct httpd_handler_sys_t httpd_handler_sys_t; 
     384typedef int (*httpd_handler_callback_t)( httpd_handler_sys_t *, httpd_handler_t *, uint8_t *psz_url, uint8_t *psz_request, int i_type, uint8_t *p_in, int i_in, char *psz_remote_addr, char *psz_remote_host, uint8_t **pp_data, int *pi_data ); 
    382385typedef struct httpd_redirect_t httpd_redirect_t; 
    383386typedef struct httpd_stream_t httpd_stream_t; 
     
    10521055VLC_EXPORT( int, vlc_iconv_close, ( vlc_iconv_t ) ); 
    10531056 
     1057/* execve wrapper (defined in src/extras/libc.c) */ 
     1058VLC_EXPORT( int, __vlc_execve, ( vlc_object_t *p_object, int i_argc, char **pp_argv, char **pp_env, char *psz_cwd, char *p_in, int i_in, char **pp_data, int *pi_data ) ); 
     1059#define vlc_execve(a,b,c,d,e,f,g,h,i) __vlc_execve(VLC_OBJECT(a),b,c,d,e,f,g,h,i) 
     1060 
    10541061/***************************************************************************** 
    10551062 * CPU capabilities 
  • include/vlc_httpd.h

    raed69fe rfe927c0  
    141141 
    142142 
     143VLC_EXPORT( httpd_handler_t *, httpd_HandlerNew, ( httpd_host_t *, const char *psz_url, const char *psz_user, const char *psz_password, const vlc_acl_t *p_acl, httpd_handler_callback_t pf_fill, httpd_handler_sys_t * ) ); 
     144VLC_EXPORT( void,           httpd_HandlerDelete, ( httpd_handler_t * ) ); 
     145 
     146 
    143147VLC_EXPORT( httpd_redirect_t *, httpd_RedirectNew, ( httpd_host_t *, const char *psz_url_dst, const char *psz_url_src ) ); 
    144148VLC_EXPORT( void,               httpd_RedirectDelete, ( httpd_redirect_t * ) ); 
  • include/vlc_symbols.h

    r3740e6a rfe927c0  
    167167void vlc_freeaddrinfo (struct addrinfo *); 
    168168void vlm_Delete (vlm_t *); 
     169void httpd_HandlerDelete (httpd_handler_t *); 
    169170void vout_DisplayPicture (vout_thread_t *, picture_t *); 
    170171void httpd_MsgClean (httpd_message_t *); 
     
    204205const char * vlc_gai_strerror (int); 
    205206void net_ListenClose (int *fd); 
     207int __vlc_execve (vlc_object_t *p_object, int i_argc, char **pp_argv, char **pp_env, char *psz_cwd, char *p_in, int i_in, char **pp_data, int *pi_data); 
    206208int playlist_NodeAppend (playlist_t *,int,playlist_item_t*,playlist_item_t *); 
    207209const iso639_lang_t * GetLang_2B (const char *); 
     
    358360void config_SetCallbacks (module_config_t *, module_config_t *); 
    359361int __vlc_cond_destroy (char *, int, vlc_cond_t *); 
     362httpd_handler_t * httpd_HandlerNew (httpd_host_t *, const char *psz_url, const char *psz_user, const char *psz_password, const vlc_acl_t *p_acl, httpd_handler_callback_t pf_fill, httpd_handler_sys_t *); 
    360363vlc_list_t * __vlc_list_find (vlc_object_t *, int, int); 
    361364char * ToLocale (const char *); 
     
    834837    int (*vlc_closedir_wrapper_inner) (void *); 
    835838    void * (*vlc_opendir_wrapper_inner) (const char *); 
     839    void (*httpd_HandlerDelete_inner) (httpd_handler_t *); 
     840    int (*__vlc_execve_inner) (vlc_object_t *p_object, int i_argc, char **pp_argv, char **pp_env, char *psz_cwd, char *p_in, int i_in, char **pp_data, int *pi_data); 
     841    httpd_handler_t * (*httpd_HandlerNew_inner) (httpd_host_t *, const char *psz_url, const char *psz_user, const char *psz_password, const vlc_acl_t *p_acl, httpd_handler_callback_t pf_fill, httpd_handler_sys_t *); 
    836842}; 
    837843#  if defined (__PLUGIN__) 
     
    12331239#  define vlc_closedir_wrapper (p_symbols)->vlc_closedir_wrapper_inner 
    12341240#  define vlc_opendir_wrapper (p_symbols)->vlc_opendir_wrapper_inner 
     1241#  define httpd_HandlerDelete (p_symbols)->httpd_HandlerDelete_inner 
     1242#  define __vlc_execve (p_symbols)->__vlc_execve_inner 
     1243#  define httpd_HandlerNew (p_symbols)->httpd_HandlerNew_inner 
    12351244#  elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__) 
    12361245/****************************************************************** 
     
    16351644    ((p_symbols)->vlc_closedir_wrapper_inner) = vlc_closedir_wrapper; \ 
    16361645    ((p_symbols)->vlc_opendir_wrapper_inner) = vlc_opendir_wrapper; \ 
     1646    ((p_symbols)->httpd_HandlerDelete_inner) = httpd_HandlerDelete; \ 
     1647    ((p_symbols)->__vlc_execve_inner) = __vlc_execve; \ 
     1648    ((p_symbols)->httpd_HandlerNew_inner) = httpd_HandlerNew; \ 
    16371649    (p_symbols)->net_ConvertIPv4_deprecated = NULL; \ 
    16381650    (p_symbols)->vlc_fix_readdir_charset_deprecated = NULL; \ 
  • modules/control/http/http.c

    r74764fb rfe927c0  
    4040#define CHARSET_LONGTEXT N_( \ 
    4141        "Charset declared in Content-Type header (default UTF-8)." ) 
     42#define HANDLERS_TEXT N_( "Handlers" ) 
     43#define HANDLERS_LONGTEXT N_( \ 
     44        "List of extensions and executable paths (for instance: " \ 
     45        "php=/usr/bin/php,pl=/usr/bin/perl)." ) 
    4246#define CERT_TEXT N_( "Certificate file" ) 
    4347#define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \ 
     
    5963        add_string ( "http-src",  NULL, NULL, SRC_TEXT,  SRC_LONGTEXT,  VLC_TRUE ); 
    6064        add_string ( "http-charset", "UTF-8", NULL, CHARSET_TEXT, CHARSET_LONGTEXT, VLC_TRUE ); 
     65#if defined( HAVE_FORK ) 
     66        add_string ( "http-handlers", NULL, NULL, HANDLERS_TEXT, HANDLERS_LONGTEXT, VLC_TRUE ); 
     67#endif 
    6168        set_section( N_("HTTP SSL" ), 0 ); 
    6269        add_string ( "http-intf-cert", NULL, NULL, CERT_TEXT, CERT_LONGTEXT, VLC_TRUE ); 
     
    109116    intf_thread_t *p_intf = (intf_thread_t*)p_this; 
    110117    intf_sys_t    *p_sys; 
    111     char          *psz_host; 
    112     char          *psz_address = ""; 
     118    char          *psz_address; 
    113119    const char    *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL, 
    114120                  *psz_crl = NULL; 
     
    116122    char          *psz_src; 
    117123 
    118     psz_host = config_GetPsz( p_intf, "http-host" ); 
    119     if( psz_host ) 
    120     { 
    121         char *psz_parser; 
    122         psz_address = psz_host; 
    123  
    124         psz_parser = strchr( psz_host, ':' ); 
     124    psz_address = config_GetPsz( p_intf, "http-host" ); 
     125    if( psz_address != NULL ) 
     126    { 
     127        char *psz_parser = strchr( psz_address, ':' ); 
    125128        if( psz_parser ) 
    126129        { 
     
    129132        } 
    130133    } 
     134    else 
     135        psz_address = strdup(""); 
    131136 
    132137    p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) ); 
     
    138143    p_sys->p_input    = NULL; 
    139144    p_sys->p_vlm      = NULL; 
     145    p_sys->psz_address = psz_address; 
     146    p_sys->i_port     = i_port; 
    140147 
    141148    /* determine Content-Type value for HTML pages */ 
     
    150157    if( p_sys->psz_html_type == NULL ) 
    151158    { 
     159        free( p_sys->psz_address ); 
    152160        free( p_sys ); 
    153161        free( psz_src ); 
     
    179187    free( psz_src ); 
    180188 
     189    /* determine file handler associations */ 
     190    p_sys->i_handlers = 0; 
     191    p_sys->pp_handlers = NULL; 
     192#if defined( HAVE_FORK ) 
     193    psz_src = config_GetPsz( p_intf, "http-handlers" ); 
     194    if( psz_src != NULL && *psz_src ) 
     195    { 
     196        char *p = psz_src; 
     197        while( p != NULL ) 
     198        { 
     199            http_association_t *p_handler; 
     200            char *psz_ext = p; 
     201            char *psz_program, *psz_options; 
     202            p = strchr( p, '=' ); 
     203            if( p == NULL ) break; 
     204            *p++ = '\0'; 
     205            psz_program = p; 
     206            p = strchr( p, ',' ); 
     207            if( p != NULL ) 
     208                *p++ = '\0'; 
     209 
     210            p_handler = malloc( sizeof( http_association_t ) ); 
     211            p_handler->psz_ext = strdup( psz_ext ); 
     212            psz_options = E_(FirstWord)( psz_program, psz_program ); 
     213            p_handler->i_argc = 0; 
     214            p_handler->ppsz_argv = NULL; 
     215            TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv, 
     216                        strdup( psz_program ) ); 
     217            while( psz_options != NULL && *psz_options ) 
     218            { 
     219                char *psz_next = E_(FirstWord)( psz_options, psz_options ); 
     220                TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv, 
     221                            strdup( psz_options ) ); 
     222                psz_options = psz_next; 
     223            } 
     224            /* NULL will be appended later on */ 
     225 
     226            TAB_APPEND( p_sys->i_handlers, p_sys->pp_handlers, p_handler ); 
     227        } 
     228    } 
     229    if( psz_src != NULL ) 
     230        free( psz_src ); 
     231#endif 
     232 
    181233    /* determine SSL configuration */ 
    182234    psz_cert = config_GetPsz( p_intf, "http-intf-cert" ); 
     
    207259        msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port ); 
    208260        free( p_sys->psz_html_type ); 
     261        free( p_sys->psz_address ); 
    209262        free( p_sys ); 
    210263        return VLC_EGENERIC; 
    211     } 
    212  
    213     if( psz_host ) 
    214     { 
    215         free( psz_host ); 
    216264    } 
    217265 
     
    226274        if( !psz_src ) return VLC_ENOMEM; 
    227275#if defined(WIN32) 
    228         sprintf( psz_src, "%s/http", psz_vlcpath); 
     276        sprintf( psz_src, "%s/http", psz_vlcpath ); 
    229277#else 
    230         sprintf( psz_src, "%s/share/http", psz_vlcpath); 
     278        sprintf( psz_src, "%s/share/http", psz_vlcpath ); 
    231279#endif 
    232280    } 
     
    280328    } 
    281329    httpd_HostDelete( p_sys->p_httpd_host ); 
     330    free( p_sys->psz_address ); 
    282331    free( p_sys->psz_html_type );  
    283332    if( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 ) 
     
    305354    for( i = 0; i < p_sys->i_files; i++ ) 
    306355    { 
    307        httpd_FileDelete( p_sys->pp_files[i]->p_file ); 
    308        if( p_sys->pp_files[i]->p_redir ) 
    309            httpd_RedirectDelete( p_sys->pp_files[i]->p_redir ); 
    310        if( p_sys->pp_files[i]->p_redir2 ) 
    311            httpd_RedirectDelete( p_sys->pp_files[i]->p_redir2 ); 
    312  
    313        free( p_sys->pp_files[i]->file ); 
    314        free( p_sys->pp_files[i]->name ); 
    315        free( p_sys->pp_files[i] ); 
     356        if( p_sys->pp_files[i]->b_handler ) 
     357            httpd_HandlerDelete( ((httpd_handler_sys_t *)p_sys->pp_files[i])->p_handler ); 
     358        else 
     359            httpd_FileDelete( p_sys->pp_files[i]->p_file ); 
     360        if( p_sys->pp_files[i]->p_redir ) 
     361            httpd_RedirectDelete( p_sys->pp_files[i]->p_redir ); 
     362        if( p_sys->pp_files[i]->p_redir2 ) 
     363            httpd_RedirectDelete( p_sys->pp_files[i]->p_redir2 ); 
     364 
     365        free( p_sys->pp_files[i]->file ); 
     366        free( p_sys->pp_files[i]->name ); 
     367        free( p_sys->pp_files[i] ); 
    316368    } 
    317369    if( p_sys->pp_files ) 
     
    319371        free( p_sys->pp_files ); 
    320372    } 
     373    for( i = 0; i < p_sys->i_handlers; i++ ) 
     374    { 
     375        http_association_t *p_handler = p_sys->pp_handlers[i]; 
     376        int j; 
     377        free( p_handler->psz_ext ); 
     378        for( j = 0; j < p_handler->i_argc; j++ ) 
     379            free( p_handler->ppsz_argv[j] ); 
     380        if( p_handler->i_argc ) 
     381            free( p_handler->ppsz_argv ); 
     382        free( p_handler ); 
     383    } 
     384    if( p_sys->i_handlers ) 
     385        free( p_sys->pp_handlers ); 
    321386    httpd_HostDelete( p_sys->p_httpd_host ); 
     387    free( p_sys->psz_address ); 
    322388    free( p_sys->psz_html_type ); 
    323389 
     
    383449 **************************************************************************** 
    384450 * a file with b_html is parsed and all "macro" replaced 
    385  * <vlc id="macro name" [param1="" [param2=""]] /> 
    386  * valid id are 
    387  * 
    388451 ****************************************************************************/ 
     452static void Callback404( httpd_file_sys_t *p_args, char **pp_data, 
     453                         int *pi_data ) 
     454{ 
     455    char *p = *pp_data = malloc( 10240 ); 
     456    if( !p ) 
     457    { 
     458        return; 
     459    } 
     460    p += sprintf( p, "<html>\n" ); 
     461    p += sprintf( p, "<head>\n" ); 
     462    p += sprintf( p, "<title>Error loading %s</title>\n", p_args->file ); 
     463    p += sprintf( p, "</head>\n" ); 
     464    p += sprintf( p, "<body>\n" ); 
     465    p += sprintf( p, "<h1><center>Error loading %s for %s</center></h1>\n", p_args->file, p_args->name ); 
     466    p += sprintf( p, "<hr />\n" ); 
     467    p += sprintf( p, "<a href=\"http://www.videolan.org/\">VideoLAN</a>\n" ); 
     468    p += sprintf( p, "</body>\n" ); 
     469    p += sprintf( p, "</html>\n" ); 
     470 
     471    *pi_data = strlen( *pp_data ); 
     472} 
     473 
     474static void ParseExecute( httpd_file_sys_t *p_args, char *p_buffer, 
     475                          int i_buffer, char *p_request, 
     476                          char **pp_data, int *pi_data ) 
     477{ 
     478    int i_request = p_request != NULL ? strlen( p_request ) : 0; 
     479    char *dst; 
     480    vlc_value_t val; 
     481    char position[4]; /* percentage */ 
     482    char time[12]; /* in seconds */ 
     483    char length[12]; /* in seconds */ 
     484    audio_volume_t i_volume; 
     485    char volume[5]; 
     486    char state[8]; 
     487 
     488#define p_sys p_args->p_intf->p_sys 
     489    if( p_sys->p_input ) 
     490    { 
     491        var_Get( p_sys->p_input, "position", &val); 
     492        sprintf( position, "%d" , (int)((val.f_float) * 100.0)); 
     493        var_Get( p_sys->p_input, "time", &val); 
     494        sprintf( time, "%d" , (int)(val.i_time / 1000000) ); 
     495        var_Get( p_sys->p_input, "length", &val); 
     496        sprintf( length, "%d" , (int)(val.i_time / 1000000) ); 
     497 
     498        var_Get( p_sys->p_input, "state", &val ); 
     499        if( val.i_int == PLAYING_S ) 
     500        { 
     501            sprintf( state, "playing" ); 
     502        } 
     503        else if( val.i_int == PAUSE_S ) 
     504        { 
     505            sprintf( state, "paused" ); 
     506        } 
     507        else 
     508        { 
     509            sprintf( state, "stop" ); 
     510        } 
     511    } 
     512    else 
     513    { 
     514        sprintf( position, "%d", 0 ); 
     515        sprintf( time, "%d", 0 ); 
     516        sprintf( length, "%d", 0 ); 
     517        sprintf( state, "stop" ); 
     518    } 
     519#undef p_sys 
     520 
     521    aout_VolumeGet( p_args->p_intf, &i_volume ); 
     522    sprintf( volume, "%d", (int)i_volume ); 
     523 
     524    p_args->vars = E_(mvar_New)( "variables", "" ); 
     525    E_(mvar_AppendNewVar)( p_args->vars, "url_param", 
     526                           i_request > 0 ? "1" : "0" ); 
     527    E_(mvar_AppendNewVar)( p_args->vars, "url_value", p_request ); 
     528    E_(mvar_AppendNewVar)( p_args->vars, "version", VLC_Version() ); 
     529    E_(mvar_AppendNewVar)( p_args->vars, "copyright", COPYRIGHT_MESSAGE ); 
     530    E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_by", VLC_CompileBy() ); 
     531    E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_host", 
     532                       VLC_CompileHost() ); 
     533    E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_domain", 
     534                       VLC_CompileDomain() ); 
     535    E_(mvar_AppendNewVar)( p_args->vars, "vlc_compiler", VLC_Compiler() ); 
     536    E_(mvar_AppendNewVar)( p_args->vars, "vlc_changeset", VLC_Changeset() ); 
     537    E_(mvar_AppendNewVar)( p_args->vars, "stream_position", position ); 
     538    E_(mvar_AppendNewVar)( p_args->vars, "stream_time", time ); 
     539    E_(mvar_AppendNewVar)( p_args->vars, "stream_length", length ); 
     540    E_(mvar_AppendNewVar)( p_args->vars, "volume", volume ); 
     541    E_(mvar_AppendNewVar)( p_args->vars, "stream_state", state ); 
     542 
     543    E_(SSInit)( &p_args->stack ); 
     544 
     545    /* allocate output */ 
     546    *pi_data = i_buffer + 1000; 
     547    dst = *pp_data = malloc( *pi_data ); 
     548 
     549    /* we parse executing all  <vlc /> macros */ 
     550    E_(Execute)( p_args, p_request, i_request, pp_data, pi_data, &dst, 
     551                 &p_buffer[0], &p_buffer[i_buffer] ); 
     552 
     553    *dst     = '\0'; 
     554    *pi_data = dst - *pp_data; 
     555 
     556    E_(SSClean)( &p_args->stack ); 
     557    E_(mvar_Delete)( p_args->vars ); 
     558} 
     559 
    389560int  E_(HttpCallback)( httpd_file_sys_t *p_args, 
    390561                       httpd_file_t *p_file, 
     
    394565    char *p_request = (char *)_p_request; 
    395566    char **pp_data = (char **)_pp_data; 
    396     int i_request = p_request ? strlen( p_request ) : 0; 
    397     char *p; 
    398567    FILE *f; 
    399568 
    400569    if( ( f = fopen( p_args->file, "r" ) ) == NULL ) 
    401570    { 
    402         p = *pp_data = malloc( 10240 ); 
    403         if( !p ) 
    404         { 
    405                 return VLC_EGENERIC; 
    406         } 
    407         p += sprintf( p, "<html>\n" ); 
    408         p += sprintf( p, "<head>\n" ); 
    409         p += sprintf( p, "<title>Error loading %s</title>\n", p_args->file ); 
    410         p += sprintf( p, "</head>\n" ); 
    411         p += sprintf( p, "<body>\n" ); 
    412         p += sprintf( p, "<h1><center>Error loading %s for %s</center></h1>\n", p_args->file, p_args->name ); 
    413         p += sprintf( p, "<hr />\n" ); 
    414         p += sprintf( p, "<a href=\"http://www.videolan.org/\">VideoLAN</a>\n" ); 
    415         p += sprintf( p, "</body>\n" ); 
    416         p += sprintf( p, "</html>\n" ); 
    417  
    418         *pi_data = strlen( *pp_data ); 
    419  
     571        Callback404( p_args, pp_data, pi_data ); 
    420572        return VLC_SUCCESS; 
    421573    } 
     
    429581        int  i_buffer; 
    430582        char *p_buffer; 
    431         char *dst; 
    432         vlc_value_t val; 
    433         char position[4]; /* percentage */ 
    434         char time[12]; /* in seconds */ 
    435         char length[12]; /* in seconds */ 
    436         audio_volume_t i_volume; 
    437         char volume[5]; 
    438         char state[8]; 
    439   
    440 #define p_sys p_args->p_intf->p_sys 
    441         if( p_sys->p_input ) 
    442         { 
    443             var_Get( p_sys->p_input, "position", &val); 
    444             sprintf( position, "%d" , (int)((val.f_float) * 100.0)); 
    445             var_Get( p_sys->p_input, "time", &val); 
    446             sprintf( time, "%d" , (int)(val.i_time / 1000000) ); 
    447             var_Get( p_sys->p_input, "length", &val); 
    448             sprintf( length, "%d" , (int)(val.i_time / 1000000) ); 
    449  
    450             var_Get( p_sys->p_input, "state", &val ); 
    451             if( val.i_int == PLAYING_S ) 
    452             { 
    453                 sprintf( state, "playing" ); 
    454             } 
    455             else if( val.i_int == PAUSE_S ) 
    456             { 
    457                 sprintf( state, "paused" ); 
    458             } 
    459             else 
    460             { 
    461                 sprintf( state, "stop" ); 
    462             } 
    463         } 
    464         else 
    465         { 
    466             sprintf( position, "%d", 0 ); 
    467             sprintf( time, "%d", 0 ); 
    468             sprintf( length, "%d", 0 ); 
    469             sprintf( state, "stop" ); 
    470         } 
    471 #undef p_sys 
    472  
    473         aout_VolumeGet( p_args->p_intf , &i_volume ); 
    474         sprintf( volume , "%d" , (int)i_volume ); 
    475  
    476         p_args->vars = E_(mvar_New)( "variables", "" ); 
    477         E_(mvar_AppendNewVar)( p_args->vars, "url_param", 
    478                            i_request > 0 ? "1" : "0" ); 
    479         E_(mvar_AppendNewVar)( p_args->vars, "url_value", p_request ); 
    480         E_(mvar_AppendNewVar)( p_args->vars, "version", VLC_Version() ); 
    481         E_(mvar_AppendNewVar)( p_args->vars, "copyright", COPYRIGHT_MESSAGE ); 
    482         E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_by", VLC_CompileBy() ); 
    483         E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_host", 
    484                            VLC_CompileHost() ); 
    485         E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_domain", 
    486                            VLC_CompileDomain() ); 
    487         E_(mvar_AppendNewVar)( p_args->vars, "vlc_compiler", VLC_Compiler() ); 
    488         E_(mvar_AppendNewVar)( p_args->vars, "vlc_changeset", VLC_Changeset() ); 
    489         E_(mvar_AppendNewVar)( p_args->vars, "stream_position", position ); 
    490         E_(mvar_AppendNewVar)( p_args->vars, "stream_time", time ); 
    491         E_(mvar_AppendNewVar)( p_args->vars, "stream_length", length ); 
    492         E_(mvar_AppendNewVar)( p_args->vars, "volume", volume ); 
    493         E_(mvar_AppendNewVar)( p_args->vars, "stream_state", state ); 
    494  
    495         E_(SSInit)( &p_args->stack ); 
    496583 
    497584        /* first we load in a temporary buffer */ 
    498585        E_(FileLoad)( f, &p_buffer, &i_buffer ); 
    499586 
    500         /* allocate output */ 
    501         *pi_data = i_buffer + 1000; 
    502         dst = *pp_data = malloc( *pi_data ); 
    503  
    504         /* we parse executing all  <vlc /> macros */ 
    505         E_(Execute)( p_args, p_request, i_request, pp_data, pi_data, &dst, 
    506                      &p_buffer[0], &p_buffer[i_buffer] ); 
    507  
    508         *dst     = '\0'; 
    509         *pi_data = dst - *pp_data; 
    510  
    511         E_(SSClean)( &p_args->stack ); 
    512         E_(mvar_Delete)( p_args->vars ); 
     587        ParseExecute( p_args, p_buffer, i_buffer, p_request, pp_data, pi_data ); 
     588 
    513589        free( p_buffer ); 
    514590    } 
     
    519595} 
    520596 
     597/**************************************************************************** 
     598 * HandlerCallback: 
     599 **************************************************************************** 
     600 * call the external handler and parse vlc macros if Content-Type is HTML 
     601 ****************************************************************************/ 
     602int  E_(HandlerCallback)( httpd_handler_sys_t *p_args, 
     603                          httpd_handler_t *p_handler, uint8_t *_p_url, 
     604                          uint8_t *_p_request, int i_type, 
     605                          uint8_t *_p_in, int i_in, 
     606                          char *psz_remote_addr, char *psz_remote_host, 
     607                          uint8_t **_pp_data, int *pi_data ) 
     608{ 
     609    char *p_url = (char *)_p_url; 
     610    char *p_request = (char *)_p_request; 
     611    char **pp_data = (char **)_pp_data; 
     612    char *p_in = (char *)p_in; 
     613    int i_request = p_request != NULL ? strlen( p_request ) : 0; 
     614    char *p; 
     615    int i_env = 0; 
     616    char **pp_env = NULL; 
     617    char *psz_tmp; 
     618    char sep; 
     619    int  i_buffer; 
     620    char *p_buffer; 
     621    char *psz_cwd; 
     622 
     623#ifdef WIN32 
     624    sep = '\\'; 
     625#else 
     626    sep = '/'; 
     627#endif 
     628 
     629    /* Create environment for the CGI */ 
     630    TAB_APPEND( i_env, pp_env, strdup("GATEWAY_INTERFACE=CGI/1.1") ); 
     631    TAB_APPEND( i_env, pp_env, strdup("SERVER_PROTOCOL=HTTP/1.1") ); 
     632    TAB_APPEND( i_env, pp_env, strdup("SERVER_SOFTWARE=" COPYRIGHT_MESSAGE) ); 
     633 
     634    switch( i_type ) 
     635    { 
     636    case HTTPD_MSG_GET: 
     637        TAB_APPEND( i_env, pp_env, strdup("REQUEST_METHOD=GET") ); 
     638        break; 
     639    case HTTPD_MSG_POST: 
     640        TAB_APPEND( i_env, pp_env, strdup("REQUEST_METHOD=POST") ); 
     641        break; 
     642    case HTTPD_MSG_HEAD: 
     643        TAB_APPEND( i_env, pp_env, strdup("REQUEST_METHOD=HEAD") ); 
     644        break; 
     645    default: 
     646        break; 
     647    } 
     648 
     649    if( i_request ) 
     650    { 
     651        psz_tmp = malloc( sizeof("QUERY_STRING=") + i_request ); 
     652        sprintf( psz_tmp, "QUERY_STRING=%s", p_request ); 
     653        TAB_APPEND( i_env, pp_env, psz_tmp ); 
     654 
     655        psz_tmp = malloc( sizeof("REQUEST_URI=?") + strlen(p_url) 
     656                           + i_request ); 
     657        sprintf( psz_tmp, "REQUEST_URI=%s?%s", p_url, p_request ); 
     658        TAB_APPEND( i_env, pp_env, psz_tmp ); 
     659    } 
     660    else 
     661    { 
     662        psz_tmp = malloc( sizeof("REQUEST_URI=") + strlen(p_url) ); 
     663        sprintf( psz_tmp, "REQUEST_URI=%s", p_url ); 
     664        TAB_APPEND( i_env, pp_env, psz_tmp ); 
     665    } 
     666 
     667    psz_tmp = malloc( sizeof("SCRIPT_NAME=") + strlen(p_url) ); 
     668    sprintf( psz_tmp, "SCRIPT_NAME=%s", p_url ); 
     669    TAB_APPEND( i_env, pp_env, psz_tmp ); 
     670 
     671    psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(p_args->file.file) ); 
     672    sprintf( psz_tmp, "SCRIPT_FILENAME=%s", p_args->file.file ); 
     673    TAB_APPEND( i_env, pp_env, psz_tmp ); 
     674 
     675#define p_sys p_args->file.p_intf->p_sys 
     676    psz_tmp = malloc( sizeof("SERVER_NAME=") + strlen(p_sys->psz_address) ); 
     677    sprintf( psz_tmp, "SERVER_NAME=%s", p_sys->psz_address ); 
     678    TAB_APPEND( i_env, pp_env, psz_tmp ); 
     679 
     680    psz_tmp = malloc( sizeof("SERVER_PORT=") + 5 ); 
     681    sprintf( psz_tmp, "SERVER_PORT=%u", p_sys->i_port ); 
     682    TAB_APPEND( i_env, pp_env, psz_tmp ); 
     683#undef p_sys 
     684 
     685    if( psz_remote_addr != NULL && *psz_remote_addr ) 
     686    { 
     687        psz_tmp = malloc( sizeof("REMOTE_ADDR=") + strlen(psz_remote_addr) ); 
     688        sprintf( psz_tmp, "REMOTE_ADDR=%s", psz_remote_addr ); 
     689        TAB_APPEND( i_env, pp_env, psz_tmp ); 
     690    } 
     691 
     692    if( psz_remote_host != NULL && *psz_remote_host ) 
     693    { 
     694        psz_tmp = malloc( sizeof("REMOTE_HOST=") + strlen(psz_remote_host) ); 
     695        sprintf( psz_tmp, "REMOTE_HOST=%s", psz_remote_host ); 
     696        TAB_APPEND( i_env, pp_env, psz_tmp ); 
     697    } 
     698 
     699    if( i_in ) 
     700    { 
     701        p = p_in; 
     702        for ( ; ; ) 
     703        { 
     704            if( !strncmp( p, "Content-Type: ", strlen("Content-Type: ") ) ) 
     705            { 
     706                char *end = strchr( p, '\r' ); 
     707                if( end == NULL ) 
     708                    break; 
     709                *end = '\0'; 
     710                psz_tmp = malloc( sizeof("CONTENT_TYPE=") + strlen(p) ); 
     711                sprintf( psz_tmp, "CONTENT_TYPE=%s", p ); 
     712                TAB_APPEND( i_env, pp_env, psz_tmp ); 
     713                *end = '\r'; 
     714            } 
     715            if( !strncmp( p, "Content-Length: ", strlen("Content-Length: ") ) ) 
     716            { 
     717                char *end = strchr( p, '\r' ); 
     718                if( end == NULL ) 
     719                    break; 
     720                *end = '\0'; 
     721                psz_tmp = malloc( sizeof("CONTENT_LENGTH=") + strlen(p) ); 
     722                sprintf( psz_tmp, "CONTENT_LENGTH=%s", p ); 
     723                TAB_APPEND( i_env, pp_env, psz_tmp ); 
     724                *end = '\r'; 
     725            } 
     726 
     727            p = strchr( p, '\n' ); 
     728            if( p == NULL || p[1] == '\r' ) 
     729            { 
     730                p = NULL; 
     731                break; 
     732            } 
     733            p++; 
     734        } 
     735    } 
     736 
     737    TAB_APPEND( i_env, pp_env, NULL ); 
     738 
     739    TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, 
     740                p_args->file.file ); 
     741    TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, 
     742                NULL ); 
     743 
     744    psz_tmp = strdup( p_args->file.file ); 
     745    p = strrchr( psz_tmp, sep ); 
     746    if( p != NULL ) 
     747    { 
     748        *p = '\0'; 
     749        psz_cwd = psz_tmp; 
     750    } 
     751    else 
     752    { 
     753        free( psz_tmp ); 
     754        psz_cwd = NULL; 
     755    } 
     756 
     757    if( vlc_execve( p_args->file.p_intf, p_args->p_association->i_argc, 
     758                    p_args->p_association->ppsz_argv, pp_env, psz_cwd, 
     759                    (char *)p_in, i_in, &p_buffer, &i_buffer ) == -1 ) 
     760    { 
     761        TAB_REMOVE( p_args->p_association->i_argc, 
     762                    p_args->p_association->ppsz_argv, NULL ); 
     763        TAB_REMOVE( p_args->p_association->i_argc, 
     764                    p_args->p_association->ppsz_argv, p_args->file.file ); 
     765        if( psz_cwd != NULL ) 
     766            free( psz_cwd ); 
     767 
     768        Callback404( (httpd_file_sys_t *)p_args, pp_data, pi_data ); 
     769        return VLC_SUCCESS; 
     770    } 
     771    TAB_REMOVE( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, 
     772                NULL ); 
     773    TAB_REMOVE( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, 
     774                p_args->file.file ); 
     775    if( psz_cwd != NULL ) 
     776        free( psz_cwd ); 
     777 
     778    p = p_buffer; 
     779    while( strncmp( p, "Content-Type: text/html", 
     780                    strlen("Content-Type: text/html") ) ) 
     781    { 
     782        p = strchr( p, '\n' ); 
     783        if( p == NULL || p[1] == '\r' ) 
     784        { 
     785            p = NULL; 
     786            break; 
     787        } 
     788        p++; 
     789    } 
     790 
     791    if( p == NULL ) 
     792    { 
     793        *pp_data = p_buffer; 
     794        *pi_data = i_buffer; 
     795    } 
     796    else 
     797    { 
     798        ParseExecute( (httpd_file_sys_t *)p_args, p_buffer, i_buffer, 
     799                      p_request, pp_data, pi_data ); 
     800 
     801        free( p_buffer ); 
     802    } 
     803 
     804    return VLC_SUCCESS; 
     805} 
  • modules/control/http/http.h

    rd80b925 rfe927c0  
    335335    char          *name; 
    336336 
    337     vlc_bool_t    b_html
     337    vlc_bool_t    b_html, b_handler
    338338 
    339339    /* inited for each access */ 
     
    343343 
    344344/** \struct 
     345 * Structure associating an extension to an external program 
     346 */ 
     347typedef struct http_association_t 
     348{ 
     349    char                *psz_ext; 
     350    int                 i_argc; 
     351    char                **ppsz_argv; 
     352} http_association_t; 
     353 
     354/** \struct 
     355 * This structure represent a single CGI file to be parsed by the macros 
     356 * handling engine */ 
     357struct httpd_handler_sys_t 
     358{ 
     359    httpd_file_sys_t file; 
     360 
     361    /* HACK ALERT: this is added below so that casting httpd_handler_sys_t 
     362     * to httpd_file_sys_t works */ 
     363    httpd_handler_t  *p_handler; 
     364    http_association_t *p_association; 
     365}; 
     366 
     367/** \struct 
    345368 * Internal service structure for the HTTP interface 
    346369 */ 
     
    351374    int                 i_files; 
    352375    httpd_file_sys_t    **pp_files; 
     376 
     377    int                 i_handlers; 
     378    http_association_t  **pp_handlers; 
    353379 
    354380    playlist_t          *p_playlist; 
     
    357383    char                *psz_html_type; 
    358384    vlc_iconv_t         iconv_from_utf8, iconv_to_utf8; 
     385 
     386    char                *psz_address; 
     387    unsigned short      i_port; 
    359388}; 
    360389 
     
    364393                      uint8_t *p_request, 
    365394                      uint8_t **pp_data, int *pi_data ); 
     395/** This function is the HTTPD Callback used for CGIs */ 
     396int  E_(HandlerCallback)( httpd_handler_sys_t *p_args, 
     397                          httpd_handler_t *p_handler, uint8_t *_p_url, 
     398                          uint8_t *_p_request, int i_type, 
     399                          uint8_t *_p_in, int i_in, 
     400                          char *psz_remote_addr, char *psz_remote_host, 
     401                          uint8_t **_pp_data, int *pi_data ); 
    366402/**@}*/ 
    367403 
  • modules/control/http/util.c

    rd80b925 rfe927c0  
    102102/* Parse a directory and recursively add files */ 
    103103int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root, 
    104                            char *psz_dir ) 
     104                        char *psz_dir ) 
    105105{ 
    106106    intf_sys_t     *p_sys = p_intf->p_sys; 
     
    206206        if( E_(ParseDirectory)( p_intf, psz_root, dir ) ) 
    207207        { 
    208             httpd_file_sys_t *f = malloc( sizeof( httpd_file_sys_t ) ); 
     208            httpd_file_sys_t *f = NULL; 
     209            httpd_handler_sys_t *h = NULL; 
    209210            vlc_bool_t b_index; 
    210             char *psz_tmp; 
     211            char *psz_tmp, *psz_file, *psz_name, *psz_ext; 
     212 
     213            psz_tmp = vlc_fix_readdir_charset( p_intf, dir ); 
     214            psz_file = E_(FromUTF8)( p_intf, psz_tmp ); 
     215            free( psz_tmp ); 
     216            psz_tmp = vlc_fix_readdir_charset( p_intf, 
     217                                               &dir[strlen( psz_root )] ); 
     218            psz_name = E_(FileToUrl)( psz_tmp, &b_index ); 
     219            free( psz_tmp ); 
     220            psz_ext = strrchr( psz_file, '.' ); 
     221            if( psz_ext != NULL ) 
     222            { 
     223                int i; 
     224                psz_ext++; 
     225                for( i = 0; i < p_sys->i_handlers; i++ ) 
     226                    if( !strcmp( p_sys->pp_handlers[i]->psz_ext, psz_ext ) ) 
     227                        break; 
     228                if( i < p_sys->i_handlers ) 
     229                { 
     230                    f = malloc( sizeof( httpd_handler_sys_t ) ); 
     231                    h = (httpd_handler_sys_t *)f; 
     232                    f->b_handler = VLC_TRUE; 
     233                    h->p_association = p_sys->pp_handlers[i]; 
     234                } 
     235            } 
     236            if( f == NULL ) 
     237            { 
     238                f = malloc( sizeof( httpd_file_sys_t ) ); 
     239                f->b_handler = VLC_FALSE; 
     240            } 
    211241 
    212242            f->p_intf  = p_intf; 
     
    214244            f->p_redir = NULL; 
    215245            f->p_redir2 = NULL; 
    216             psz_tmp = vlc_fix_readdir_charset( p_intf, dir ); 
    217             f->file = E_(FromUTF8)( p_intf, psz_tmp ); 
    218             free( psz_tmp ); 
    219             psz_tmp = vlc_fix_readdir_charset( p_intf, 
    220                                                &dir[strlen( psz_root )] ); 
    221             f->name = E_(FileToUrl)( psz_tmp, &b_index ); 
    222             free( psz_tmp ); 
     246            f->file = psz_file; 
     247            f->name = psz_name; 
    223248            f->b_html = strstr( &dir[strlen( psz_root )], ".htm" ) ? VLC_TRUE : VLC_FALSE; 
    224249 
     
    233258                     f->file, f->name ); 
    234259 
    235             f->p_file = httpd_FileNew( p_sys->p_httpd_host, 
    236                                        f->name, 
    237                                        f->b_html ? p_sys->psz_html_type : NULL, 
    238                                        user, password, p_acl, 
    239                                        E_(HttpCallback), f ); 
    240  
    241             if( f->p_file ) 
    242             { 
    243                 TAB_APPEND( p_sys->i_files, p_sys->pp_files, f ); 
    244             } 
     260            if( !f->b_handler ) 
     261            { 
     262                f->p_file = httpd_FileNew( p_sys->p_httpd_host, 
     263                                           f->name, 
     264                                           f->b_html ? p_sys->psz_html_type : 
     265                                            NULL, 
     266                                           user, password, p_acl, 
     267                                           E_(HttpCallback), f ); 
     268                if( f->p_file != NULL ) 
     269                { 
     270                    TAB_APPEND( p_sys->i_files, p_sys->pp_files, f ); 
     271                } 
     272            } 
     273            else 
     274            { 
     275                h->p_handler = httpd_HandlerNew( p_sys->p_httpd_host, 
     276                                                 f->name, 
     277</