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 + -
显示快捷键?