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