httpreadwrite.c

来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 2,067 行 · 第 1/5 页

C
2,067
字号
 *				is not UPNP_USING_CHUNKED,  *	IN unsigned int *size:	Size of the data to be sent. *	IN int timeout:		time out value * * Description: *	Formats data if format used is UPNP_USING_CHUNKED. *	Writes data on the socket connected to the peer. * * Return: int *	UPNP_E_SUCCESS - On Success *	UPNP_E_INVALID_PARAM - Invalid Parameter *	-1 - On Socket Error. ************************************************************************/inthttp_WriteHttpPost( IN void *Handle,                    IN char *buf,                    IN unsigned int *size,                    IN int timeout ){    http_post_handle_t *handle = ( http_post_handle_t * ) Handle;    char *tempbuf = NULL;    int tempbufSize = 0;    int freeTempbuf = 0;    int numWritten = 0;    if( ( !handle ) || ( !size ) || ( ( ( *size ) > 0 ) && !buf )        || ( ( *size ) < 0 ) ) {        if(size) ( *size ) = 0;        return UPNP_E_INVALID_PARAM;    }    if( handle->contentLength == UPNP_USING_CHUNKED ) {        if( ( *size ) ) {            int tempSize = 0;            tempbuf = ( char * )malloc(                *size + CHUNK_HEADER_SIZE + CHUNK_TAIL_SIZE );            if ( tempbuf == NULL) {                return UPNP_E_OUTOF_MEMORY;            }	    // begin chunk            sprintf( tempbuf, "%x\r\n", ( *size ) );            tempSize = strlen( tempbuf );            memcpy( tempbuf + tempSize, buf, ( *size ) );            memcpy( tempbuf + tempSize + ( *size ), "\r\n", 2 );            // end of chunk            tempbufSize = tempSize + ( *size ) + 2;            freeTempbuf = 1;        }    } else {        tempbuf = buf;        tempbufSize = ( *size );    }    numWritten =        sock_write( &handle->sock_info, tempbuf, tempbufSize, &timeout );    //(*size) = sock_write(&handle->sock_info,tempbuf,tempbufSize,&timeout);    if( freeTempbuf ) {        free( tempbuf );    }    if( numWritten < 0 ) {        ( *size ) = 0;        return numWritten;    } else {        ( *size ) = numWritten;        return UPNP_E_SUCCESS;    }}/************************************************************************ * Function: http_CloseHttpPost * * Parameters: *	IN void *Handle;	Handle to the http post object *	IN OUT int *httpStatus;	HTTP status returned on receiving a *				response message *	IN int timeout;		time out value * * Description: *	Sends remaining data if using  UPNP_USING_CHUNKED  *	format. Receives any more messages. Destroys socket and any socket *	associated memory. Frees handle associated with the HTTP POST msg. * * Return: int *	UPNP_E_SUCCESS		- On Sucess *	UPNP_E_INVALID_PARAM	- Invalid Parameter ************************************************************************/inthttp_CloseHttpPost( IN void *Handle,                    IN OUT int *httpStatus,                    IN int timeout ){    int retc = 0;    http_parser_t response;    int http_error_code;    http_post_handle_t *handle = Handle;    if( ( !handle ) || ( !httpStatus ) ) {        return UPNP_E_INVALID_PARAM;    }    if( handle->contentLength == UPNP_USING_CHUNKED ) {        retc = sock_write( &handle->sock_info, "0\r\n\r\n", strlen( "0\r\n\r\n" ), &timeout );  //send last chunk    }    //read response    parser_response_init( &response, HTTPMETHOD_POST );    retc =        http_RecvMessage( &handle->sock_info, &response, HTTPMETHOD_POST,                          &timeout, &http_error_code );    ( *httpStatus ) = http_error_code;    sock_destroy( &handle->sock_info, SD_BOTH );    //should shutdown completely    httpmsg_destroy( &response.msg );    free( handle );    return retc;}/************************************************************************ * Function: http_OpenHttpPost * * Parameters: *	IN const char *url_str;		String as a URL	 *	IN OUT void **Handle;		Pointer to buffer to store HTTP *					post handle *	IN const char *contentType;	Type of content *	IN int contentLength;		length of content *	IN int timeout;			time out value * * Description: *	Makes the HTTP POST message, connects to the peer,  *	sends the HTTP POST request. Adds the post handle to buffer of  *	such handles * * Return : int; *	UPNP_E_SUCCESS		- On Sucess *	UPNP_E_INVALID_PARAM	- Invalid Parameter *	UPNP_E_OUTOF_MEMORY *	UPNP_E_SOCKET_ERROR *	UPNP_E_SOCKET_CONNECT ************************************************************************/inthttp_OpenHttpPost( IN const char *url_str,                   IN OUT void **Handle,                   IN const char *contentType,                   IN int contentLength,                   IN int timeout ){    int ret_code;    int tcp_connection;    membuffer request;    http_post_handle_t *handle = NULL;    uri_type url;    if( ( !url_str ) || ( !Handle ) || ( !contentType ) ) {        return UPNP_E_INVALID_PARAM;    }    ( *Handle ) = handle;    if( ( ret_code =          MakePostMessage( url_str, &request, &url, contentLength,                           contentType ) ) != UPNP_E_SUCCESS ) {        return ret_code;    }    handle =        ( http_post_handle_t * ) malloc( sizeof( http_post_handle_t ) );    if( handle == NULL ) {        return UPNP_E_OUTOF_MEMORY;    }    handle->contentLength = contentLength;    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 );    }  errorHandler:    membuffer_destroy( &request );    ( *Handle ) = handle;    return ret_code;}typedef struct HTTPGETHANDLE {    http_parser_t response;    SOCKINFO sock_info;    int entity_offset;    int cancel;} http_get_handle_t;/************************************************************************* Function: MakeGetMessage** Parameters:*	const char *url_str ;	String as a URL*	const char *proxy_str ;	String as a URL of proxy to use*	membuffer *request ;	Buffer containing the request*	uri_type *url ; 	URI object containing the scheme, path *				query token, etc.** Description:*	Makes the message for the HTTP GET method** Returns:*	UPNP_E_INVALID_URL* 	Error Codes returned by http_MakeMessage*	UPNP_E_SUCCESS************************************************************************/intMakeGetMessage( const char *url_str,                const char *proxy_str,                membuffer * request,                uri_type * url ){    int ret_code;    char *urlPath = alloca( strlen( url_str ) + 1 );    size_t querylen = 0;    const char *querystr;    size_t hostlen = 0;    char *hoststr,     *temp;    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "DOWNLOAD URL : %s\n", url_str );    ret_code =        http_FixStrUrl( ( char * )url_str, strlen( url_str ), url );    if( ret_code != UPNP_E_SUCCESS ) {        return ret_code;    }    // make msg    membuffer_init( request );    strcpy( urlPath, url_str );    hoststr = strstr( urlPath, "//" );    if( hoststr == NULL ) {        return UPNP_E_INVALID_URL;    }    hoststr += 2;    temp = strchr( hoststr, '/' );    if( temp == NULL ) {        return UPNP_E_INVALID_URL;    }    *temp = '\0';    hostlen = strlen( hoststr );    *temp = '/';    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen );    if( proxy_str ) {        querystr = url_str;        querylen = strlen( querystr );    } else {        querystr = url->pathquery.buff;        querylen = url->pathquery.size;    }    ret_code = http_MakeMessage(        request, 1, 1,        "Q" "s" "bcDCUc",        HTTPMETHOD_GET, querystr, querylen,        "HOST: ",        hoststr, hostlen );    if( ret_code != 0 ) {        UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,            "HTTP Makemessage failed\n" );        membuffer_destroy( request );        return ret_code;    }    UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,        "HTTP Buffer:\n %s\n" "----------END--------\n",        request->buf );    return UPNP_E_SUCCESS;}/************************************************************************ * Function: ReadResponseLineAndHeaders * * Parameters: *	IN SOCKINFO *info;		Socket information object *	IN OUT http_parser_t *parser;	HTTP Parser object *	IN OUT int *timeout_secs;	time out value *	IN OUT int *http_error_code;	HTTP errror code returned * * Description: *	Parses already exiting data. If not complete reads more  *	data on the connected socket. The read data is then parsed. The  *	same methid is carried out for headers. * * Return: int *	PARSE_OK - On Success *	PARSE_FAILURE - Failure to parse data correctly *	UPNP_E_BAD_HTTPMSG - Socker read() returns an error ************************************************************************/intReadResponseLineAndHeaders( IN SOCKINFO * info,                            IN OUT http_parser_t * parser,                            IN OUT int *timeout_secs,                            IN OUT int *http_error_code ){    parse_status_t status;    int num_read;    char buf[2 * 1024];    int done = 0;    int ret_code = 0;    //read response line    status = parser_parse_responseline( parser );    if( status == PARSE_OK ) {        done = 1;    } else if( status == PARSE_INCOMPLETE ) {        done = 0;    } else {        //error        return status;    }    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_responseline( parser );            if( status == PARSE_OK ) {                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;        }    }    done = 0;    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;    }    //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 ) ) {

⌨️ 快捷键说明

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