static int vlclua_httpd_tls_host_new( lua_State *L ) { vlc_object_t *p_this = vlclua_get_this( L ); const char *psz_host = luaL_checkstring( L, 1 ); int i_port = luaL_checkint( L, 2 ); const char *psz_cert = luaL_optstring( L, 3, NULL ); const char *psz_key = luaL_optstring( L, 4, NULL ); const char *psz_ca = luaL_optstring( L, 5, NULL ); const char *psz_crl = luaL_optstring( L, 6, NULL ); httpd_host_t *p_host = httpd_TLSHostNew( p_this, psz_host, i_port, psz_cert, psz_key, psz_ca, psz_crl ); if( !p_host ) return luaL_error( L, "Failed to create HTTP TLS host \"%s:%d\" " "(cert: \"%s\", key: \"%s\", ca: \"%s\", " "crl: \"%s\").", psz_host, i_port, psz_cert, psz_key, psz_ca, psz_crl ); httpd_host_t **pp_host = lua_newuserdata( L, sizeof( httpd_host_t * ) ); *pp_host = p_host; if( luaL_newmetatable( L, "httpd_host" ) ) { lua_newtable( L ); luaL_register( L, NULL, vlclua_httpd_reg ); lua_setfield( L, -2, "__index" ); lua_pushcfunction( L, vlclua_httpd_host_delete ); lua_setfield( L, -2, "__gc" ); } lua_setmetatable( L, -2 ); return 1; }
/***************************************************************************** * HTTPOpen: Start the internal HTTP server *****************************************************************************/ int E_(HTTPOpen)( access_t *p_access ) { #define FREE( x ) \ if ( (x) != NULL ) \ free( x ); access_sys_t *p_sys = p_access->p_sys; char *psz_address, *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL, *psz_crl = NULL, *psz_user = NULL, *psz_password = NULL, *psz_acl = NULL; int i_port = 0; char psz_tmp[10]; vlc_acl_t *p_acl = NULL; httpd_file_sys_t *f; vlc_mutex_init( p_access, &p_sys->httpd_mutex ); vlc_cond_init( p_access, &p_sys->httpd_cond ); p_sys->b_request_frontend_info = p_sys->b_request_mmi_info = VLC_FALSE; p_sys->i_httpd_timeout = 0; psz_address = var_GetString( p_access, "dvb-http-host" ); if( psz_address != NULL && *psz_address ) { char *psz_parser = strchr( psz_address, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; i_port = atoi( psz_parser ); } } else { if ( psz_address != NULL ) free( psz_address ); return VLC_SUCCESS; } /* determine SSL configuration */ psz_cert = var_GetString( p_access, "dvb-http-intf-cert" ); if ( psz_cert != NULL && *psz_cert ) { msg_Dbg( p_access, "enabling TLS for HTTP interface (cert file: %s)", psz_cert ); psz_key = config_GetPsz( p_access, "dvb-http-intf-key" ); psz_ca = config_GetPsz( p_access, "dvb-http-intf-ca" ); psz_crl = config_GetPsz( p_access, "dvb-http-intf-crl" ); if ( i_port <= 0 ) i_port = 8443; } else { if ( !*psz_cert ) { free( psz_cert ); psz_cert = NULL; } if ( i_port <= 0 ) i_port= 8082; } /* Ugly hack to allow to run several HTTP servers on different ports. */ sprintf( psz_tmp, ":%d", i_port + 1 ); config_PutPsz( p_access, "dvb-http-host", psz_tmp ); msg_Dbg( p_access, "base %s:%d", psz_address, i_port ); p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access), 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_access, "cannot listen on %s:%d", psz_address, i_port ); free( psz_address ); return VLC_EGENERIC; } free( psz_address ); psz_user = var_GetString( p_access, "dvb-http-user" ); psz_password = var_GetString( p_access, "dvb-http-password" ); psz_acl = var_GetString( p_access, "dvb-http-acl" ); if ( psz_acl != NULL ) { p_acl = ACL_Create( p_access, VLC_FALSE ); if( ACL_LoadFile( p_acl, psz_acl ) ) { ACL_Destroy( p_acl ); p_acl = NULL; } } /* Declare an index.html file. */ f = malloc( sizeof(httpd_file_sys_t) ); f->p_access = p_access; f->p_file = httpd_FileNew( p_sys->p_httpd_host, "/index.html", "text/html; charset=UTF-8", psz_user, psz_password, p_acl, HttpCallback, f ); FREE( psz_user ); FREE( psz_password ); FREE( psz_acl ); if ( p_acl != NULL ) ACL_Destroy( p_acl ); if ( f->p_file == NULL ) { free( f ); p_sys->p_httpd_file = NULL; return VLC_EGENERIC; } p_sys->p_httpd_file = f; p_sys->p_httpd_redir = httpd_RedirectNew( p_sys->p_httpd_host, "/index.html", "/" ); #undef FREE return VLC_SUCCESS; }
/***************************************************************************** * 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_Get( 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 = var_InheritString( p_intf, "http-handlers" ); if( psz_src != NULL ) { 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 = var_InheritString( 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_InheritString( p_intf, "http-intf-key" ); psz_ca = var_InheritString( p_intf, "http-intf-ca" ); psz_crl = var_InheritString( 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 ); 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 = var_InheritString( p_intf, "http-src" ); if( psz_src == NULL ) { char *data_path = config_GetDataDir( p_intf ); if( asprintf( &psz_src, "%s" DIR_SEP "http", data_path ) == -1 ) psz_src = NULL; free( data_path ); } if( psz_src == NULL ) { 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; } if( var_InheritBool( p_intf, "http-album-art" ) ) { /* FIXME: we're leaking h */ httpd_handler_sys_t *h = malloc( sizeof( httpd_handler_sys_t ) ); if( !h ) 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; } free( psz_src ); 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 ); return VLC_EGENERIC; }
httpd_host_t *httpd_HostNew (vlc_object_t *obj, const char *host, int port) { return httpd_TLSHostNew (obj, host, port, NULL, NULL, NULL, NULL); }