📄 webserver.c
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000-2003 Intel Corporation // All rights reserved. //// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: //// * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission.// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.//////////////////////////////////////////////////////////////////////////////************************************************************************* Purpose: This file defines the Web Server and has functions to carry out * operations of the Web Server. ************************************************************************/#include <assert.h>#include "util.h"#include "strintmap.h"#include "membuffer.h"#include "httpparser.h"#include "httpreadwrite.h"#include "statcodes.h"#include "webserver.h"#include "upnp.h"#include "config.h"#include "upnpapi.h"#include <unistd.h>#include <sys/stat.h>#include "ithread.h"#include "unixutil.h"/* Response Types */enum resp_type { RESP_FILEDOC, RESP_XMLDOC, RESP_HEADERS, RESP_WEBDOC, RESP_POST };// mapping of file extension to content-type of documentstruct document_type_t { const char *file_ext; const char *content_type; const char *content_subtype;};struct xml_alias_t { membuffer name; // name of DOC from root; e.g.: /foo/bar/mydesc.xml membuffer doc; // the XML document contents time_t last_modified; int *ct;};static const char *gMediaTypes[] = { NULL, // 0 "audio", // 1 "video", // 2 "image", // 3 "application", // 4 "text" // 5};/* Defines */// index into 'gMediaTypes'#define AUDIO_STR "\1"#define VIDEO_STR "\2"#define IMAGE_STR "\3"#define APPLICATION_STR "\4"#define TEXT_STR "\5"// int index#define APPLICATION_INDEX 4#define TEXT_INDEX 5// general#define NUM_MEDIA_TYPES 69#define NUM_HTTP_HEADER_NAMES 33// sorted by file extension; must have 'NUM_MEDIA_TYPES' extensionsstatic const char *gEncodedMediaTypes = "aif\0" AUDIO_STR "aiff\0" "aifc\0" AUDIO_STR "aiff\0" "aiff\0" AUDIO_STR "aiff\0" "asf\0" VIDEO_STR "x-ms-asf\0" "asx\0" VIDEO_STR "x-ms-asf\0" "au\0" AUDIO_STR "basic\0" "avi\0" VIDEO_STR "msvideo\0" "bmp\0" IMAGE_STR "bmp\0" "dcr\0" APPLICATION_STR "x-director\0" "dib\0" IMAGE_STR "bmp\0" "dir\0" APPLICATION_STR "x-director\0" "dxr\0" APPLICATION_STR "x-director\0" "gif\0" IMAGE_STR "gif\0" "hta\0" TEXT_STR "hta\0" "htm\0" TEXT_STR "html\0" "html\0" TEXT_STR "html\0" "jar\0" APPLICATION_STR "java-archive\0" "jfif\0" IMAGE_STR "pjpeg\0" "jpe\0" IMAGE_STR "jpeg\0" "jpeg\0" IMAGE_STR "jpeg\0" "jpg\0" IMAGE_STR "jpeg\0" "js\0" APPLICATION_STR "x-javascript\0" "kar\0" AUDIO_STR "midi\0" "m3u\0" AUDIO_STR "mpegurl\0" "mid\0" AUDIO_STR "midi\0" "midi\0" AUDIO_STR "midi\0" "mov\0" VIDEO_STR "quicktime\0" "mp2v\0" VIDEO_STR "x-mpeg2\0" "mp3\0" AUDIO_STR "mpeg\0" "mpe\0" VIDEO_STR "mpeg\0" "mpeg\0" VIDEO_STR "mpeg\0" "mpg\0" VIDEO_STR "mpeg\0" "mpv\0" VIDEO_STR "mpeg\0" "mpv2\0" VIDEO_STR "x-mpeg2\0" "pdf\0" APPLICATION_STR "pdf\0" "pjp\0" IMAGE_STR "jpeg\0" "pjpeg\0" IMAGE_STR "jpeg\0" "plg\0" TEXT_STR "html\0" "pls\0" AUDIO_STR "scpls\0" "png\0" IMAGE_STR "png\0" "qt\0" VIDEO_STR "quicktime\0" "ram\0" AUDIO_STR "x-pn-realaudio\0" "rmi\0" AUDIO_STR "mid\0" "rmm\0" AUDIO_STR "x-pn-realaudio\0" "rtf\0" APPLICATION_STR "rtf\0" "shtml\0" TEXT_STR "html\0" "smf\0" AUDIO_STR "midi\0" "snd\0" AUDIO_STR "basic\0" "spl\0" APPLICATION_STR "futuresplash\0" "ssm\0" APPLICATION_STR "streamingmedia\0" "swf\0" APPLICATION_STR "x-shockwave-flash\0" "tar\0" APPLICATION_STR "tar\0" "tcl\0" APPLICATION_STR "x-tcl\0" "text\0" TEXT_STR "plain\0" "tif\0" IMAGE_STR "tiff\0" "tiff\0" IMAGE_STR "tiff\0" "txt\0" TEXT_STR "plain\0" "ulw\0" AUDIO_STR "basic\0" "wav\0" AUDIO_STR "wav\0" "wax\0" AUDIO_STR "x-ms-wax\0" "wm\0" VIDEO_STR "x-ms-wm\0" "wma\0" AUDIO_STR "x-ms-wma\0" "wmv\0" VIDEO_STR "x-ms-wmv\0" "wvx\0" VIDEO_STR "x-ms-wvx\0" "xbm\0" IMAGE_STR "x-xbitmap\0" "xml\0" TEXT_STR "xml\0" "xsl\0" TEXT_STR "xml\0" "z\0" APPLICATION_STR "x-compress\0" "zip\0" APPLICATION_STR "zip\0" "\0"; // *** end ***/***********************************************************************//* module variables - Globals, static and externs *//***********************************************************************/static struct document_type_t gMediaTypeList[NUM_MEDIA_TYPES];membuffer gDocumentRootDir; // a local dir which serves as webserver rootstatic struct xml_alias_t gAliasDoc; // XML documentstatic ithread_mutex_t gWebMutex;extern str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES];/************************************************************************* Function: has_xml_content_type * * Parameters: * none * * Description: decodes list and stores it in gMediaTypeList * * Returns: * void ************************************************************************/static XINLINE voidmedia_list_init( void ){ int i; const char *s = gEncodedMediaTypes; struct document_type_t *doc_type; for( i = 0; *s != '\0'; i++ ) { doc_type = &gMediaTypeList[i]; doc_type->file_ext = s; s += strlen( s ) + 1; // point to type doc_type->content_type = gMediaTypes[( int )*s]; // set cont-type s++; // point to subtype doc_type->content_subtype = s; s += strlen( s ) + 1; // next entry } assert( i == NUM_MEDIA_TYPES );}/************************************************************************* Function: has_xml_content_type * * Parameters: * IN const char* extension ; * OUT const char** con_type, * OUT const char** con_subtype * * Description: Based on the extension, returns the content type and * content subtype * * Returns: * 0 on success; * -1 on error ************************************************************************/static XINLINE intsearch_extension( IN const char *extension, OUT const char **con_type, OUT const char **con_subtype ){ int top, mid, bot; int cmp; top = 0; bot = NUM_MEDIA_TYPES - 1; while( top <= bot ) { mid = ( top + bot ) / 2; cmp = strcasecmp( extension, gMediaTypeList[mid].file_ext ); if( cmp > 0 ) { top = mid + 1; // look below mid } else if( cmp < 0 ) { bot = mid - 1; // look above mid } else // cmp == 0 { *con_type = gMediaTypeList[mid].content_type; *con_subtype = gMediaTypeList[mid].content_subtype; return 0; } } return -1;}/************************************************************************* Function: get_content_type * * Parameters: * IN const char* filename, * OUT DOMString* content_type * * Description: Based on the extension, clones an XML string based on * type and content subtype. If content type and sub type are not * found, unknown types are used * * Returns: * 0 - On Sucess * UPNP_E_OUTOF_MEMORY - on memory allocation failures ************************************************************************/XINLINE intget_content_type( IN const char *filename, OUT DOMString * content_type ){ const char *extension; const char *type, *subtype; xboolean ctype_found = FALSE; char *temp = NULL; int length = 0; ( *content_type ) = NULL; // get ext extension = strrchr( filename, '.' ); if( extension != NULL ) { if( search_extension( extension + 1, &type, &subtype ) == 0 ) { ctype_found = TRUE; } } if( !ctype_found ) { // unknown content type type = gMediaTypes[APPLICATION_INDEX]; subtype = "octet-stream"; } length = strlen( type ) + strlen( "/" ) + strlen( subtype ) + 1; temp = ( char * )malloc( length ); if( !temp ) { return UPNP_E_OUTOF_MEMORY; } sprintf( temp, "%s/%s", type, subtype ); ( *content_type ) = ixmlCloneDOMString( temp ); free( temp ); if( !content_type ) { return UPNP_E_OUTOF_MEMORY; } return 0;}/************************************************************************* Function: glob_alias_init * * Parameters: * none * * Description: Initialize the global XML document. Allocate buffers * for the XML document * * Returns: * void ************************************************************************/static XINLINE voidglob_alias_init( void ){ struct xml_alias_t *alias = &gAliasDoc; membuffer_init( &alias->doc ); membuffer_init( &alias->name ); alias->ct = NULL; alias->last_modified = 0;}/************************************************************************* Function: is_valid_alias * * Parameters: * IN const struct xml_alias_t* alias ; XML alias object * * Description: Check for the validity of the XML object buffer * * Returns: * BOOLEAN ************************************************************************/static XINLINE xbooleanis_valid_alias( IN const struct xml_alias_t *alias ){ return alias->doc.buf != NULL;}/************************************************************************* Function: alias_grab * * Parameters: * OUT struct xml_alias_t* alias ; XML alias object * * Description: Copy the contents of the global XML document into the * local OUT parameter * * Returns: * void ************************************************************************/static voidalias_grab( OUT struct xml_alias_t *alias ){ ithread_mutex_lock( &gWebMutex ); assert( is_valid_alias( &gAliasDoc ) ); memcpy( alias, &gAliasDoc, sizeof( struct xml_alias_t ) ); *alias->ct = *alias->ct + 1; ithread_mutex_unlock( &gWebMutex );}/************************************************************************* Function: alias_release * * Parameters: * IN struct xml_alias_t* alias ; XML alias object * * Description: Release the XML document referred to by the IN parameter * Free the allocated buffers associated with this object * * Returns: * void ************************************************************************/static voidalias_release( IN struct xml_alias_t *alias ){ ithread_mutex_lock( &gWebMutex ); // ignore invalid alias if( !is_valid_alias( alias ) ) { ithread_mutex_unlock( &gWebMutex ); return; } assert( alias->ct > 0 ); *alias->ct = *alias->ct - 1; if( *alias->ct <= 0 ) { membuffer_destroy( &alias->doc ); membuffer_destroy( &alias->name ); free( alias->ct ); } ithread_mutex_unlock( &gWebMutex );}/************************************************************************* Function: web_server_set_alias * * Parameters: * alias_name: webserver name of alias; created by caller and freed by * caller (doesn't even have to be malloc()d .) * alias_content: the xml doc; this is allocated by the caller; and * freed by the web server
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -