📄 httpreadwrite.c
字号:
if( ( status == PARSE_OK ) && ( parser->position == POS_ENTITY ) ) { done = 1; } else if( status == PARSE_INCOMPLETE ) { done = 0; } else { //error return status; } //read headers while( !done ) { num_read = sock_read( info, buf, sizeof( buf ), timeout_secs ); 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 PARSE_FAILURE; } status = parser_parse_headers( parser ); if( ( status == PARSE_OK ) && ( parser->position == POS_ENTITY ) ) { done = 1; } else if( status == PARSE_INCOMPLETE ) { done = 0; } else { //error return status; } } else if( num_read == 0 ) { // partial msg *http_error_code = HTTP_BAD_REQUEST; // or response return UPNP_E_BAD_HTTPMSG; } else { *http_error_code = parser->http_error_code; return num_read; } } return PARSE_OK;}/************************************************************************* Function : http_ReadHttpGet** Parameters :* IN void *Handle : Handle to the HTTP get object* IN OUT char *buf : Buffer to get the read and parsed data* IN OUT unsigned int *size : Size of tge buffer passed* IN int timeout : time out value** Description : Parses already existing data, then gets new data.* Parses and extracts information from the new data.** Return : int ;* UPNP_E_SUCCESS - On Sucess ;* UPNP_E_INVALID_PARAM - Invalid Parameter;* UPNP_E_BAD_RESPONSE ;* UPNP_E_BAD_HTTPMSG ;** Note :************************************************************************/inthttp_ReadHttpGet( IN void *Handle, IN OUT char *buf, IN OUT unsigned int *size, IN int timeout ){ http_get_handle_t *handle = Handle; parse_status_t status; int num_read; xboolean ok_on_close = FALSE; char tempbuf[2 * 1024]; int ret_code = 0; if( ( !handle ) || ( !size ) || ( ( ( *size ) > 0 ) && !buf ) || ( ( *size ) < 0 ) ) { ( *size ) = 0; return UPNP_E_INVALID_PARAM; } //first parse what has already been gotten if( handle->response.position != POS_COMPLETE ) { status = parser_parse_entity( &handle->response ); } else { status = PARSE_SUCCESS; } 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 ( *size ) = 0; return UPNP_E_BAD_RESPONSE; } //read more if necessary entity while( ( ( handle->entity_offset + ( *size ) ) > handle->response.msg.entity.length ) && ( handle->response.position != POS_COMPLETE ) ) { num_read = sock_read( &handle->sock_info, tempbuf, sizeof( tempbuf ), &timeout ); if( num_read > 0 ) { // append data to buffer ret_code = membuffer_append( &handle->response.msg.msg, tempbuf, num_read ); if( ret_code != 0 ) { // set failure status handle->response.http_error_code = HTTP_INTERNAL_SERVER_ERROR; ( *size ) = 0; return PARSE_FAILURE; } status = parser_parse_entity( &handle->response ); 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 ( *size ) = 0; return UPNP_E_BAD_RESPONSE; } } else if( num_read == 0 ) { if( ok_on_close ) { DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "<<< (RECVD) <<<\n%s\n-----------------\n", handle->response.msg.msg.buf ); //print_http_headers( &parser->msg ); ) handle->response.position = POS_COMPLETE; } else { // partial msg ( *size ) = 0; handle->response.http_error_code = HTTP_BAD_REQUEST; // or response return UPNP_E_BAD_HTTPMSG; } } else { ( *size ) = 0; return num_read; } } if( ( handle->entity_offset + ( *size ) ) > handle->response.msg.entity.length ) { ( *size ) = handle->response.msg.entity.length - handle->entity_offset; } memcpy( buf, &handle->response.msg.msg.buf[handle-> response.entity_start_position + handle->entity_offset], ( *size ) ); handle->entity_offset += ( *size ); return UPNP_E_SUCCESS;}/************************************************************************* Function : http_CloseHttpGet** Parameters :* IN void *Handle ; Handle to HTTP get object** Description : Clears the handle allocated for the HTTP GET operation* Clears socket states and memory allocated for socket operations. ** Return : int ;* UPNP_E_SUCCESS - On Success* UPNP_E_INVALID_PARAM - Invalid Parameter** Note :************************************************************************/inthttp_CloseHttpGet( IN void *Handle ){ http_get_handle_t *handle = Handle; if( !handle ) { return UPNP_E_INVALID_PARAM; } sock_destroy( &handle->sock_info, SD_BOTH ); //should shutdown completely httpmsg_destroy( &handle->response.msg ); handle->entity_offset = 0; free( handle ); return UPNP_E_SUCCESS;}/************************************************************************* Function : http_OpenHttpGet** Parameters :* IN const char *url_str : String as a URL* IN OUT void **Handle : Pointer to buffer to store HTTP* post handle* IN OUT char **contentType : Type of content* OUT int *contentLength : length of content* OUT int *httpStatus : HTTP status returned on receiving a* response message* IN int timeout : time out value** Description : Makes the HTTP GET message, connects to the peer, * sends the HTTP GET request, gets the response and parses the * response.** Return : int;* UPNP_E_SUCCESS - On Success ;* UPNP_E_INVALID_PARAM - Invalid Paramters ;* UPNP_E_OUTOF_MEMORY ;* UPNP_E_SOCKET_ERROR ;* UPNP_E_BAD_RESPONSE ;** Note :*************************************************************************/inthttp_OpenHttpGet( IN const char *url_str, IN OUT void **Handle, IN OUT char **contentType, OUT int *contentLength, OUT int *httpStatus, IN int timeout ){ int ret_code; int http_error_code; memptr ctype; int tcp_connection; membuffer request; http_get_handle_t *handle = NULL; uri_type url; parse_status_t status; if( ( !url_str ) || ( !Handle ) || ( !contentType ) || ( !httpStatus ) ) { return UPNP_E_INVALID_PARAM; } ( *httpStatus ) = 0; ( *Handle ) = handle; ( *contentType ) = NULL; ( *contentLength ) = 0; if( ( ret_code = MakeGetMessage( url_str, &request, &url ) ) != UPNP_E_SUCCESS ) { return ret_code; } handle = ( http_get_handle_t * ) malloc( sizeof( http_get_handle_t ) ); if( handle == NULL ) { return UPNP_E_OUTOF_MEMORY; } handle->entity_offset = 0; parser_response_init( &handle->response, HTTPMETHOD_GET ); tcp_connection = socket( AF_INET, SOCK_STREAM, 0 ); if( tcp_connection == -1 ) { ret_code = UPNP_E_SOCKET_ERROR; goto errorHandler; } if( sock_init( &handle->sock_info, tcp_connection ) != UPNP_E_SUCCESS ) { sock_destroy( &handle->sock_info, SD_BOTH ); ret_code = UPNP_E_SOCKET_ERROR; goto errorHandler; } ret_code = connect( handle->sock_info.socket, ( struct sockaddr * )&url.hostport.IPv4address, sizeof( struct sockaddr_in ) ); if( ret_code == -1 ) { sock_destroy( &handle->sock_info, SD_BOTH ); ret_code = UPNP_E_SOCKET_CONNECT; goto errorHandler; } // send request ret_code = http_SendMessage( &handle->sock_info, &timeout, "b", request.buf, request.length ); if( ret_code != 0 ) { sock_destroy( &handle->sock_info, SD_BOTH ); goto errorHandler; } status = ReadResponseLineAndHeaders( &handle->sock_info, &handle->response, &timeout, &http_error_code ); if( status != PARSE_OK ) { ret_code = UPNP_E_BAD_RESPONSE; goto errorHandler; } status = parser_get_entity_read_method( &handle->response ); if( ( status != PARSE_CONTINUE_1 ) && ( status != PARSE_SUCCESS ) ) { ret_code = UPNP_E_BAD_RESPONSE; goto errorHandler; } ( *httpStatus ) = handle->response.msg.status_code; ret_code = UPNP_E_SUCCESS; if( httpmsg_find_hdr( &handle->response.msg, HDR_CONTENT_TYPE, &ctype ) == NULL ) { *contentType = NULL; // no content-type } else { *contentType = ctype.buf; } if( handle->response.position == POS_COMPLETE ) { ( *contentLength ) = 0; } else if( handle->response.ent_position == ENTREAD_USING_CHUNKED ) { ( *contentLength ) = UPNP_USING_CHUNKED; } else if( handle->response.ent_position == ENTREAD_USING_CLEN ) { ( *contentLength ) = handle->response.content_length; } else if( handle->response.ent_position == ENTREAD_UNTIL_CLOSE ) { ( *contentLength ) = UPNP_UNTIL_CLOSE; } errorHandler: ( *Handle ) = handle; membuffer_destroy( &request ); if( ret_code != UPNP_E_SUCCESS ) { httpmsg_destroy( &handle->response.msg ); } return ret_code;}/************************************************************************* Function : http_SendStatusResponse** Parameters :* IN SOCKINFO *info : Socket information object* IN int http_status_code : error code returned while making * or sending the response message* IN int request_major_version : request major version* IN int request_minor_version : request minor version** Description : Generate a response message for the status query and* send the status response.** Return : int;* 0 -- success* UPNP_E_OUTOF_MEMORY* UPNP_E_SOCKET_WRITE* UPNP_E_TIMEDOUT** Note :************************************************************************/inthttp_SendStatusResponse( IN SOCKINFO * info, IN int http_status_code, IN int request_major_version, IN int request_minor_version ){ int response_major, response_minor; membuffer membuf; int ret; int timeout; http_CalcResponseVersion( request_major_version, request_minor_version, &response_major, &response_minor ); membuffer_init( &membuf ); membuf.size_inc = 70; ret = http_MakeMessage( &membuf, response_major, response_minor, "RSCB", http_status_code, // response start line http_status_code ); // body if( ret == 0 ) { timeout = HTTP_DEFAULT_TIMEOUT; ret = http_SendMessage( info, &timeout, "b", membuf.buf, membuf.length ); } membuffer_destroy( &membuf ); return ret;}/************************************************************************* Function : http_MakeMessage** Parameters :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -