?? http.c
字號(hào):
/***************************************************************************** * http.c : http mini-server ;) ***************************************************************************** * Copyright (C) 2001-2005 VideoLAN * $Id: http.c 11000 2005-05-13 17:58:05Z zorglub $ * * Authors: Gildas Bazin <gbazin@netcourrier.com> * Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************//* TODO: * - clean up ? * - doc ! (mouarf ;) */#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/intf.h>#include <vlc/aout.h>#include <vlc/vout.h> /* for fullscreen */#include "vlc_httpd.h"#include "vlc_vlm.h"#include "vlc_tls.h"#include "charset.h"#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_ERRNO_H# include <errno.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#elif defined( WIN32 ) && !defined( UNDER_CE )# include <io.h>#endif#ifdef HAVE_DIRENT_H# include <dirent.h>#endif/* stat() support for large files on win32 */#if defined( WIN32 ) && !defined( UNDER_CE )# define stat _stati64#endif/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t * );static void Close( vlc_object_t * );#define HOST_TEXT N_( "Host address" )#define HOST_LONGTEXT N_( \ "You can set the address and port the http interface will bind to." )#define SRC_TEXT N_( "Source directory" )#define SRC_LONGTEXT N_( "Source directory" )#define CERT_TEXT N_( "Certificate file" )#define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \ "(enables SSL)" )#define KEY_TEXT N_( "Private key file" )#define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )#define CA_TEXT N_( "Root CA file" )#define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \ "certificates file" )#define CRL_TEXT N_( "CRL file" )#define CRL_LONGTEXT N_( "HTTP interace Certificates Revocation List file" )vlc_module_begin(); set_shortname( _("HTTP")); set_description( _("HTTP remote control interface") ); set_category( CAT_INTERFACE ); set_subcategory( SUBCAT_INTERFACE_GENERAL ); add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE ); add_string ( "http-src", NULL, NULL, SRC_TEXT, SRC_LONGTEXT, VLC_TRUE ); set_section( N_("HTTP SSL" ), 0 ); add_string ( "http-intf-cert", NULL, NULL, CERT_TEXT, CERT_LONGTEXT, VLC_TRUE ); add_string ( "http-intf-key", NULL, NULL, KEY_TEXT, KEY_LONGTEXT, VLC_TRUE ); add_string ( "http-intf-ca", NULL, NULL, CA_TEXT, CA_LONGTEXT, VLC_TRUE ); add_string ( "http-intf-crl", NULL, NULL, CRL_TEXT, CRL_LONGTEXT, VLC_TRUE ); set_capability( "interface", 0 ); set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static void Run ( intf_thread_t *p_intf );static int ParseDirectory( intf_thread_t *p_intf, char *psz_root, char *psz_dir );static int DirectoryCheck( char *psz_dir ){ DIR *p_dir;#ifdef HAVE_SYS_STAT_H struct stat stat_info; if( stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) ) { return VLC_EGENERIC; }#endif if( ( p_dir = opendir( psz_dir ) ) == NULL ) { return VLC_EGENERIC; } closedir( p_dir ); return VLC_SUCCESS;}static int HttpCallback( httpd_file_sys_t *p_args, httpd_file_t *, uint8_t *p_request, uint8_t **pp_data, int *pi_data );static char *uri_extract_value( char *psz_uri, const char *psz_name, char *psz_value, int i_value_max );static int uri_test_param( char *psz_uri, const char *psz_name );static void uri_decode_url_encoded( char *psz );static char *Find_end_MRL( char *psz );static playlist_item_t *parse_MRL( intf_thread_t * , char *psz );/***************************************************************************** * *****************************************************************************/typedef struct mvar_s{ char *name; char *value; int i_field; struct mvar_s **field;} mvar_t;#define STACK_MAX 100typedef struct{ char *stack[STACK_MAX]; int i_stack;} rpn_stack_t;struct httpd_file_sys_t{ intf_thread_t *p_intf; httpd_file_t *p_file; httpd_redirect_t *p_redir; httpd_redirect_t *p_redir2; char *file; char *name; vlc_bool_t b_html; /* inited for each access */ rpn_stack_t stack; mvar_t *vars;};struct intf_sys_t{ httpd_host_t *p_httpd_host; int i_files; httpd_file_sys_t **pp_files; playlist_t *p_playlist; input_thread_t *p_input; vlm_t *p_vlm; char *psz_html_type;};/***************************************************************************** * Activate: initialize and create stuff *****************************************************************************/static int Open( vlc_object_t *p_this ){ intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys; char *psz_host; char *psz_address = ""; const char *psz_cert; int i_port = 0; char *psz_src; tls_server_t *p_tls; psz_host = config_GetPsz( p_intf, "http-host" ); if( psz_host ) { char *psz_parser; psz_address = psz_host; psz_parser = strchr( psz_host, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; i_port = atoi( psz_parser ); } } p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) ); if( !p_intf->p_sys ) { return( VLC_ENOMEM ); } p_sys->p_playlist = NULL; p_sys->p_input = NULL; p_sys->p_vlm = NULL; /* determine Content-Type value for HTML pages */ vlc_current_charset(&psz_src); if( psz_src == NULL ) { free( p_sys ); return VLC_ENOMEM; } p_sys->psz_html_type = malloc( 20 + strlen( psz_src ) ); if( p_sys->psz_html_type == NULL ) { free( p_sys ); free( psz_src ); return VLC_ENOMEM ; } sprintf( p_sys->psz_html_type, "text/html; charset=%s", psz_src ); free( psz_src ); /* determine SSL configuration */ psz_cert = config_GetPsz( p_intf, "http-intf-cert" ); if ( psz_cert != NULL ) { const char *psz_pem; msg_Dbg( p_intf, "enablind TLS for HTTP interface (cert file: %s)", psz_cert ); psz_pem = config_GetPsz( p_intf, "http-intf-key" ); p_tls = tls_ServerCreate( p_this, psz_cert, psz_pem ); if ( p_tls == NULL ) { msg_Err( p_intf, "TLS initialization error" ); free( p_sys->psz_html_type ); free( p_sys ); return VLC_EGENERIC; } psz_pem = config_GetPsz( p_intf, "http-intf-ca" ); if ( ( psz_pem != NULL) && tls_ServerAddCA( p_tls, psz_pem ) ) { msg_Err( p_intf, "TLS CA error" ); tls_ServerDelete( p_tls ); free( p_sys->psz_html_type ); free( p_sys ); return VLC_EGENERIC; } psz_pem = config_GetPsz( p_intf, "http-intf-crl" ); if ( ( psz_pem != NULL) && tls_ServerAddCRL( p_tls, psz_pem ) ) { msg_Err( p_intf, "TLS CRL error" ); tls_ServerDelete( p_tls ); free( p_sys->psz_html_type ); free( p_sys ); return VLC_EGENERIC; } if( i_port <= 0 ) i_port = 8443; } else { p_tls = NULL; if( i_port <= 0 ) i_port= 8080; } msg_Dbg( p_intf, "base %s:%d", psz_address, i_port ); p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_intf), psz_address, i_port, p_tls ); if( p_sys->p_httpd_host == NULL ) { msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port ); if ( p_tls != NULL ) tls_ServerDelete( p_tls ); free( p_sys->psz_html_type ); free( p_sys ); return VLC_EGENERIC; } if( psz_host ) { free( psz_host ); } p_sys->i_files = 0; p_sys->pp_files = NULL;#if defined(SYS_DARWIN) || defined(SYS_BEOS) || defined(WIN32) if ( ( psz_src = config_GetPsz( p_intf, "http-src" )) == NULL ) { char * psz_vlcpath = p_intf->p_libvlc->psz_vlcpath; psz_src = malloc( strlen(psz_vlcpath) + strlen("/share/http" ) + 1 ); if( !psz_src ) return VLC_ENOMEM;#if defined(WIN32) sprintf( psz_src, "%s/http", psz_vlcpath);#else sprintf( psz_src, "%s/share/http", psz_vlcpath);#endif }#else psz_src = config_GetPsz( p_intf, "http-src" ); if( !psz_src || *psz_src == '\0' ) { if( !DirectoryCheck( "share/http" ) ) { psz_src = strdup( "share/http" ); } else if( !DirectoryCheck( DATA_PATH "/http" ) ) { psz_src = strdup( DATA_PATH "/http" ); } }#endif if( !psz_src || *psz_src == '\0' ) { msg_Err( p_intf, "invalid src dir" ); goto failed; } /* remove trainling \ or / */ if( psz_src[strlen( psz_src ) - 1] == '\\' || psz_src[strlen( psz_src ) - 1] == '/' ) { psz_src[strlen( psz_src ) - 1] = '\0'; } ParseDirectory( p_intf, psz_src, psz_src ); if( p_sys->i_files <= 0 ) { msg_Err( p_intf, "cannot find any files (%s)", psz_src ); goto failed; } p_intf->pf_run = Run; free( psz_src ); return VLC_SUCCESS;failed: if( psz_src ) free( psz_src ); if( p_sys->pp_files ) { free( p_sys->pp_files ); } httpd_HostDelete( p_sys->p_httpd_host ); free( p_sys->psz_html_type ); free( p_sys ); return VLC_EGENERIC;}/***************************************************************************** * CloseIntf: destroy interface *****************************************************************************/void Close ( vlc_object_t *p_this ){ intf_thread_t *p_intf = (intf_thread_t *)p_this; intf_sys_t *p_sys = p_intf->p_sys; int i; if( p_sys->p_vlm ) { vlm_Delete( p_sys->p_vlm ); } for( i = 0; i < p_sys->i_files; i++ ) { httpd_FileDelete( p_sys->pp_files[i]->p_file ); if( p_sys->pp_files[i]->p_redir ) httpd_RedirectDelete( p_sys->pp_files[i]->p_redir ); if( p_sys->pp_files[i]->p_redir2 ) httpd_RedirectDelete( p_sys->pp_files[i]->p_redir2 ); free( p_sys->pp_files[i]->file ); free( p_sys->pp_files[i]->name ); free( p_sys->pp_files[i] ); } if( p_sys->pp_files ) { free( p_sys->pp_files ); } httpd_HostDelete( p_sys->p_httpd_host ); free( p_sys->psz_html_type ); free( p_sys );}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -