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

📄 httpreadwrite.c

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

                    amount_to_be_read = amount_to_be_read - num_read;

                    if( Instr->ReadSendSize < 0 ) {
                        //read until close
                        amount_to_be_read = Data_Buf_Size;
                    }
                } else {
                    num_read = fread( file_buf, 1, Data_Buf_Size, Fp );
                }

                if( num_read == 0 ) // EOF so no more to send.
                {
                    if( Instr && Instr->IsChunkActive ) {
                        num_written = sock_write( info, "0\r\n\r\n",
                                                  strlen( "0\r\n\r\n" ),
                                                  TimeOut );
                    } else {
                        RetVal = UPNP_E_FILE_READ_ERROR;
                    }
                    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 );
		DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
				     ">>> num bytes sent = %d\n----------\n",
				     num_written);
		    )
                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							
************************************************************************/
int
http_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 )
{
    SOCKET tcp_connection;
    int ret_code;
    int http_error_code;
#ifdef _WIN32
    int retVal;
#endif
    SOCKINFO info;

    tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
    if( tcp_connection == UPNP_INVALID_SOCKET ) {
        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 == UPNP_SOCKETERROR ) {
#ifdef _WIN32
		retVal = WSAGetLastError();
		DBGONLY(
			UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
			"connect error: %d\n", retVal);
		)
#endif
		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 :
************************************************************************/
int
http_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														
************************************************************************/
int
MakePostMessage( 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 );
         )

⌨️ 快捷键说明

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