📄 httpreadwrite.c
字号:
goto Cleanup_File; } // 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 ) { goto Cleanup_File; //Send error nothing we can do. } } else { // write data num_written = sock_write( info, file_buf, num_read, TimeOut ); DBGONLY( 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; } } } //While Cleanup_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 = ( char * )va_arg( argp, char * ); buf_length = ( size_t ) va_arg( argp, size_t ); if( buf_length > 0 ) { num_written = sock_write( info, buf, buf_length, TimeOut ); if( ( size_t ) num_written != buf_length ) goto end; DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, ">>> (SENT) >>>\n%.*s\n------------\n", ( int )buf_length, buf ); ) } } } 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;* ** Note :************************************************************************/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, *entity_start, *hoststr, *temp; http_parser_t response; size_t msg_length, 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 ); 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 ); ) // 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; } DBGONLY( UpnpPrintf ( UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n" ); ) DBGONLY( 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 ); 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 ); ) 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -