httpreadwrite.c
来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 2,067 行 · 第 1/5 页
C
2,067 行
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 the 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 * UPNP_E_CANCELED ************************************************************************/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 ) ) { if(size) ( *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->cancel ) && ( 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 ) { UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "<<< (RECVD) <<<\n%s\n-----------------\n", handle->response.msg.msg.buf ); 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 ); if ( handle->cancel ) return UPNP_E_CANCELED; return UPNP_E_SUCCESS;}/************************************************************************ * Function: http_HttpGetProgress * * Parameters: * IN void *Handle; Handle to the HTTP get object * OUT unsigned int *length; Buffer to get the read and parsed data * OUT unsigned int *total; Size of tge buffer passed * * Description: * Extracts information from the Handle to the HTTP get object. * * Return: int * UPNP_E_SUCCESS - On Sucess * UPNP_E_INVALID_PARAM - Invalid Parameter ************************************************************************/int http_HttpGetProgress( IN void *Handle, OUT unsigned int *length, OUT unsigned int *total ){ http_get_handle_t *handle = Handle; if( ( !handle ) || ( !length ) || ( !total ) ) { return UPNP_E_INVALID_PARAM; } *length = handle->response.msg.entity.length; *total = handle->response.content_length; return UPNP_E_SUCCESS;}/************************************************************************ * Function: http_CancelHttpGet * * Parameters: * IN void *Handle; Handle to HTTP get object * * Description: * Set the cancel flag of the HttpGet handle * * Return: int * UPNP_E_SUCCESS - On Success * UPNP_E_INVALID_PARAM - Invalid Parameter ************************************************************************/inthttp_CancelHttpGet( IN void *Handle ){ http_get_handle_t *handle = Handle; if( !handle ) { return UPNP_E_INVALID_PARAM; } handle->cancel = 1; 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 ************************************************************************/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 ************************************************************************/inthttp_OpenHttpGet( IN const char *url_str, IN OUT void **Handle, IN OUT char **contentType, OUT int *contentLength, OUT int *httpStatus, IN int timeout ){ return http_OpenHttpGetProxy(url_str, NULL, Handle, contentType, contentLength, httpStatus, timeout);}/************************************************************************ * Function: http_OpenHttpGetProxy * * Parameters: * IN const char *url_str; String as a URL * IN const char *proxy_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. * If a proxy URL is defined then the connection is made there. * * 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 ************************************************************************/inthttp_OpenHttpGetProxy( IN const char *url_str, IN const char *proxy_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; uri_type proxy; uri_type *peer; 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, proxy_str, &request, &url ) ) != UPNP_E_SUCCESS ) { return ret_code; } if( proxy_str ) { ret_code = http_FixStrUrl( ( char * )proxy_str, strlen( proxy_str ), &proxy ); peer = &proxy; } else { peer = &url; } handle = ( http_get_handle_t * ) malloc( sizeof( http_get_handle_t ) ); if( handle == NULL ) { return UPNP_E_OUTOF_MEMORY; } handle->entity_offset = 0; handle->cancel = 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 * )&peer->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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?