00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "http.h"
00027
00028
00029
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
00080
00081 static void Run ( intf_thread_t *p_intf );
00082
00083
00084
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
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
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
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
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
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
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
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
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
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
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
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
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
00454
00455
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];
00487 char time[12];
00488 char length[12];
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
00551 *pi_data = i_buffer + 1000;
00552 dst = *pp_data = malloc( *pi_data );
00553
00554
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
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
00604
00605
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
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 }