📄 webserver.c
字号:
* alias_content_length: length of alias body in bytes * last_modified: time when the contents of alias were last * changed (local time) * * Description: Replaces current alias with the given alias. To remove * the current alias, set alias_name to NULL. * * Returns: * 0 - OK * UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here ************************************************************************/intweb_server_set_alias( IN const char *alias_name, IN const char *alias_content, IN size_t alias_content_length, IN time_t last_modified ){ int ret_code; struct xml_alias_t alias; alias_release( &gAliasDoc ); if( alias_name == NULL ) { // don't serve aliased doc anymore return 0; } assert( alias_content != NULL ); membuffer_init( &alias.doc ); membuffer_init( &alias.name ); alias.ct = NULL; do { // insert leading /, if missing if( *alias_name != '/' ) { if( membuffer_assign_str( &alias.name, "/" ) != 0 ) { break; // error; out of mem } } ret_code = membuffer_append_str( &alias.name, alias_name ); if( ret_code != 0 ) { break; // error } if( ( alias.ct = ( int * )malloc( sizeof( int ) ) ) == NULL ) { break; // error } *alias.ct = 1; membuffer_attach( &alias.doc, ( char * )alias_content, alias_content_length ); alias.last_modified = last_modified; // save in module var ithread_mutex_lock( &gWebMutex ); gAliasDoc = alias; ithread_mutex_unlock( &gWebMutex ); return 0; } while( FALSE ); // error handler // free temp alias membuffer_destroy( &alias.name ); membuffer_destroy( &alias.doc ); free( alias.ct ); return UPNP_E_OUTOF_MEMORY;}/************************************************************************* Function: web_server_init * * Parameters: * none * * Description: Initilialize the different documents. Initialize the * memory for root directory for web server. Call to initialize global * XML document. Sets bWebServerState to WEB_SERVER_ENABLED * * Returns: * 0 - OK * UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here ************************************************************************/intweb_server_init( void ){ int ret_code; if( bWebServerState == WEB_SERVER_DISABLED ) { media_list_init( ); // decode media list membuffer_init( &gDocumentRootDir ); glob_alias_init( ); pVirtualDirList = NULL; ret_code = ithread_mutex_init( &gWebMutex, NULL ); if( ret_code == -1 ) { return UPNP_E_OUTOF_MEMORY; } bWebServerState = WEB_SERVER_ENABLED; } return 0;}/************************************************************************* Function: web_server_destroy * * Parameters: * none * * Description: Release memory allocated for the global web server root * directory and the global XML document * Resets the flag bWebServerState to WEB_SERVER_DISABLED * * Returns: * void ************************************************************************/voidweb_server_destroy( void ){ int ret; if( bWebServerState == WEB_SERVER_ENABLED ) { membuffer_destroy( &gDocumentRootDir ); alias_release( &gAliasDoc ); ithread_mutex_lock( &gWebMutex ); memset( &gAliasDoc, 0, sizeof( struct xml_alias_t ) ); ithread_mutex_unlock( &gWebMutex ); ret = ithread_mutex_destroy( &gWebMutex ); assert( ret == 0 ); bWebServerState = WEB_SERVER_DISABLED; }}/************************************************************************* Function: get_file_info * * Parameters: * IN const char* filename ; Filename having the description document* OUT struct File_Info * info ; File information object having file * attributes such as filelength, when was * the file last modified, whether a file * or a directory and whether the file or* directory is readable. * * Description: Release memory allocated for the global web server root * directory and the global XML document * Resets the flag bWebServerState to WEB_SERVER_DISABLED * * Returns: * int ************************************************************************/static intget_file_info( IN const char *filename, OUT struct File_Info *info ){ int code; struct stat s; FILE *fp; int rc = 0; info->content_type = NULL; code = stat( filename, &s ); if( code == -1 ) { return -1; } if( S_ISDIR( s.st_mode ) ) { info->is_directory = TRUE; } else if( S_ISREG( s.st_mode ) ) { info->is_directory = FALSE; } else { return -1; } // check readable fp = fopen( filename, "r" ); info->is_readable = ( fp != NULL ); if( fp ) { fclose( fp ); } info->file_length = s.st_size; info->last_modified = s.st_mtime; rc = get_content_type( filename, &info->content_type ); DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "file info: %s, length: %d, last_mod=%s readable=%d\n", filename, info->file_length, asctime( gmtime( &info->last_modified ) ), info->is_readable ); ) return rc;}/************************************************************************* Function: web_server_set_root_dir * * Parameters: * IN const char* root_dir ; String having the root directory for the * document * * Description: Assign the path specfied by the IN const char* root_dir * parameter to the global Document root directory. Also check for * path names ending in '/' * * Returns: * int ************************************************************************/intweb_server_set_root_dir( IN const char *root_dir ){ int index; int ret; ret = membuffer_assign_str( &gDocumentRootDir, root_dir ); if( ret != 0 ) { return ret; } // remove trailing '/', if any if( gDocumentRootDir.length > 0 ) { index = gDocumentRootDir.length - 1; // last char if( gDocumentRootDir.buf[index] == '/' ) { membuffer_delete( &gDocumentRootDir, index, 1 ); } } return 0;}/************************************************************************* Function: get_alias * * Parameters: * IN const char* request_file ; request file passed in to be compared with* OUT struct xml_alias_t* alias ; xml alias object which has a file name * stored * OUT struct File_Info * info ; File information object which will be * filled up if the file comparison * succeeds * * Description: Compare the files names between the one on the XML alias * the one passed in as the input parameter. If equal extract file * information* * Returns: * TRUE - On Success * FALSE if request is not an alias ************************************************************************/static XINLINE xbooleanget_alias( IN const char *request_file, OUT struct xml_alias_t *alias, OUT struct File_Info *info ){ int cmp; cmp = strcmp( alias->name.buf, request_file ); if( cmp == 0 ) { // fill up info info->file_length = alias->doc.length; info->is_readable = TRUE; info->is_directory = FALSE; info->last_modified = alias->last_modified; } return cmp == 0;}/************************************************************************* Function: isFileInVirtualDir * * Parameters: * IN char *filePath ; directory path to be tested for virtual directory* * Description: Compares filePath with paths from the list of virtual* directory lists* * Returns: * BOOLEAN ************************************************************************/intisFileInVirtualDir( IN char *filePath ){ virtualDirList *pCurVirtualDir; int webDirLen; pCurVirtualDir = pVirtualDirList; while( pCurVirtualDir != NULL ) { webDirLen = strlen( pCurVirtualDir->dirName ); if( pCurVirtualDir->dirName[webDirLen - 1] == '/' ) { if( strncmp( pCurVirtualDir->dirName, filePath, webDirLen ) == 0 ) return TRUE; } else { if( ( strncmp( pCurVirtualDir->dirName, filePath, webDirLen ) == 0 ) && ( filePath[webDirLen] == '/' ) ) return TRUE; } pCurVirtualDir = pCurVirtualDir->next; } return FALSE;}/************************************************************************* Function: ToUpperCase * * Parameters: * INOUT char * Str ; Input string to be converted * * Description: Converts input string to upper case * * Returns: * int ************************************************************************/intToUpperCase( char *Str ){ int i; for( i = 0; i < ( int )strlen( Str ); i++ ) Str[i] = toupper( Str[i] ); return 1;}/************************************************************************* Function: StrStr * * Parameters: * IN char * S1 ; Input string* IN char * S2 ; Input sub-string * * Description: Finds a substring from a string * * Returns: * char * ptr - pointer to the first occurence of S2 in S1 ************************************************************************/char *StrStr( char *S1, char *S2 ){ char *Str1, *Str2; char *Ptr, *Ret; int Pos; Str1 = ( char * )malloc( strlen( S1 ) + 2 ); Str2 = ( char * )malloc( strlen( S2 ) + 2 ); if( !Str1 || !Str2 ) return NULL; strcpy( Str1, S1 ); strcpy( Str2, S2 ); ToUpperCase( Str1 ); ToUpperCase( Str2 ); Ptr = strstr( Str1, Str2 ); if( Ptr == NULL ) return NULL; Pos = Ptr - Str1; Ret = S1 + Pos; free( Str1 ); free( Str2 ); return Ret;}/************************************************************************* Function: StrTok * * Parameters: * IN char ** Src ; String containing the token * IN char * del ; Set of delimiter characters * * Description: Finds next token in a string * * Returns: * char * ptr - pointer to the first occurence of S2 in S1 ************************************************************************/char *StrTok( char **Src, char *Del ){ char *TmpPtr, *RetPtr; if( *Src != NULL ) { RetPtr = *Src; TmpPtr = strstr( *Src, Del ); if( TmpPtr != NULL ) { *TmpPtr = '\0'; *Src = TmpPtr + strlen( Del ); } else *Src = NULL; return RetPtr; } return NULL;}/************************************************************************* Function: GetNextRange * * Parameters: * IN char ** SrcRangeStr ; string containing the token / range * OUT int * FirstByte ; gets the first byte of the token * OUT int * LastByte ; gets the last byte of the token * * Description: Returns a range of integers from a sring * * Returns: int ;* always returns 1; ************************************************************************/intGetNextRange( char **SrcRangeStr, int *FirstByte, int *LastByte ){ char *Ptr, *Tok;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -