⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * http.c : HTTP/HTTPS Remote control interface ***************************************************************************** * Copyright (C) 2001-2006 the VideoLAN team * * Authors: Gildas Bazin <gbazin@netcourrier.com> *          Laurent Aimar <fenrir@via.ecp.fr> *          Christophe Massiot <massiot@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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "http.h"#include <vlc_plugin.h>#include <assert.h>/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );#define HOST_TEXT N_( "Host address" )#define HOST_LONGTEXT N_( \    "Address and port the HTTP interface will listen on. It defaults to " \    "all network interfaces (0.0.0.0)." \    " If you want the HTTP interface to be available only on the local " \    "machine, enter 127.0.0.1" )#define SRC_TEXT N_( "Source directory" )#define SRC_LONGTEXT N_( "Source directory" )#define HANDLERS_TEXT N_( "Handlers" )#define HANDLERS_LONGTEXT N_( \        "List of handler extensions and executable paths (for instance: " \        "php=/usr/bin/php,pl=/usr/bin/perl)." )#define ART_TEXT N_( "Export album art as /art." )#define ART_LONGTEXT N_( \        "Allow exporting album art for current playlist items at the " \        "/art and /art?id=<id> URLs." )#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( N_("HTTP"));    set_description( N_("HTTP remote control interface") );    set_category( CAT_INTERFACE );    set_subcategory( SUBCAT_INTERFACE_MAIN );        add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, true );        add_string ( "http-src",  NULL, NULL, SRC_TEXT,  SRC_LONGTEXT,  true );        add_obsolete_string ( "http-charset" );#if defined( HAVE_FORK ) || defined( WIN32 )        add_string ( "http-handlers", NULL, NULL, HANDLERS_TEXT, HANDLERS_LONGTEXT, true );#endif        add_bool   ( "http-album-art", false, NULL, ART_TEXT, ART_LONGTEXT, true );        set_section( N_("HTTP SSL" ), 0 );        add_string ( "http-intf-cert", NULL, NULL, CERT_TEXT, CERT_LONGTEXT, true );        add_string ( "http-intf-key",  NULL, NULL, KEY_TEXT,  KEY_LONGTEXT,  true );        add_string ( "http-intf-ca",   NULL, NULL, CA_TEXT,   CA_LONGTEXT,   true );        add_string ( "http-intf-crl",  NULL, NULL, CRL_TEXT,  CRL_LONGTEXT,  true );    set_capability( "interface", 0 );    set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/int  ArtCallback( httpd_handler_sys_t *p_args,                          httpd_handler_t *p_handler, char *_p_url,                          uint8_t *_p_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 );/***************************************************************************** * 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_address;    char          *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,                  *psz_crl = NULL;    int           i_port       = 0;    char          *psz_src = NULL;    psz_address = var_CreateGetNonEmptyString( p_intf, "http-host" );    if( psz_address != NULL )    {        char *psz_parser = strrchr( psz_address, ':' );        if( psz_parser )        {            *psz_parser++ = '\0';            i_port = atoi( psz_parser );        }    }    else        psz_address = strdup("");    p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );    if( !p_intf->p_sys )    {        free( psz_address );        return( VLC_ENOMEM );    }    p_sys->p_playlist = pl_Yield( p_this );    p_sys->p_input    = NULL;    p_sys->p_vlm      = NULL;    p_sys->psz_address = psz_address;    p_sys->i_port     = i_port;    p_sys->p_art_handler = NULL;    /* determine file handler associations */    p_sys->i_handlers = 0;    p_sys->pp_handlers = NULL;#if defined( HAVE_FORK ) || defined( WIN32 )    psz_src = config_GetPsz( p_intf, "http-handlers" );    if( psz_src != NULL && *psz_src )    {        char *p = psz_src;        while( p != NULL )        {            http_association_t *p_handler;            char *psz_ext = p;            char *psz_program, *psz_options;            p = strchr( p, '=' );            if( p == NULL ) break;            *p++ = '\0';            psz_program = p;            p = strchr( p, ',' );            if( p != NULL )                *p++ = '\0';            p_handler = malloc( sizeof( http_association_t ) );            p_handler->psz_ext = strdup( psz_ext );            psz_options = FirstWord( psz_program, psz_program );            p_handler->i_argc = 0;            p_handler->ppsz_argv = NULL;            TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv,                        strdup( psz_program ) );            while( psz_options != NULL && *psz_options )            {                char *psz_next = FirstWord( psz_options, psz_options );                TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv,                            strdup( psz_options ) );                psz_options = psz_next;            }            /* NULL will be appended later on */            TAB_APPEND( p_sys->i_handlers, p_sys->pp_handlers, p_handler );        }    }    free( psz_src );#endif    /* determine SSL configuration */    psz_cert = config_GetPsz( p_intf, "http-intf-cert" );    if ( psz_cert != NULL )    {        msg_Dbg( p_intf, "enabling TLS for HTTP interface (cert file: %s)",                 psz_cert );        psz_key = var_GetNonEmptyString( p_intf, "http-intf-key" );        psz_ca = var_GetNonEmptyString( p_intf, "http-intf-ca" );        psz_crl = var_GetNonEmptyString( p_intf, "http-intf-crl" );        if( i_port <= 0 )            i_port = 8443;    }    else    {        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, psz_cert, psz_key, psz_ca,                                            psz_crl );    free( psz_cert );    free( psz_key );    free( psz_ca );    free( psz_crl );    if( p_sys->p_httpd_host == NULL )    {        msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port );        pl_Release( p_this );        free( p_sys->psz_address );        free( p_sys );        return VLC_EGENERIC;    }    else    {        char psz_tmp[NI_MAXHOST + 6];        /* Ugly hack to run several HTTP servers on different ports */        snprintf( psz_tmp, sizeof (psz_tmp), "%s:%d", psz_address, i_port + 1 );        var_Create(p_intf->p_libvlc, "http-host", VLC_VAR_STRING );        var_SetString( p_intf->p_libvlc, "http-host", psz_tmp );    }    p_sys->i_files  = 0;    p_sys->pp_files = NULL;    psz_src = config_GetPsz( p_intf, "http-src" );    if( ( psz_src == NULL ) || ( *psz_src == '\0' ) )    {        const char *data_path = config_GetDataDir ();        if( asprintf( &psz_src, "%s/http", data_path ) == -1 )            psz_src = NULL;    }    if( !psz_src || *psz_src == '\0' )    {        msg_Err( p_intf, "invalid web interface source directory" );        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 file in directory %s", psz_src );        goto failed;    }    free( psz_src );    if( config_GetInt( p_intf, "http-album-art" ) )    {        /* FIXME: we're leaking h */        httpd_handler_sys_t *h = malloc( sizeof( httpd_handler_sys_t ) );        if( !h )        {            msg_Err( p_intf, "not enough memory to allocate album art handler" );            goto failed;        }        h->file.p_intf = p_intf;        h->file.file = NULL;        h->file.name = NULL;        /* TODO: use ACL and login/password stuff here too */        h->p_handler = httpd_HandlerNew( p_sys->p_httpd_host,                                         "/art", NULL, NULL, NULL,                                         ArtCallback, h );        p_sys->p_art_handler = h->p_handler;    }    return VLC_SUCCESS;failed:    free( psz_src );    free( p_sys->pp_files );    httpd_HostDelete( p_sys->p_httpd_host );    free( p_sys->psz_address );    free( p_sys );    pl_Release( p_this );    return VLC_EGENERIC;}/***************************************************************************** * Close: destroy interface *****************************************************************************/static 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;#ifdef ENABLE_VLM    if( p_sys->p_vlm )        vlm_Delete( p_sys->p_vlm );#endif    for( i = 0; i < p_sys->i_files; i++ )    {        if( p_sys->pp_files[i]->b_handler )            httpd_HandlerDelete( ((httpd_handler_sys_t *)p_sys->pp_files[i])->p_handler );        else            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] );    }    free( p_sys->pp_files );    for( i = 0; i < p_sys->i_handlers; i++ )    {        http_association_t *p_handler = p_sys->pp_handlers[i];        int j;        free( p_handler->psz_ext );        for( j = 0; j < p_handler->i_argc; j++ )            free( p_handler->ppsz_argv[j] );        if( p_handler->i_argc )            free( p_handler->ppsz_argv );        free( p_handler );    }    if( p_sys->i_handlers )        free( p_sys->pp_handlers );    if( p_sys->p_art_handler )        httpd_HandlerDelete( p_sys->p_art_handler );    httpd_HostDelete( p_sys->p_httpd_host );    free( p_sys->psz_address );    free( p_sys );    pl_Release( p_this );}/**************************************************************************** * HttpCallback: **************************************************************************** * a file with b_html is parsed and all "macro" replaced ****************************************************************************/static void Callback404( httpd_file_sys_t *p_args, char **pp_data,                         int *pi_data ){    char *p = *pp_data = malloc( 10240 );    if( !p )    {        return;    }    p += sprintf( p, "Content-Type: text/html\n" );    p += sprintf( p, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" );    p += sprintf( p, "<head>\n" );    p += sprintf( p, "<title>Error loading %s</title>\n", p_args->file );    p += sprintf( p, "</head>\n" );    p += sprintf( p, "<body>\n" );    p += sprintf( p, "<h1><center>Error loading %s for %s</center></h1>\n", p_args->file, p_args->name );    p += sprintf( p, "<a href=\"http://www.videolan.org/\">VideoLAN</a>\n" );    p += sprintf( p, "</body>\n" );    p += sprintf( p, "</html>\n" );    *pi_data = strlen( *pp_data );}static void ParseExecute( httpd_file_sys_t *p_args, char *p_buffer,                          int i_buffer, char *p_request,                          char **pp_data, int *pi_data ){    intf_sys_t *p_sys = p_args->p_intf->p_sys;    int i_request = p_request != NULL ? strlen( p_request ) : 0;    char *dst;    vlc_value_t val;    char position[4]; /* percentage */    char time[12]; /* in seconds */    char length[12]; /* in seconds */    audio_volume_t i_volume;    char volume[5];    const char *state;    char stats[20];    assert( p_sys->p_input == NULL );    /* FIXME: proper locking anyone? */    p_sys->p_input = p_sys->p_playlist->p_input;    if( p_sys->p_input )    {        vlc_object_yield( p_sys->p_input );        var_Get( p_sys->p_input, "position", &val);        sprintf( position, "%d" , (int)((val.f_float) * 100.0));        var_Get( p_sys->p_input, "time", &val);        sprintf( time, "%"PRIi64, (int64_t)val.i_time / INT64_C(1000000) );        var_Get( p_sys->p_input, "length", &val);        sprintf( length, "%"PRIi64, (int64_t)val.i_time / INT64_C(1000000) );        var_Get( p_sys->p_input, "state", &val );        if( val.i_int == PLAYING_S )        {            state = "playing";        }        else if( val.i_int == OPENING_S )        {            state = "opening/connecting";        }        else if( val.i_int == BUFFERING_S )        {            state = "buffering";        }        else if( val.i_int == PAUSE_S )        {            state = "paused";        }        else        {            state = "stop";        }    }    else    {        sprintf( position, "%d", 0 );        sprintf( time, "%d", 0 );        sprintf( length, "%d", 0 );        state = "stop";    }    aout_VolumeGet( p_args->p_intf, &i_volume );    sprintf( volume, "%d", (int)i_volume );    p_args->vars = mvar_New( "variables", "" );    mvar_AppendNewVar( p_args->vars, "url_param",                           i_request > 0 ? "1" : "0" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -