📄 server.cpp
字号:
// determine new dot index dot_index = GetExtensionIndex( actualAlias ); } assert( find(actualAlias.c_str()) == NULL ); } DBG( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__, "actual alias = %s\n", actualAlias.c_str()); ) // fill values ae->alias = actualAlias; ae->entity = entity; ae->modifiedTime = time( NULL ); ae->count = 1; ae->stopServing = false; if ( dot_index == -1 ) { ae->contentType = ApplicationStr; ae->contentSubtype = "octet-stream"; } else { GetMediaType( actualAlias.c_str() + dot_index + 1, ae->contentType, ae->contentSubtype ); } aliasList.addAfterTail( ae ); } catch ( int excepCode ) { eCode = excepCode; } pthread_mutex_unlock( &mutex ); if ( eCode == -5 ) { throw OutOfMemoryException("AliasedEntityList::addEntity()" ); }}////////////////////////////////////////void AliasedEntityList::grabEntity( IN const char* alias, OUT HttpEntity** entity, OUT xstring& contentType, OUT xstring& contentSubtype, OUT time_t& lastModifiedTime ){ dblListNode *node; AliasedEntity* ae; int eCode; pthread_mutex_lock( &mutex ); try { node = find( alias ); if ( node == NULL ) { throw -2; // alias not found } ae = (AliasedEntity*) (node->data); assert( ae != NULL ); // if not serving anymore - fake not found if ( ae->stopServing ) { throw -2; } *entity = ae->entity; contentType = ae->contentType; contentSubtype = ae->contentSubtype; lastModifiedTime = ae->modifiedTime; ae->count++; eCode = 0; } catch ( int excepCode ) { eCode = excepCode; } pthread_mutex_unlock( &mutex ); if ( eCode == -2 ) { AliasedListException e("grabEntity(): alias not found"); e.setErrorCode( E_NOT_FOUND ); throw e; }}////////////////////////////////////////void AliasedEntityList::releaseEntity( IN const char* alias, bool stopServing ){ dblListNode * node; AliasedEntity* ae; int eCode; pthread_mutex_lock( &mutex ); try { node = find( alias ); if ( node == NULL ) { throw -2; // alias not found } ae = (AliasedEntity *)(node->data); ae->stopServing = stopServing; assert( ae->count > 0 ); if ( --ae->count <= 0 ) { aliasList.remove( node ); } eCode = 0; } catch ( int excepCode ) { eCode = excepCode; } pthread_mutex_unlock( &mutex ); if ( eCode == -2 ) { AliasedListException e("releaseEntity(): alias not found"); e.setErrorCode( E_NOT_FOUND ); throw e; }}////////////////////////////////////////bool AliasedEntityList::isAliasPresent( IN const char* alias ){ dblListNode *node; pthread_mutex_lock( &mutex ); node = find(alias); pthread_mutex_lock( &mutex ); return node != NULL;}////////////////////////////////////////dblListNode* AliasedEntityList::find( IN const char* alias ){ AliasedEntity key; dblListNode* result; key.alias = alias; result = aliasList.find( &key ); return result;}///////////////////////////////////////void http_SetRootDir( const char* httpRootDir ){ if ( httpRootDir == NULL ) { // deactivate server gServerActive = false; gRootDocumentDir = "/###***%////"; } else { xstring &s = gRootDocumentDir; s = httpRootDir; // remove trailing '/', if any if ( s.length() > 0 ) { int index = s.length() - 1; if ( s[index] == '/' ) { s.deleteSubstring( index, 1 ); } } DBG( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__, "http_SetRootDir(): root = '%s'\n", s.c_str()); ) gServerActive = true; }}////////////////////////////////////////////// returns:// 1: 'filename' is a regular file// 2: 'filename' is a directory (fileLength, last_modified not returned)// -1: filename in neither a file nor a directory//static int GetFileInfo( IN const char* filename, OUT int& fileLength, OUT time_t& last_modified ){ int code; struct stat s; int fileType; code = stat( filename, &s ); if ( code == -1 ) { return -1; } if ( S_ISREG(s.st_mode) ) { fileType = 1; // reg file // DBG( printf("is regular file\n"); ) } else if ( S_ISDIR(s.st_mode) ) { fileType = 2; //DBG( printf("is directory\n"); ) return fileType; } else { //DBG( printf("invalid file type\n"); ) return -1; } fileLength = s.st_size; //DBG( printf("fileLength = %d\n", fileLength); ) last_modified = s.st_mtime; //DBG( //struct tm* last_mod; //last_mod = gmtime( &s.st_mtime ); //printf("last mod = %s\n", asctime(last_mod) ); //) return fileType;}////////////////////////////////////////////// determines resource filename and its length from given request//// throws HttpServerException// HTTP_BAD_REQUEST,// HTTP_NOT_FOUND,// HTTP_INTERNAL_SERVER_ERROR// HTTP_FORBIDDENstatic void GetFilename( IN HttpMessage& request, OUT xstring& filename, OUT int& fileLength, OUT time_t& last_modified ){ xstring resourceName; uri_type* uri; HttpServerException e; uri = &request.requestLine.uri.uri; resourceName.copyLimited( uri->pathquery.buff, uri->pathquery.size ); try { // security: do not allow access to files above the // http root dir //if ( strstr(resourceName.c_str(), "..") != NULL ) //{ // throw HTTP_FORBIDDEN; //} if ( request.requestLine.pathIsStar || resourceName.length() == 0 || resourceName[0] != '/' ) { throw HTTP_BAD_REQUEST; } // get file info { const char* tempResPtr; xstring resName; char *tempBuf; int code; resName = resourceName; tempBuf = resName.detach(); code = remove_dots( tempBuf, strlen(tempBuf) ); resourceName = tempBuf; free( tempBuf ); if ( code != 0 ) { throw HTTP_FORBIDDEN; } filename = gRootDocumentDir; // append '/' suffix if ( (gRootDocumentDir.length() > 0 && gRootDocumentDir[gRootDocumentDir.length()-1] != '/') || (gRootDocumentDir.length() == 0) ) { filename += '/'; } // skip leading '/' tempResPtr = resourceName.c_str(); tempResPtr += (resourceName[0] == '/' ? 1 : 0); filename += tempResPtr; } int fileType; fileType = GetFileInfo( filename.c_str(), fileLength, last_modified ); if ( fileType == -1 ) { throw HTTP_NOT_FOUND; // file not found } if ( fileType == 2 ) { // handle dir; use default index.html // add '/' suffix if ( filename[filename.length()-1] != '/' ) { filename += '/'; } filename += "index.html"; fileType = GetFileInfo( filename.c_str(), fileLength, last_modified ); if ( fileType != 1 ) { // not a file throw HTTP_NOT_FOUND; } } // make sure file is readable { FILE *fp; fp = fopen( filename.c_str(), "r" ); if ( fp == NULL ) { throw HTTP_FORBIDDEN; } fclose( fp ); } assert( fileType == 1 ); // regular file DBG( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__, "GetFileName(): file: %s\n", filename.c_str()); ) } catch ( int code ) { //DBG( perror("GetFilename()"); ) DBG( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__, "GetFileName() error: %s\n", strerror(errno)); ) e.setErrorCode( code ); throw e; }}////////////////////////////////////////////// Sees if request doc is an alias. If it is, the entity is// loaded into the response.//// returns:// 0: success; loaded alias in request// -1: did not find aliasstatic int TryToGetAlias( IN HttpMessage& request, OUT HttpMessage& response, OUT xstring& aliasOut ){ xstring resourceName; uri_type* uri; int retCode = 0; char *tempBuf; uri = &request.requestLine.uri.uri; resourceName.copyLimited( uri->pathquery.buff, uri->pathquery.size ); tempBuf = resourceName.detach(); retCode = remove_dots( tempBuf, strlen(tempBuf) ); resourceName = tempBuf; free( tempBuf ); if ( retCode != 0 ) { return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -