httpreadwrite.c
来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 2,067 行 · 第 1/5 页
C
2,067 行
// Create chunk for the current buffer. if( Instr && Instr->IsChunkActive ) { // Copy CRLF at the end of the chunk memcpy( file_buf + num_read, "\r\n", 2 ); // Hex length for the chunk size. sprintf( Chunk_Header, "%x", num_read ); //itoa(num_read,Chunk_Header,16); strcat( Chunk_Header, "\r\n" ); // Copy the chunk size header memcpy( file_buf - strlen( Chunk_Header ), Chunk_Header, strlen( Chunk_Header ) ); // on the top of the buffer. //file_buf[num_read+strlen(Chunk_Header)] = NULL; //printf("Sending %s\n",file_buf-strlen(Chunk_Header)); num_written = sock_write( info, file_buf - strlen( Chunk_Header ), num_read + strlen( Chunk_Header ) + 2, TimeOut ); if( num_written != num_read + ( int )strlen( Chunk_Header ) + 2 ) { // Send error nothing we can do. goto Cleanup_File; } } else { // write data num_written = sock_write( info, file_buf, num_read, TimeOut ); UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, ">>> (SENT) >>>\n%.*s\n------------\n", ( int )num_written, file_buf ); // Send error nothing we can do if( num_written != num_read ) { goto Cleanup_File; } } } // whileCleanup_File: va_end( argp ); if( Instr && Instr->IsVirtualFile ) { virtualDirCallback.close( Fp ); } else { fclose( Fp ); } free( ChunkBuf ); return RetVal; } else if( c == 'b' ) { // memory buffer buf = va_arg(argp, char *); buf_length = va_arg(argp, size_t); if( buf_length > 0 ) { num_written = sock_write( info, buf, buf_length, TimeOut ); UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, ">>> (SENT) >>>\n" "%.*s\nbuf_length=%d, num_written=%d\n" "------------\n", (int)buf_length, buf, (int)buf_length, num_written ); if( (size_t)num_written != buf_length ) { goto end; } } } }end: va_end( argp ); free( ChunkBuf ); return 0;}/************************************************************************ * Function: http_RequestAndResponse * * Parameters: * IN uri_type* destination; Destination URI object which contains * remote IP address among other elements * IN const char* request; Request to be sent * IN size_t request_length; Length of the request * IN http_method_t req_method; HTTP Request method * IN int timeout_secs; time out value * OUT http_parser_t* response; Parser object to receive the repsonse * * Description: * Initiates socket, connects to the destination, sends a * request and waits for the response from the remote end * * Returns: * UPNP_E_SOCKET_ERROR * UPNP_E_SOCKET_CONNECT * Error Codes returned by http_SendMessage * Error Codes returned by http_RecvMessage ************************************************************************/inthttp_RequestAndResponse( IN uri_type * destination, IN const char *request, IN size_t request_length, IN http_method_t req_method, IN int timeout_secs, OUT http_parser_t * response ){ int tcp_connection; int ret_code; int http_error_code; SOCKINFO info; tcp_connection = socket( AF_INET, SOCK_STREAM, 0 ); if( tcp_connection == -1 ) { parser_response_init( response, req_method ); return UPNP_E_SOCKET_ERROR; } if( sock_init( &info, tcp_connection ) != UPNP_E_SUCCESS ) { sock_destroy( &info, SD_BOTH ); parser_response_init( response, req_method ); return UPNP_E_SOCKET_ERROR; } // connect ret_code = connect( info.socket, ( struct sockaddr * )&destination->hostport. IPv4address, sizeof( struct sockaddr_in ) ); if( ret_code == -1 ) { sock_destroy( &info, SD_BOTH ); parser_response_init( response, req_method ); return UPNP_E_SOCKET_CONNECT; } // send request ret_code = http_SendMessage( &info, &timeout_secs, "b", request, request_length ); if( ret_code != 0 ) { sock_destroy( &info, SD_BOTH ); parser_response_init( response, req_method ); return ret_code; } // recv response ret_code = http_RecvMessage( &info, response, req_method, &timeout_secs, &http_error_code ); sock_destroy( &info, SD_BOTH ); //should shutdown completely return ret_code;}/************************************************************************ * Function: http_Download * * Parameters: * IN const char* url_str; String as a URL * IN int timeout_secs; time out value * OUT char** document; buffer to store the document extracted * from the donloaded message. * OUT int* doc_length; length of the extracted document * OUT char* content_type; Type of content * * Description: * Download the document message and extract the document * from the message. * * Return: int * UPNP_E_SUCCESS * UPNP_E_INVALID_URL ************************************************************************/inthttp_Download( IN const char *url_str, IN int timeout_secs, OUT char **document, OUT int *doc_length, OUT char *content_type ){ int ret_code; uri_type url; char *msg_start; char *entity_start; char *hoststr; char *temp; http_parser_t response; size_t msg_length; size_t hostlen; memptr ctype; size_t copy_len; membuffer request; char *urlPath = alloca( strlen( url_str ) + 1 ); //ret_code = parse_uri( (char*)url_str, strlen(url_str), &url ); 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 ); ret_code = http_MakeMessage( &request, 1, 1, "Q" "s" "bcDCUc", HTTPMETHOD_GET, url.pathquery.buff, url.pathquery.size, "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 ); // get doc msg ret_code = http_RequestAndResponse( &url, request.buf, request.length, HTTPMETHOD_GET, timeout_secs, &response ); if( ret_code != 0 ) { httpmsg_destroy( &response.msg ); membuffer_destroy( &request ); return ret_code; } UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n" ); print_http_headers( &response.msg ); // optional content-type if( content_type ) { if( httpmsg_find_hdr( &response.msg, HDR_CONTENT_TYPE, &ctype ) == NULL ) { *content_type = '\0'; // no content-type } else { // safety copy_len = ctype.length < LINE_SIZE - 1 ? ctype.length : LINE_SIZE - 1; memcpy( content_type, ctype.buf, copy_len ); content_type[copy_len] = '\0'; } } // // extract doc from msg // if( ( *doc_length = ( int )response.msg.entity.length ) == 0 ) { // 0-length msg *document = NULL; } else if( response.msg.status_code == HTTP_OK ) { //LEAK_FIX_MK // copy entity entity_start = response.msg.entity.buf; // what we want msg_length = response.msg.msg.length; // save for posterity msg_start = membuffer_detach( &response.msg.msg ); // whole msg // move entity to the start; copy null-terminator too memmove( msg_start, entity_start, *doc_length + 1 ); // save mem for body only *document = realloc( msg_start, *doc_length + 1 ); //LEAK_FIX_MK // *document = Realloc( msg_start,msg_length, *doc_length + 1 );//LEAK_FIX_MK // shrink can't fail assert( ( int )msg_length > *doc_length ); assert( *document != NULL ); } if( response.msg.status_code == HTTP_OK ) { ret_code = 0; // success } else { // server sent error msg (not requested doc) ret_code = response.msg.status_code; } httpmsg_destroy( &response.msg ); membuffer_destroy( &request ); return ret_code;}typedef struct HTTPPOSTHANDLE { SOCKINFO sock_info; int contentLength;} http_post_handle_t;/************************************************************************ * Function: MakePostMessage * * 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. * int contentLength; length of content * const char *contentType; Type of content * * Description: * Makes the message for the HTTP POST message * * Returns: * UPNP_E_INVALID_URL * UPNP_E_INVALID_PARAM * UPNP_E_SUCCESS ************************************************************************/intMakePostMessage( const char *url_str, membuffer * request, uri_type * url, int contentLength, const char *contentType ){ int ret_code = 0; char *urlPath = alloca( strlen( url_str ) + 1 ); 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( contentLength >= 0 ) { ret_code = http_MakeMessage( request, 1, 1, "Q" "s" "bcDCU" "T" "Nc", HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size, "HOST: ", hoststr, hostlen, contentType, (off_t)contentLength ); } else if( contentLength == UPNP_USING_CHUNKED ) { ret_code = http_MakeMessage( request, 1, 1, "Q" "s" "bcDCU" "TKc", 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, "Q" "s" "bcDCU" "Tc", HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size, "HOST: ", hoststr, hostlen, contentType ); } else { ret_code = UPNP_E_INVALID_PARAM; } 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: http_WriteHttpPost * * Parameters: * IN void *Handle: Handle to the http post object * IN char *buf: Buffer to send to peer, if format used
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?