Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

http.c

00001 /*****************************************************************************
00002  * http.c : HTTP/HTTPS Remote control interface
00003  *****************************************************************************
00004  * Copyright (C) 2001-2005 the VideoLAN team
00005  * $Id: http.c 12449 2005-09-02 17:11:23Z massiot $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *          Laurent Aimar <[email protected]>
00009  *          Christophe Massiot <[email protected]>
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00024  *****************************************************************************/
00025 
00026 #include "http.h"
00027 
00028 /*****************************************************************************
00029  * Module descriptor
00030  *****************************************************************************/
00031 static int  Open ( vlc_object_t * );
00032 static void Close( vlc_object_t * );
00033 
00034 #define HOST_TEXT N_( "Host address" )
00035 #define HOST_LONGTEXT N_( \
00036     "You can set the address and port the http interface will bind to." )
00037 #define SRC_TEXT N_( "Source directory" )
00038 #define SRC_LONGTEXT N_( "Source directory" )
00039 #define CHARSET_TEXT N_( "Charset" )
00040 #define CHARSET_LONGTEXT N_( \
00041         "Charset declared in Content-Type header (default UTF-8)." )
00042 #define HANDLERS_TEXT N_( "Handlers" )
00043 #define HANDLERS_LONGTEXT N_( \
00044         "List of extensions and executable paths (for instance: " \
00045         "php=/usr/bin/php,pl=/usr/bin/perl)." )
00046 #define CERT_TEXT N_( "Certificate file" )
00047 #define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \
00048                           "(enables SSL)" )
00049 #define KEY_TEXT N_( "Private key file" )
00050 #define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )
00051 #define CA_TEXT N_( "Root CA file" )
00052 #define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \
00053                         "certificates file" )
00054 #define CRL_TEXT N_( "CRL file" )
00055 #define CRL_LONGTEXT N_( "HTTP interace Certificates Revocation List file" )
00056 
00057 vlc_module_begin();
00058     set_shortname( _("HTTP"));
00059     set_description( _("HTTP remote control interface") );
00060     set_category( CAT_INTERFACE );
00061     set_subcategory( SUBCAT_INTERFACE_GENERAL );
00062         add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE );
00063         add_string ( "http-src",  NULL, NULL, SRC_TEXT,  SRC_LONGTEXT,  VLC_TRUE );
00064         add_string ( "http-charset", "UTF-8", NULL, CHARSET_TEXT, CHARSET_LONGTEXT, VLC_TRUE );
00065 #if defined( HAVE_FORK ) || defined( WIN32 )
00066         add_string ( "http-handlers", NULL, NULL, HANDLERS_TEXT, HANDLERS_LONGTEXT, VLC_TRUE );
00067 #endif
00068         set_section( N_("HTTP SSL" ), 0 );
00069         add_string ( "http-intf-cert", NULL, NULL, CERT_TEXT, CERT_LONGTEXT, VLC_TRUE );
00070         add_string ( "http-intf-key",  NULL, NULL, KEY_TEXT,  KEY_LONGTEXT,  VLC_TRUE );
00071         add_string ( "http-intf-ca",   NULL, NULL, CA_TEXT,   CA_LONGTEXT,   VLC_TRUE );
00072         add_string ( "http-intf-crl",  NULL, NULL, CRL_TEXT,  CRL_LONGTEXT,  VLC_TRUE );
00073     set_capability( "interface", 0 );
00074     set_callbacks( Open, Close );
00075 vlc_module_end();
00076 
00077 
00078 /*****************************************************************************
00079  * Local prototypes
00080  *****************************************************************************/
00081 static void Run          ( intf_thread_t *p_intf );
00082 
00083 /*****************************************************************************
00084  * Local functions
00085  *****************************************************************************/
00086 #if !defined(SYS_DARWIN) && !defined(SYS_BEOS) && !defined(WIN32)
00087 static int DirectoryCheck( char *psz_dir )
00088 {
00089     DIR           *p_dir;
00090 
00091 #ifdef HAVE_SYS_STAT_H
00092     struct stat   stat_info;
00093 
00094     if( stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) )
00095     {
00096         return VLC_EGENERIC;
00097     }
00098 #endif
00099 
00100     if( ( p_dir = opendir( psz_dir ) ) == NULL )
00101     {
00102         return VLC_EGENERIC;
00103     }
00104     closedir( p_dir );
00105 
00106     return VLC_SUCCESS;
00107 }
00108 #endif
00109 
00110 
00111 /*****************************************************************************
00112  * Activate: initialize and create stuff
00113  *****************************************************************************/
00114 static int Open( vlc_object_t *p_this )
00115 {
00116     intf_thread_t *p_intf = (intf_thread_t*)p_this;
00117     intf_sys_t    *p_sys;
00118     char          *psz_address;
00119     const char    *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,
00120                   *psz_crl = NULL;
00121     int           i_port       = 0;
00122     char          *psz_src;
00123     char          psz_tmp[10];
00124 
00125     psz_address = config_GetPsz( p_intf, "http-host" );
00126     if( psz_address != NULL )
00127     {
00128         char *psz_parser = strchr( psz_address, ':' );
00129         if( psz_parser )
00130         {
00131             *psz_parser++ = '\0';
00132             i_port = atoi( psz_parser );
00133         }
00134     }
00135     else
00136         psz_address = strdup("");
00137 
00138     p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );
00139     if( !p_intf->p_sys )
00140     {
00141         return( VLC_ENOMEM );
00142     }
00143     p_sys->p_playlist = NULL;
00144     p_sys->p_input    = NULL;
00145     p_sys->p_vlm      = NULL;
00146     p_sys->psz_address = psz_address;
00147     p_sys->i_port     = i_port;
00148 
00149     /* determine Content-Type value for HTML pages */
00150     psz_src = config_GetPsz( p_intf, "http-charset" );
00151     if( psz_src == NULL || !*psz_src )
00152     {
00153         if( psz_src != NULL ) free( psz_src );
00154         psz_src = strdup("UTF-8");
00155     }
00156 
00157     p_sys->psz_html_type = malloc( 20 + strlen( psz_src ) );
00158     if( p_sys->psz_html_type == NULL )
00159     {
00160         free( p_sys->psz_address );
00161         free( p_sys );
00162         free( psz_src );
00163         return VLC_ENOMEM ;
00164     }
00165     sprintf( p_sys->psz_html_type, "text/html; charset=%s", psz_src );
00166     msg_Dbg( p_intf, "using charset=%s", psz_src );
00167 
00168     if( strcmp( psz_src, "UTF-8" ) )
00169     {
00170         p_sys->iconv_from_utf8 = vlc_iconv_open( psz_src, "UTF-8" );
00171         if( p_sys->iconv_from_utf8 == (vlc_iconv_t)-1 )
00172             msg_Warn( p_intf, "unable to perform charset conversion to %s",
00173                       psz_src );
00174         else
00175         {
00176             p_sys->iconv_to_utf8 = vlc_iconv_open( "UTF-8", psz_src );
00177             if( p_sys->iconv_to_utf8 == (vlc_iconv_t)-1 )
00178                 msg_Warn( p_intf,
00179                           "unable to perform charset conversion from %s",
00180                           psz_src );
00181         }
00182     }
00183     else
00184     {
00185         p_sys->iconv_from_utf8 = p_sys->iconv_to_utf8 = (vlc_iconv_t)-1;
00186     }
00187 
00188     free( psz_src );
00189 
00190     /* determine file handler associations */
00191     p_sys->i_handlers = 0;
00192     p_sys->pp_handlers = NULL;
00193 #if defined( HAVE_FORK ) || defined( WIN32 )
00194     psz_src = config_GetPsz( p_intf, "http-handlers" );
00195     if( psz_src != NULL && *psz_src )
00196     {
00197         char *p = psz_src;
00198         while( p != NULL )
00199         {
00200             http_association_t *p_handler;
00201             char *psz_ext = p;
00202             char *psz_program, *psz_options;
00203             p = strchr( p, '=' );
00204             if( p == NULL ) break;
00205             *p++ = '\0';
00206             psz_program = p;
00207             p = strchr( p, ',' );
00208             if( p != NULL )
00209                 *p++ = '\0';
00210 
00211             p_handler = malloc( sizeof( http_association_t ) );
00212             p_handler->psz_ext = strdup( psz_ext );
00213             psz_options = E_(FirstWord)( psz_program, psz_program );
00214             p_handler->i_argc = 0;
00215             p_handler->ppsz_argv = NULL;
00216             TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv,
00217                         strdup( psz_program ) );
00218             while( psz_options != NULL && *psz_options )
00219             {
00220                 char *psz_next = E_(FirstWord)( psz_options, psz_options );
00221                 TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv,
00222                             strdup( psz_options ) );
00223                 psz_options = psz_next;
00224             }
00225             /* NULL will be appended later on */
00226 
00227             TAB_APPEND( p_sys->i_handlers, p_sys->pp_handlers, p_handler );
00228         }
00229     }
00230     if( psz_src != NULL )
00231         free( psz_src );
00232 #endif
00233 
00234     /* determine SSL configuration */
00235     psz_cert = config_GetPsz( p_intf, "http-intf-cert" );
00236     if ( psz_cert != NULL )
00237     {
00238         msg_Dbg( p_intf, "enabling TLS for HTTP interface (cert file: %s)",
00239                  psz_cert );
00240         psz_key = config_GetPsz( p_intf, "http-intf-key" );
00241         psz_ca = config_GetPsz( p_intf, "http-intf-ca" );
00242         psz_crl = config_GetPsz( p_intf, "http-intf-crl" );
00243 
00244         if( i_port <= 0 )
00245             i_port = 8443;
00246     }
00247     else
00248     {
00249         if( i_port <= 0 )
00250             i_port= 8080;
00251     }
00252 
00253     /* Ugly hack to allow to run several HTTP servers on different ports. */
00254     sprintf( psz_tmp, ":%d", i_port + 1 );
00255     config_PutPsz( p_intf, "http-host", psz_tmp );
00256 
00257     msg_Dbg( p_intf, "base %s:%d", psz_address, i_port );
00258 
00259     p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_intf), psz_address,
00260                                             i_port, psz_cert, psz_key, psz_ca,
00261                                             psz_crl );
00262     if( p_sys->p_httpd_host == NULL )
00263     {
00264         msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port );
00265         free( p_sys->psz_html_type );
00266         free( p_sys->psz_address );
00267         free( p_sys );
00268         return VLC_EGENERIC;
00269     }
00270 
00271     p_sys->i_files  = 0;
00272     p_sys->pp_files = NULL;
00273 
00274 #if defined(SYS_DARWIN) || defined(SYS_BEOS) || defined(WIN32)
00275     if ( ( psz_src = config_GetPsz( p_intf, "http-src" )) == NULL )
00276     {
00277         char * psz_vlcpath = p_intf->p_libvlc->psz_vlcpath;
00278         psz_src = malloc( strlen(psz_vlcpath) + strlen("/share/http" ) + 1 );
00279         if( !psz_src ) return VLC_ENOMEM;
00280 #if defined(WIN32)
00281         sprintf( psz_src, "%s/http", psz_vlcpath );
00282 #else
00283         sprintf( psz_src, "%s/share/http", psz_vlcpath );
00284 #endif
00285     }
00286 #else
00287     psz_src = config_GetPsz( p_intf, "http-src" );
00288 
00289     if( !psz_src || *psz_src == '\0' )
00290     {
00291         if( !DirectoryCheck( "share/http" ) )
00292         {
00293             psz_src = strdup( "share/http" );
00294         }
00295         else if( !DirectoryCheck( DATA_PATH "/http" ) )
00296         {
00297             psz_src = strdup( DATA_PATH "/http" );
00298         }
00299     }
00300 #endif
00301 
00302     if( !psz_src || *psz_src == '\0' )
00303     {
00304         msg_Err( p_intf, "invalid src dir" );
00305         goto failed;
00306     }
00307 
00308     /* remove trainling \ or / */
00309     if( psz_src[strlen( psz_src ) - 1] == '\\' ||
00310         psz_src[strlen( psz_src ) - 1] == '/' )
00311     {
00312         psz_src[strlen( psz_src ) - 1] = '\0';
00313     }
00314 
00315     E_(ParseDirectory)( p_intf, psz_src, psz_src );
00316 
00317 
00318     if( p_sys->i_files <= 0 )
00319     {
00320         msg_Err( p_intf, "cannot find any files (%s)", psz_src );
00321         goto failed;
00322     }
00323     p_intf->pf_run = Run;
00324     free( psz_src );
00325 
00326     return VLC_SUCCESS;
00327 
00328 failed:
00329     if( psz_src ) free( psz_src );
00330     if( p_sys->pp_files )
00331     {
00332         free( p_sys->pp_files );
00333     }
00334     httpd_HostDelete( p_sys->p_httpd_host );
00335     free( p_sys->psz_address );
00336     free( p_sys->psz_html_type ); 
00337     if( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 )
00338         vlc_iconv_close( p_sys->iconv_from_utf8 );
00339     if( p_sys->iconv_to_utf8 != (vlc_iconv_t)-1 )
00340         vlc_iconv_close( p_sys->iconv_to_utf8 );
00341     free( p_sys );
00342     return VLC_EGENERIC;
00343 }
00344 
00345 /*****************************************************************************
00346  * Close: destroy interface
00347  *****************************************************************************/
00348 static void Close ( vlc_object_t *p_this )
00349 {
00350     intf_thread_t *p_intf = (intf_thread_t *)p_this;
00351     intf_sys_t    *p_sys = p_intf->p_sys;
00352 
00353     int i;
00354 
00355     if( p_sys->p_vlm )
00356     {
00357         vlm_Delete( p_sys->p_vlm );
00358     }
00359     for( i = 0; i < p_sys->i_files; i++ )
00360     {
00361         if( p_sys->pp_files[i]->b_handler )
00362             httpd_HandlerDelete( ((httpd_handler_sys_t *)p_sys->pp_files[i])->p_handler );
00363         else
00364             httpd_FileDelete( p_sys->pp_files[i]->p_file );
00365         if( p_sys->pp_files[i]->p_redir )
00366             httpd_RedirectDelete( p_sys->pp_files[i]->p_redir );
00367         if( p_sys->pp_files[i]->p_redir2 )
00368             httpd_RedirectDelete( p_sys->pp_files[i]->p_redir2 );
00369 
00370         free( p_sys->pp_files[i]->file );
00371         free( p_sys->pp_files[i]->name );
00372         free( p_sys->pp_files[i] );
00373     }
00374     if( p_sys->pp_files )
00375     {
00376         free( p_sys->pp_files );
00377     }
00378     for( i = 0; i < p_sys->i_handlers; i++ )
00379     {
00380         http_association_t *p_handler = p_sys->pp_handlers[i];
00381         int j;
00382         free( p_handler->psz_ext );
00383         for( j = 0; j < p_handler->i_argc; j++ )
00384             free( p_handler->ppsz_argv[j] );
00385         if( p_handler->i_argc )
00386             free( p_handler->ppsz_argv );
00387         free( p_handler );
00388     }
00389     if( p_sys->i_handlers )
00390         free( p_sys->pp_handlers );
00391     httpd_HostDelete( p_sys->p_httpd_host );
00392     free( p_sys->psz_address );
00393     free( p_sys->psz_html_type );
00394 
00395     if( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 )
00396         vlc_iconv_close( p_sys->iconv_from_utf8 );
00397     if( p_sys->iconv_to_utf8 != (vlc_iconv_t)-1 )
00398         vlc_iconv_close( p_sys->iconv_to_utf8 );
00399     free( p_sys );
00400 }
00401 
00402 /*****************************************************************************
00403  * Run: http interface thread
00404  *****************************************************************************/
00405 static void Run( intf_thread_t *p_intf )
00406 {
00407     intf_sys_t     *p_sys = p_intf->p_sys;
00408 
00409     while( !p_intf->b_die )
00410     {
00411         /* get the playlist */
00412         if( p_sys->p_playlist == NULL )
00413         {
00414             p_sys->p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00415         }
00416 
00417         /* Manage the input part */
00418         if( p_sys->p_input == NULL )
00419         {
00420             if( p_sys->p_playlist )
00421             {
00422                 p_sys->p_input =
00423                     vlc_object_find( p_sys->p_playlist,
00424                                      VLC_OBJECT_INPUT,
00425                                      FIND_CHILD );
00426             }
00427         }
00428         else if( p_sys->p_input->b_dead )
00429         {
00430             vlc_object_release( p_sys->p_input );
00431             p_sys->p_input = NULL;
00432         }
00433 
00434 
00435         /* Wait a bit */
00436         msleep( INTF_IDLE_SLEEP );
00437     }
00438 
00439     if( p_sys->p_input )
00440     {
00441         vlc_object_release( p_sys->p_input );
00442         p_sys->p_input = NULL;
00443     }
00444 
00445     if( p_sys->p_playlist )
00446     {
00447         vlc_object_release( p_sys->p_playlist );
00448         p_sys->p_playlist = NULL;
00449     }
00450 }
00451 
00452 /****************************************************************************
00453  * HttpCallback:
00454  ****************************************************************************
00455  * a file with b_html is parsed and all "macro" replaced
00456  ****************************************************************************/
00457 static void Callback404( httpd_file_sys_t *p_args, char **pp_data,
00458                          int *pi_data )
00459 {
00460     char *p = *pp_data = malloc( 10240 );
00461     if( !p )
00462     {
00463         return;
00464     }
00465     p += sprintf( p, "<html>\n" );
00466     p += sprintf( p, "<head>\n" );
00467     p += sprintf( p, "<title>Error loading %s</title>\n", p_args->file );
00468     p += sprintf( p, "</head>\n" );
00469     p += sprintf( p, "<body>\n" );
00470     p += sprintf( p, "<h1><center>Error loading %s for %s</center></h1>\n", p_args->file, p_args->name );
00471     p += sprintf( p, "<hr />\n" );
00472     p += sprintf( p, "<a href=\"http://www.videolan.org/\">VideoLAN</a>\n" );
00473     p += sprintf( p, "</body>\n" );
00474     p += sprintf( p, "</html>\n" );
00475 
00476     *pi_data = strlen( *pp_data );
00477 }
00478 
00479 static void ParseExecute( httpd_file_sys_t *p_args, char *p_buffer,
00480                           int i_buffer, char *p_request,
00481                           char **pp_data, int *pi_data )
00482 {
00483     int i_request = p_request != NULL ? strlen( p_request ) : 0;
00484     char *dst;
00485     vlc_value_t val;
00486     char position[4]; /* percentage */
00487     char time[12]; /* in seconds */
00488     char length[12]; /* in seconds */
00489     audio_volume_t i_volume;
00490     char volume[5];
00491     char state[8];
00492 
00493 #define p_sys p_args->p_intf->p_sys
00494     if( p_sys->p_input )
00495     {
00496         var_Get( p_sys->p_input, "position", &val);
00497         sprintf( position, "%d" , (int)((val.f_float) * 100.0));
00498         var_Get( p_sys->p_input, "time", &val);
00499         sprintf( time, "%d" , (int)(val.i_time / 1000000) );
00500         var_Get( p_sys->p_input, "length", &val);
00501         sprintf( length, "%d" , (int)(val.i_time / 1000000) );
00502 
00503         var_Get( p_sys->p_input, "state", &val );
00504         if( val.i_int == PLAYING_S )
00505         {
00506             sprintf( state, "playing" );
00507         }
00508         else if( val.i_int == PAUSE_S )
00509         {
00510             sprintf( state, "paused" );
00511         }
00512         else
00513         {
00514             sprintf( state, "stop" );
00515         }
00516     }
00517     else
00518     {
00519         sprintf( position, "%d", 0 );
00520         sprintf( time, "%d", 0 );
00521         sprintf( length, "%d", 0 );
00522         sprintf( state, "stop" );
00523     }
00524 #undef p_sys
00525 
00526     aout_VolumeGet( p_args->p_intf, &i_volume );
00527     sprintf( volume, "%d", (int)i_volume );
00528 
00529     p_args->vars = E_(mvar_New)( "variables", "" );
00530     E_(mvar_AppendNewVar)( p_args->vars, "url_param",
00531                            i_request > 0 ? "1" : "0" );
00532     E_(mvar_AppendNewVar)( p_args->vars, "url_value", p_request );
00533     E_(mvar_AppendNewVar)( p_args->vars, "version", VLC_Version() );
00534     E_(mvar_AppendNewVar)( p_args->vars, "copyright", COPYRIGHT_MESSAGE );
00535     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_by", VLC_CompileBy() );
00536     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_host",
00537                            VLC_CompileHost() );
00538     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_domain",
00539                            VLC_CompileDomain() );
00540     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compiler", VLC_Compiler() );
00541     E_(mvar_AppendNewVar)( p_args->vars, "vlc_changeset", VLC_Changeset() );
00542     E_(mvar_AppendNewVar)( p_args->vars, "stream_position", position );
00543     E_(mvar_AppendNewVar)( p_args->vars, "stream_time", time );
00544     E_(mvar_AppendNewVar)( p_args->vars, "stream_length", length );
00545     E_(mvar_AppendNewVar)( p_args->vars, "volume", volume );
00546     E_(mvar_AppendNewVar)( p_args->vars, "stream_state", state );
00547 
00548     E_(SSInit)( &p_args->stack );
00549 
00550     /* allocate output */
00551     *pi_data = i_buffer + 1000;
00552     dst = *pp_data = malloc( *pi_data );
00553 
00554     /* we parse executing all  <vlc /> macros */
00555     E_(Execute)( p_args, p_request, i_request, pp_data, pi_data, &dst,
00556                  &p_buffer[0], &p_buffer[i_buffer] );
00557 
00558     *dst     = '\0';
00559     *pi_data = dst - *pp_data;
00560 
00561     E_(SSClean)( &p_args->stack );
00562     E_(mvar_Delete)( p_args->vars );
00563 }
00564 
00565 int  E_(HttpCallback)( httpd_file_sys_t *p_args,
00566                        httpd_file_t *p_file,
00567                        uint8_t *_p_request,
00568                        uint8_t **_pp_data, int *pi_data )
00569 {
00570     char *p_request = (char *)_p_request;
00571     char **pp_data = (char **)_pp_data;
00572     FILE *f;
00573 
00574     if( ( f = fopen( p_args->file, "r" ) ) == NULL )
00575     {
00576         Callback404( p_args, pp_data, pi_data );
00577         return VLC_SUCCESS;
00578     }
00579 
00580     if( !p_args->b_html )
00581     {
00582         E_(FileLoad)( f, pp_data, pi_data );
00583     }
00584     else
00585     {
00586         int  i_buffer;
00587         char *p_buffer;
00588 
00589         /* first we load in a temporary buffer */
00590         E_(FileLoad)( f, &p_buffer, &i_buffer );
00591 
00592         ParseExecute( p_args, p_buffer, i_buffer, p_request, pp_data, pi_data );
00593 
00594         free( p_buffer );
00595     }
00596 
00597     fclose( f );
00598 
00599     return VLC_SUCCESS;
00600 }
00601 
00602 /****************************************************************************
00603  * HandlerCallback:
00604  ****************************************************************************
00605  * call the external handler and parse vlc macros if Content-Type is HTML
00606  ****************************************************************************/
00607 int  E_(HandlerCallback)( httpd_handler_sys_t *p_args,
00608                           httpd_handler_t *p_handler, uint8_t *_p_url,
00609                           uint8_t *_p_request, int i_type,
00610                           uint8_t *_p_in, int i_in,
00611                           char *psz_remote_addr, char *psz_remote_host,
00612                           uint8_t **_pp_data, int *pi_data )
00613 {
00614     char *p_url = (char *)_p_url;
00615     char *p_request = (char *)_p_request;
00616     char **pp_data = (char **)_pp_data;
00617     char *p_in = (char *)p_in;
00618     int i_request = p_request != NULL ? strlen( p_request ) : 0;
00619     char *p;
00620     int i_env = 0;
00621     char **ppsz_env = NULL;
00622     char *psz_tmp;
00623     char sep;
00624     int  i_buffer;
00625     char *p_buffer;
00626     char *psz_cwd, *psz_file = NULL;
00627     int i_ret;
00628 
00629 #ifdef WIN32
00630     sep = '\\';
00631 #else
00632     sep = '/';
00633 #endif
00634 
00635     /* Create environment for the CGI */
00636     TAB_APPEND( i_env, ppsz_env, strdup("GATEWAY_INTERFACE=CGI/1.1") );
00637     TAB_APPEND( i_env, ppsz_env, strdup("SERVER_PROTOCOL=HTTP/1.1") );
00638     TAB_APPEND( i_env, ppsz_env, strdup("SERVER_SOFTWARE=" COPYRIGHT_MESSAGE) );
00639 
00640     switch( i_type )
00641     {
00642     case HTTPD_MSG_GET:
00643         TAB_APPEND( i_env, ppsz_env, strdup("REQUEST_METHOD=GET") );
00644         break;
00645     case HTTPD_MSG_POST:
00646         TAB_APPEND( i_env, ppsz_env, strdup("REQUEST_METHOD=POST") );
00647         break;
00648     case HTTPD_MSG_HEAD:
00649         TAB_APPEND( i_env, ppsz_env, strdup("REQUEST_METHOD=HEAD") );
00650         break;
00651     default:
00652         break;
00653     }
00654 
00655     if( i_request )
00656     {
00657         psz_tmp = malloc( sizeof("QUERY_STRING=") + i_request );
00658         sprintf( psz_tmp, "QUERY_STRING=%s", p_request );
00659         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00660 
00661         psz_tmp = malloc( sizeof("REQUEST_URI=?") + strlen(p_url)
00662                            + i_request );
00663         sprintf( psz_tmp, "REQUEST_URI=%s?%s", p_url, p_request );
00664         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00665     }
00666     else
00667     {
00668         psz_tmp = malloc( sizeof("REQUEST_URI=") + strlen(p_url) );
00669         sprintf( psz_tmp, "REQUEST_URI=%s", p_url );
00670         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00671     }
00672 
00673     psz_tmp = malloc( sizeof("SCRIPT_NAME=") + strlen(p_url) );
00674     sprintf( psz_tmp, "SCRIPT_NAME=%s", p_url );
00675     TAB_APPEND( i_env, ppsz_env, psz_tmp );
00676 
00677 #define p_sys p_args->file.p_intf->p_sys
00678     psz_tmp = malloc( sizeof("SERVER_NAME=") + strlen(p_sys->psz_address) );
00679     sprintf( psz_tmp, "SERVER_NAME=%s", p_sys->psz_address );
00680     TAB_APPEND( i_env, ppsz_env, psz_tmp );
00681 
00682     psz_tmp = malloc( sizeof("SERVER_PORT=") + 5 );
00683     sprintf( psz_tmp, "SERVER_PORT=%u", p_sys->i_port );
00684     TAB_APPEND( i_env, ppsz_env, psz_tmp );
00685 #undef p_sys
00686 
00687     p = getenv( "PATH" );
00688     if( p != NULL )
00689     {
00690         psz_tmp = malloc( sizeof("PATH=") + strlen(p) );
00691         sprintf( psz_tmp, "PATH=%s", p );
00692         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00693     }
00694 
00695 #ifdef WIN32
00696     p = getenv( "windir" );
00697     if( p != NULL )
00698     {
00699         psz_tmp = malloc( sizeof("SYSTEMROOT=") + strlen(p) );
00700         sprintf( psz_tmp, "SYSTEMROOT=%s", p );
00701         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00702     }
00703 #endif
00704 
00705     if( psz_remote_addr != NULL && *psz_remote_addr )
00706     {
00707         psz_tmp = malloc( sizeof("REMOTE_ADDR=") + strlen(psz_remote_addr) );
00708         sprintf( psz_tmp, "REMOTE_ADDR=%s", psz_remote_addr );
00709         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00710     }
00711 
00712     if( psz_remote_host != NULL && *psz_remote_host )
00713     {
00714         psz_tmp = malloc( sizeof("REMOTE_HOST=") + strlen(psz_remote_host) );
00715         sprintf( psz_tmp, "REMOTE_HOST=%s", psz_remote_host );
00716         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00717     }
00718 
00719     if( i_in )
00720     {
00721         p = p_in;
00722         for ( ; ; )
00723         {
00724             if( !strncmp( p, "Content-Type: ", strlen("Content-Type: ") ) )
00725             {
00726                 char *end = strchr( p, '\r' );
00727                 if( end == NULL )
00728                     break;
00729                 *end = '\0';
00730                 psz_tmp = malloc( sizeof("CONTENT_TYPE=") + strlen(p) );
00731                 sprintf( psz_tmp, "CONTENT_TYPE=%s", p );
00732                 TAB_APPEND( i_env, ppsz_env, psz_tmp );
00733                 *end = '\r';
00734             }
00735             if( !strncmp( p, "Content-Length: ", strlen("Content-Length: ") ) )
00736             {
00737                 char *end = strchr( p, '\r' );
00738                 if( end == NULL )
00739                     break;
00740                 *end = '\0';
00741                 psz_tmp = malloc( sizeof("CONTENT_LENGTH=") + strlen(p) );
00742                 sprintf( psz_tmp, "CONTENT_LENGTH=%s", p );
00743                 TAB_APPEND( i_env, ppsz_env, psz_tmp );
00744                 *end = '\r';
00745             }
00746 
00747             p = strchr( p, '\n' );
00748             if( p == NULL || p[1] == '\r' )
00749             {
00750                 p = NULL;
00751                 break;
00752             }
00753             p++;
00754         }
00755     }
00756 
00757     psz_file = strrchr( p_args->file.file, sep );
00758     if( psz_file != NULL )
00759     {
00760         psz_file++;
00761         psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(psz_file) );
00762         sprintf( psz_tmp, "SCRIPT_FILENAME=%s", psz_file );
00763         TAB_APPEND( i_env, ppsz_env, psz_tmp );
00764 
00765         TAB_APPEND( p_args->p_association->i_argc,
00766                     p_args->p_association->ppsz_argv, psz_file );
00767     }
00768 
00769     TAB_APPEND( i_env, ppsz_env, NULL );
00770 
00771     TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv,
00772                 NULL );
00773 
00774     psz_tmp = strdup( p_args->file.file );
00775     p = strrchr( psz_tmp, sep );
00776     if( p != NULL )
00777     {
00778         *p = '\0';
00779         psz_cwd = psz_tmp;
00780     }
00781     else
00782     {
00783         free( psz_tmp );
00784         psz_cwd = NULL;
00785     }
00786 
00787     i_ret = vlc_execve( p_args->file.p_intf, p_args->p_association->i_argc,
00788                         p_args->p_association->ppsz_argv, ppsz_env, psz_cwd,
00789                         (char *)p_in, i_in, &p_buffer, &i_buffer );
00790     TAB_REMOVE( p_args->p_association->i_argc, p_args->p_association->ppsz_argv,
00791                 NULL );
00792     TAB_REMOVE( p_args->p_association->i_argc, p_args->p_association->ppsz_argv,
00793                 psz_file );
00794     if( psz_cwd != NULL )
00795         free( psz_cwd );
00796     while( i_env )
00797         TAB_REMOVE( i_env, ppsz_env, ppsz_env[0] );
00798 
00799     if( i_ret == -1 )
00800     {
00801         Callback404( (httpd_file_sys_t *)p_args, pp_data, pi_data );
00802         return VLC_SUCCESS;
00803     }
00804     p = p_buffer;
00805     while( strncmp( p, "Content-Type: text/html",
00806                     strlen("Content-Type: text/html") ) )
00807     {
00808         p = strchr( p, '\n' );
00809         if( p == NULL || p[1] == '\r' )
00810         {
00811             p = NULL;
00812             break;
00813         }
00814         p++;
00815     }
00816 
00817     if( p == NULL )
00818     {
00819         *pp_data = p_buffer;
00820         *pi_data = i_buffer;
00821     }
00822     else
00823     {
00824         ParseExecute( (httpd_file_sys_t *)p_args, p_buffer, i_buffer,
00825                       p_request, pp_data, pi_data );
00826 
00827         free( p_buffer );
00828     }
00829 
00830     return VLC_SUCCESS;
00831 }

Generated on Tue Dec 20 10:14:25 2005 for vlc-0.8.4a by  doxygen 1.4.2