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

📄 httpreadwrite.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 5 页
字号:

        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 = '/';
    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                         "HOSTNAME : %s Length : %d\n", hoststr, hostlen );
         )

        if( contentLength >= 0 ) {
        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTNc",
                                     HTTPMETHOD_POST, url->pathquery.buff,
                                     url->pathquery.size, "HOST: ",
                                     hoststr, hostlen, contentType,
                                     contentLength );
    } else if( contentLength == UPNP_USING_CHUNKED ) {
        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTKc",
                                     HTTPMETHOD_POST, url->pathquery.buff,
                                     url->pathquery.size, "HOST: ",
                                     hoststr, hostlen, contentType );
    } else if( contentLength == UPNP_UNTIL_CLOSE ) {
        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTc",
                                     HTTPMETHOD_POST, url->pathquery.buff,
                                     url->pathquery.size, "HOST: ",
                                     hoststr, hostlen, contentType );
    } else {
        ret_code = UPNP_E_INVALID_PARAM;
    }

    if( ret_code != 0 ) {
        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                             "HTTP Makemessage failed\n" );
             )
            membuffer_destroy( request );
        return ret_code;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                         "HTTP Buffer:\n %s\n" "----------END--------\n",
                         request->buf );
         )

        return UPNP_E_SUCCESS;
}

/************************************************************************
*	Function :	http_WriteHttpPost
*
*	Parameters :
*		IN void *Handle :		Handle to the http post object
*		IN char *buf :			Buffer to send to peer, if format used
*								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.
*
*	Note :
************************************************************************/
int
http_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 ) ) {
        ( *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 );
            sprintf( tempbuf, "%x\r\n", ( *size ) );    //begin chunk
            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;
*
*	Note :
************************************************************************/
int
http_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 Paramter ;
*		UPNP_E_OUTOF_MEMORY ;
*		UPNP_E_SOCKET_ERROR ;
*		UPNP_E_SOCKET_CONNECT ;
*
*	Note :
************************************************************************/
int
http_OpenHttpPost( IN const char *url_str,
                   IN OUT void **Handle,
                   IN const char *contentType,
                   IN int contentLength,
                   IN int timeout )
{
    int ret_code;
    SOCKET 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 == UPNP_INVALID_SOCKET ) {
        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 == UPNP_SOCKETERROR ) {
#ifdef _WIN32
		DBGONLY(
			UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
			"connect error: %d\n", WSAGetLastError());
		)
#endif
		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;
} http_get_handle_t;

/************************************************************************
* Function: MakeGetMessage												
*																		
* Parameters:															
*	const char *url_str ;	String as a URL
*	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														
************************************************************************/
int
MakeGetMessage( const char *url_str,
                membuffer * request,
                uri_type * url )
{
    int ret_code;
    char *urlPath = alloca( strlen( url_str ) + 1 );
    int hostlen = 0;
    char *hoststr,
     *temp;

    DBGONLY( 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 = '/';
    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                         "HOSTNAME : %s Length : %d\n", hoststr, hostlen );
         )

        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUc",
                                     HTTPMETHOD_GET, url->pathquery.buff,
                                     url->pathquery.size, "HOST: ",
                                     hoststr, hostlen );

    if( ret_code != 0 ) {
        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                             "HTTP Makemessage failed\n" );
             )
            membuffer_destroy( request );
        return ret_code;
    }

    DBGONLY( 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 ;

⌨️ 快捷键说明

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