📄 httpreadwrite.c
字号:
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 + -