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

📄 webserver.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 4 页
字号:
        // filename str        if( membuffer_assign_str( filename, gDocumentRootDir.buf ) != 0 ||            membuffer_append_str( filename, request_doc ) != 0 ) {            goto error_handler; // out of mem        }        // remove trailing slashes        while( filename->length > 0 &&               filename->buf[filename->length - 1] == '/' ) {            membuffer_delete( filename, filename->length - 1, 1 );        }        if( req->method != HTTPMETHOD_POST ) {            // get info on file            if( get_file_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( get_file_info( filename->buf, &finfo ) != 0 ||                    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;        //      }    }    RespInstr->ReadSendSize = finfo.file_length;    //Check other header field.    if( ( err_code =          CheckOtherHTTPHeaders( req, RespInstr,                                 finfo.file_length ) ) != HTTP_OK ) {        goto error_handler;    }    if( req->method == HTTPMETHOD_POST ) {        *rtype = RESP_POST;        err_code = UPNP_E_SUCCESS;        goto error_handler;    }    if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {        //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT        //Transfer-Encoding: chunked        // K means add chunky header ang G means range header.        if( http_MakeMessage( headers, resp_major, resp_minor, "RTGKDstcSCc", HTTP_PARTIAL_CONTENT, // status code                              // RespInstr->ReadSendSize,// content length                              finfo.content_type,                              //     content_type.buf,            // content type                              RespInstr,    // Range                              "LAST-MODIFIED: ",                              &finfo.last_modified ) != 0 ) {            goto error_handler;        }    } else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {        //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT        //Transfer-Encoding: chunked        // K means add chunky header ang G means range header.        if( http_MakeMessage( headers, resp_major, resp_minor, "RNTGDstcSCc", HTTP_PARTIAL_CONTENT, // status code                              RespInstr->ReadSendSize,  // content length                              finfo.content_type,                              //content_type.buf,            // content type                              RespInstr,    //Range Info                              "LAST-MODIFIED: ",                              &finfo.last_modified ) != 0 ) {            goto error_handler;        }    } else if( !RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {        //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT        //Transfer-Encoding: chunked        // K means add chunky header ang G means range header.        if( http_MakeMessage( headers, resp_major, resp_minor, "RKTDstcSCc", HTTP_OK,   // status code                              //RespInstr->ReadSendSize,// content length                              finfo.content_type,                              // content_type.buf,            // content type                              "LAST-MODIFIED: ",                              &finfo.last_modified ) != 0 ) {            goto error_handler;        }    } else {        if( RespInstr->ReadSendSize >= 0 ) {            //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT            //Transfer-Encoding: chunked            // K means add chunky header ang G means range header.            if( http_MakeMessage( headers, resp_major, resp_minor, "RNTDstcSCc", HTTP_OK,   // status code                                  RespInstr->ReadSendSize,  // content length                                  finfo.content_type,                                  //content_type.buf,          // content type                                  "LAST-MODIFIED: ",                                  &finfo.last_modified ) != 0 ) {                goto error_handler;            }        } else {            //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT            //Transfer-Encoding: chunked            // K means add chunky header ang G means range header.            if( http_MakeMessage( headers, resp_major, resp_minor, "RTDstcSCc", HTTP_OK,    // status code                                  //RespInstr->ReadSendSize,// content length                                  finfo.content_type,                                  //content_type.buf,          // content type                                  "LAST-MODIFIED: ",                                  &finfo.last_modified ) != 0 ) {                goto error_handler;            }        }    }    if( req->method == HTTPMETHOD_HEAD ) {        *rtype = RESP_HEADERS;    } else if( using_alias ) {        // GET xml        *rtype = RESP_XMLDOC;    } else if( using_virtual_dir ) {        *rtype = RESP_WEBDOC;    } else {        // GET filename        *rtype = RESP_FILEDOC;    }    //simple get http 0.9 as specified in http 1.0    //don't send headers    if( req->method == HTTPMETHOD_SIMPLEGET ) {        membuffer_destroy( headers );    }    err_code = UPNP_E_SUCCESS;  error_handler:    free( request_doc );    ixmlFreeDOMString( finfo.content_type );    //  membuffer_destroy( &content_type );    if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {        alias_release( alias );    }    return err_code;}/************************************************************************* Function: http_RecvPostMessage										*																		* Parameters:															*	http_parser_t* parser ; HTTP Parser object							*	IN SOCKINFO *info ; Socket Information object													*	char * filename ; 	File where received data is copied to*	struct SendInstruction * Instr	; Send Instruction object which gives*			information whether the file is a virtual file or not.*																		* Description: Receives the HTTP post message														*																		* Returns:																*	HTTP_INTERNAL_SERVER_ERROR											*	HTTP_UNAUTHORIZED													*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									*	HTTP_OK																************************************************************************/inthttp_RecvPostMessage( http_parser_t * parser,                      IN SOCKINFO * info,                      char *filename,                      struct SendInstruction *Instr ){    unsigned int Data_Buf_Size = 1024;    char Buf[1024];    int Timeout = 0;    long Num_Write = 0;    FILE *Fp;    parse_status_t status = PARSE_OK;    xboolean ok_on_close = FALSE;    unsigned int entity_offset = 0;    int num_read = 0;    int ret_code = 0;    if( Instr && Instr->IsVirtualFile ) {        Fp = virtualDirCallback.open( filename, UPNP_WRITE );        if( Fp == NULL ) {            return HTTP_INTERNAL_SERVER_ERROR;        }    } else {        Fp = fopen( filename, "wb" );        if( Fp == NULL ) {            return HTTP_UNAUTHORIZED;        }    }    parser->position = POS_ENTITY;    do {        //first parse what has already been gotten        if( parser->position != POS_COMPLETE ) {            status = parser_parse_entity( parser );        }        if( status == PARSE_INCOMPLETE_ENTITY ) {            // read until close            ok_on_close = TRUE;        } else if( ( status != PARSE_SUCCESS )                   && ( status != PARSE_CONTINUE_1 )                   && ( status != PARSE_INCOMPLETE ) ) {            //error            return HTTP_BAD_REQUEST;        }        //read more if necessary entity        while( ( ( entity_offset + Data_Buf_Size ) >                 parser->msg.entity.length )               && ( parser->position != POS_COMPLETE ) ) {            num_read = sock_read( info, Buf, sizeof( Buf ), &Timeout );            if( num_read > 0 ) {                // append data to buffer                ret_code = membuffer_append( &parser->msg.msg,                                             Buf, num_read );                if( ret_code != 0 ) {                    // set failure status                    parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;                    return HTTP_INTERNAL_SERVER_ERROR;                }                status = parser_parse_entity( parser );                if( status == PARSE_INCOMPLETE_ENTITY ) {                    // read until close                    ok_on_close = TRUE;                } else if( ( status != PARSE_SUCCESS )                           && ( status != PARSE_CONTINUE_1 )                           && ( status != PARSE_INCOMPLETE ) ) {                    return HTTP_BAD_REQUEST;                }            } else if( num_read == 0 ) {                if( ok_on_close ) {                    DBGONLY( UpnpPrintf                             ( UPNP_INFO, HTTP, __FILE__, __LINE__,                               "<<< (RECVD) <<<\n%s\n-----------------\n",                               parser->msg.msg.buf );                             //print_http_headers( &parser->msg );                         )                        parser->position = POS_COMPLETE;                } else {                    // partial msg                    parser->http_error_code = HTTP_BAD_REQUEST; // or response                    return HTTP_BAD_REQUEST;                }            } else {                return num_read;            }        }        if( ( entity_offset + Data_Buf_Size ) > parser->msg.entity.length ) {            Data_Buf_Size = parser->msg.entity.length - entity_offset;        }        memcpy( Buf, &parser->msg.msg.buf[parser->entity_start_position                                          + entity_offset],                Data_Buf_Size );        entity_offset += Data_Buf_Size;        if( Instr->IsVirtualFile ) {            Num_Write = virtualDirCallback.write( Fp, Buf, Data_Buf_Size );            if( Num_Write < 0 ) {                virtualDirCallback.close( Fp );                return HTTP_INTERNAL_SERVER_ERROR;            }        } else {            Num_Write = fwrite( Buf, 1, Data_Buf_Size, Fp );            if( Num_Write < 0 ) {                fclose( Fp );                return HTTP_INTERNAL_SERVER_ERROR;            }        }    } while( ( parser->position != POS_COMPLETE )             || ( entity_offset != parser->msg.entity.length ) );    if( Instr->IsVirtualFile ) {        virtualDirCallback.close( Fp );    } else {        fclose( Fp );    }    /*       while(TotalByteReceived < Instr->RecvWriteSize &&       (NumReceived = sock_read(info,Buf, Data_Buf_Size,&Timeout) ) > 0 )        {       TotalByteReceived = TotalByteReceived + NumReceived;       Num_Write = virtualDirCallback.write(Fp, Buf, NumReceived);       if (ferror(Fp))       {       virtualDirCallback.close(Fp);       return HTTP_INTERNAL_SERVER_ERROR;       }       }       if(TotalByteReceived < Instr->RecvWriteSize)       {       return HTTP_INTERNAL_SERVER_ERROR;       }       virtualDirCallback.close(Fp);       }     */    return HTTP_OK;}/************************************************************************* Function: web_server_callback											*																		* Parameters:															*	IN http_parser_t *parser ; HTTP Parser Object						*	INOUT http_message_t* req ; HTTP Message request										*	IN SOCKINFO *info ;			Socket information object													*																		* Description: main entry point into web server;						*	handles HTTP GET and HEAD requests									*																		* Returns:																*	void																************************************************************************/voidweb_server_callback( IN http_parser_t * parser,                     INOUT http_message_t * req,                     IN SOCKINFO * info ){    int ret;    int timeout = 0;    enum resp_type rtype;    membuffer headers;    membuffer filename;    struct xml_alias_t xmldoc;    struct SendInstruction RespInstr;    //Initialize instruction header.    RespInstr.IsVirtualFile = 0;    RespInstr.IsChunkActive = 0;    RespInstr.IsRangeActive = 0;    RespInstr.IsTrailers = 0;    // init    membuffer_init( &headers );    membuffer_init( &filename );    //Process request should create the different kind of header depending on the    //the type of request.    ret =        process_request( req, &rtype, &headers, &filename, &xmldoc,                         &RespInstr );    if( ret != UPNP_E_SUCCESS ) {        // send error code        http_SendStatusResponse( info, ret, req->major_version,                                 req->minor_version );    } else {        //        // send response        switch ( rtype ) {            case RESP_FILEDOC: // send file, I = further instruction to send data.                http_SendMessage( info, &timeout, "Ibf", &RespInstr,                                  headers.buf, headers.length,                                  filename.buf );                break;            case RESP_XMLDOC:  // send xmldoc , I = further instruction to send data.                http_SendMessage( info, &timeout, "Ibb", &RespInstr,                                  headers.buf, headers.length,                                  xmldoc.doc.buf, xmldoc.doc.length );                alias_release( &xmldoc );                break;            case RESP_WEBDOC:  //, I = further instruction to send data.                /*                   http_SendVirtualDirDoc( info, &timeout, "Ibf",&RespInstr,                   headers.buf, headers.length,                   filename.buf );                   */                http_SendMessage( info, &timeout, "Ibf", &RespInstr,                                  headers.buf, headers.length,                                  filename.buf );                break;            case RESP_HEADERS: // headers only                http_SendMessage( info, &timeout, "b",                                  headers.buf, headers.length );                break;            case RESP_POST:    // headers only                ret =                    http_RecvPostMessage( parser, info, filename.buf,                                          &RespInstr );                //Send response.                http_MakeMessage( &headers, 1, 1, "RTDSCc", ret,                                  "text/html" );                http_SendMessage( info, &timeout, "b", headers.buf,                                  headers.length );                break;            default:                assert( 0 );        }    }    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,                         "webserver: request processed...\n" );         )        membuffer_destroy( &headers );    membuffer_destroy( &filename );}

⌨️ 快捷键说明

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