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

📄 webserver.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 4 页
字号:
    int i,      F = -1,      L = -1;    int Is_Suffix_byte_Range = 1;    if( *SrcRangeStr == NULL )        return -1;    Tok = StrTok( SrcRangeStr, "," );    if( ( Ptr = strstr( Tok, "-" ) ) == NULL )        return -1;    *Ptr = ' ';    sscanf( Tok, "%d%d", &F, &L );    if( F == -1 || L == -1 ) {        *Ptr = '-';        for( i = 0; i < ( int )strlen( Tok ); i++ ) {            if( Tok[i] == '-' ) {                break;            } else if( isdigit( Tok[i] ) ) {                Is_Suffix_byte_Range = 0;                break;            }        }        if( Is_Suffix_byte_Range ) {            *FirstByte = L;            *LastByte = F;            return 1;        }    }    *FirstByte = F;    *LastByte = L;    return 1;}/************************************************************************* Function: CreateHTTPRangeResponseHeader								*																		* Parameters:															*	char * ByteRangeSpecifier ; String containing the range 	*	long FileLength ; Length of the file													*	OUT struct SendInstruction * Instr ; SendInstruction object	where the *										range operations will be stored*																		* Description: Fills in the Offset, read size and contents to send out	*	as an HTTP Range Response											*																		* Returns:																*	HTTP_BAD_REQUEST													*	UPNP_E_OUTOF_MEMORY													*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									*	HTTP_OK																************************************************************************/intCreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,                               long FileLength,                               OUT struct SendInstruction *Instr ){    int FirstByte,      LastByte;    char *RangeInput,     *Ptr;    Instr->IsRangeActive = 1;    Instr->ReadSendSize = FileLength;    if( !ByteRangeSpecifier )        return HTTP_BAD_REQUEST;    RangeInput = malloc( strlen( ByteRangeSpecifier ) + 1 );    if( !RangeInput )        return UPNP_E_OUTOF_MEMORY;    strcpy( RangeInput, ByteRangeSpecifier );    //CONTENT-RANGE: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT    if( StrStr( RangeInput, "bytes" ) == NULL ||        ( Ptr = StrStr( RangeInput, "=" ) ) == NULL ) {        free( RangeInput );        Instr->IsRangeActive = 0;        return HTTP_BAD_REQUEST;    }    //Jump =    Ptr = Ptr + 1;    if( FileLength < 0 ) {        free( RangeInput );        return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;    }    if( GetNextRange( &Ptr, &FirstByte, &LastByte ) != -1 ) {        if( FileLength < FirstByte ) {            free( RangeInput );            return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;        }        if( FirstByte >= 0 && LastByte >= 0 && LastByte >= FirstByte ) {            if( LastByte >= FileLength )                LastByte = FileLength - 1;            Instr->RangeOffset = FirstByte;            Instr->ReadSendSize = LastByte - FirstByte + 1;            sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes %d-%d/%ld\r\n", FirstByte, LastByte, FileLength );   //Data between two range.        } else if( FirstByte >= 0 && LastByte == -1                   && FirstByte < FileLength ) {            Instr->RangeOffset = FirstByte;            Instr->ReadSendSize = FileLength - FirstByte;            sprintf( Instr->RangeHeader,                     "CONTENT-RANGE: bytes %d-%ld/%ld\r\n", FirstByte,                     FileLength - 1, FileLength );        } else if( FirstByte == -1 && LastByte > 0 ) {            if( LastByte >= FileLength ) {                Instr->RangeOffset = 0;                Instr->ReadSendSize = FileLength;                sprintf( Instr->RangeHeader,                         "CONTENT-RANGE: bytes 0-%ld/%ld\r\n",                         FileLength - 1, FileLength );            } else {                Instr->RangeOffset = FileLength - LastByte;                Instr->ReadSendSize = LastByte;                sprintf( Instr->RangeHeader,                         "CONTENT-RANGE: bytes %ld-%ld/%ld\r\n",                         FileLength - LastByte + 1, FileLength,                         FileLength );            }        } else {            free( RangeInput );            return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;        }    } else {        free( RangeInput );        return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;    }    free( RangeInput );    return HTTP_OK;}/************************************************************************* Function: CheckOtherHTTPHeaders										*																		* Parameters:															*	IN http_message_t * Req ;  HTTP Request message*	OUT struct SendInstruction * RespInstr ; Send Instruction object to *							data for the response*	int FileSize ;	Size of the file containing the request document*																		* Description: Get header id from the request parameter and take		*	appropriate action based on the ids.								*	as an HTTP Range Response											*																		* Returns:																*	HTTP_BAD_REQUEST													*	UPNP_E_OUTOF_MEMORY													*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									*	HTTP_OK																************************************************************************/intCheckOtherHTTPHeaders( IN http_message_t * Req,                       OUT struct SendInstruction *RespInstr,                       int FileSize ){    http_header_t *header;    ListNode *node;    //NNS: dlist_node* node;    int index,      RetCode = HTTP_OK;    char *TmpBuf;    TmpBuf = ( char * )malloc( LINE_SIZE );    if( !TmpBuf )        return UPNP_E_OUTOF_MEMORY;    node = ListHead( &Req->headers );    while( node != NULL ) {        header = ( http_header_t * ) node->item;        // find header type.        index = map_str_to_int( ( const char * )header->name.buf,                                header->name.length, Http_Header_Names,                                NUM_HTTP_HEADER_NAMES, FALSE );        if( header->value.length >= LINE_SIZE ) {            free( TmpBuf );            TmpBuf = ( char * )malloc( header->value.length + 1 );            if( !TmpBuf )                return UPNP_E_OUTOF_MEMORY;        }        memcpy( TmpBuf, header->value.buf, header->value.length );        TmpBuf[header->value.length] = '\0';        if( index >= 0 )            switch ( Http_Header_Names[index].id ) {                case HDR_TE:   //Request                    {                        RespInstr->IsChunkActive = 1;                        if( strlen( TmpBuf ) > strlen( "gzip" ) ) {                            if( StrStr( TmpBuf, "trailers" ) != NULL ) {    //means client will accept trailer                                RespInstr->IsTrailers = 1;                            }                        }                    }                    break;                case HDR_CONTENT_LENGTH:                    {                        RespInstr->RecvWriteSize = atoi( TmpBuf );                        break;                    }                case HDR_RANGE:                    if( ( RetCode = CreateHTTPRangeResponseHeader( TmpBuf,                                                                   FileSize,                                                                   RespInstr ) )                        != HTTP_OK ) {                        free( TmpBuf );                        return RetCode;                    }                    break;                default:                    /*                       TODO                      */                    /*                       header.value is the value.                      */                    /*                       case HDR_CONTENT_TYPE: //return 1;                       case HDR_CONTENT_LANGUAGE://return 1;                       case HDR_LOCATION: //return 1;                       case HDR_CONTENT_LOCATION://return 1;                       case HDR_ACCEPT: //return 1;                       case HDR_ACCEPT_CHARSET://return 1;                       case HDR_ACCEPT_LANGUAGE://return 1;                       case HDR_USER_AGENT: break;//return 1;                     */                    //Header check for encoding                     /*                       case HDR_ACCEPT_RANGE: //Server capability.                       case HDR_CONTENT_RANGE://Response.                       case HDR_IF_RANGE:                     */                    //Header check for encoding                     /*                       case HDR_ACCEPT_ENCODING:                       if(StrStr(TmpBuf, "identity"))                       {                       break;                       }                       else return -1;                       case HDR_CONTENT_ENCODING:                       case HDR_TRANSFER_ENCODING: //Response                     */                    break;            }        node = ListNext( &Req->headers, node );    }    free( TmpBuf );    return RetCode;}/************************************************************************* Function: process_request												*																		* Parameters:															*	IN http_message_t *req ; HTTP Request message												*	OUT enum resp_type *rtype ; Tpye of response											*	OUT membuffer *headers ; 												*	OUT membuffer *filename ; Get filename from request document*	OUT struct xml_alias_t *alias ; Xml alias document from the *									request document,										*	OUT struct SendInstruction * RespInstr ; Send Instruction object *					where the response is set up.										*																		* Description: Processes the request and returns the result in the OUT	*	parameters															*																		* Returns:																*	HTTP_BAD_REQUEST													*	UPNP_E_OUTOF_MEMORY													*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									*	HTTP_OK																************************************************************************/static intprocess_request( IN http_message_t * req,                 OUT enum resp_type *rtype,                 OUT membuffer * headers,                 OUT membuffer * filename,                 OUT struct xml_alias_t *alias,                 OUT struct SendInstruction *RespInstr ){    int code;    int err_code;    //membuffer content_type;    char *request_doc;    struct File_Info finfo;    xboolean using_alias;    xboolean using_virtual_dir;    uri_type *url;    char *temp_str;    int resp_major,      resp_minor;    xboolean alias_grabbed;    int dummy;    struct UpnpVirtualDirCallbacks *pVirtualDirCallback;    print_http_headers( req );    url = &req->uri;    assert( req->method == HTTPMETHOD_GET ||            req->method == HTTPMETHOD_HEAD            || req->method == HTTPMETHOD_POST            || req->method == HTTPMETHOD_SIMPLEGET );    // init    request_doc = NULL;    finfo.content_type = NULL;    //membuffer_init( &content_type );    alias_grabbed = FALSE;    err_code = HTTP_INTERNAL_SERVER_ERROR;  // default error    using_virtual_dir = FALSE;    using_alias = FALSE;    http_CalcResponseVersion( req->major_version, req->minor_version,                              &resp_major, &resp_minor );    //    // remove dots    //    request_doc = malloc( url->pathquery.size + 1 );    if( request_doc == NULL ) {        goto error_handler;     // out of mem    }    memcpy( request_doc, url->pathquery.buff, url->pathquery.size );    request_doc[url->pathquery.size] = '\0';    dummy = url->pathquery.size;    remove_escaped_chars( request_doc, &dummy );    code = remove_dots( request_doc, url->pathquery.size );    if( code != 0 ) {        err_code = HTTP_FORBIDDEN;        goto error_handler;    }    if( *request_doc != '/' ) {        // no slash        err_code = HTTP_BAD_REQUEST;        goto error_handler;    }    if( isFileInVirtualDir( request_doc ) ) {        using_virtual_dir = TRUE;        RespInstr->IsVirtualFile = 1;        if( membuffer_assign_str( filename, request_doc ) != 0 ) {            goto error_handler;        }    } else {        //        // try using alias        //        if( is_valid_alias( &gAliasDoc ) ) {            alias_grab( alias );            alias_grabbed = TRUE;            using_alias = get_alias( request_doc, alias, &finfo );            if( using_alias == TRUE ) {                finfo.content_type = ixmlCloneDOMString( "text/xml" );                if( finfo.content_type == NULL ) {                    goto error_handler;                }            }        }    }    if( using_virtual_dir ) {        if( req->method != HTTPMETHOD_POST ) {            // get file info            pVirtualDirCallback = &virtualDirCallback;            if( pVirtualDirCallback->get_info( filename->buf, &finfo ) !=                0 ) {                err_code = HTTP_NOT_FOUND;                goto error_handler;            }            // try index.html if req is a dir            if( finfo.is_directory ) {                if( filename->buf[filename->length - 1] == '/' ) {                    temp_str = "index.html";                } else {                    temp_str = "/index.html";                }                if( membuffer_append_str( filename, temp_str ) != 0 ) {                    goto error_handler;                }                // get info                if( ( pVirtualDirCallback->                      get_info( filename->buf, &finfo ) != UPNP_E_SUCCESS )                    || finfo.is_directory ) {                    err_code = HTTP_NOT_FOUND;                    goto error_handler;                }            }            // not readable            if( !finfo.is_readable ) {                err_code = HTTP_FORBIDDEN;                goto error_handler;            }            // finally, get content type            // if ( get_content_type(filename->buf, &content_type) != 0 )            //{            //  goto error_handler;            // }        }    } else if( !using_alias ) {        if( gDocumentRootDir.length == 0 ) {            goto error_handler;        }        //        // get file name        //

⌨️ 快捷键说明

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