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

📄 httpreadwrite.c

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

    if( handle->response.position == POS_COMPLETE ) {
        ( *contentLength ) = 0;
    } else if( handle->response.ent_position == ENTREAD_USING_CHUNKED ) {
        ( *contentLength ) = UPNP_USING_CHUNKED;
    } else if( handle->response.ent_position == ENTREAD_USING_CLEN ) {
        ( *contentLength ) = handle->response.content_length;
    } else if( handle->response.ent_position == ENTREAD_UNTIL_CLOSE ) {
        ( *contentLength ) = UPNP_UNTIL_CLOSE;
    }

  errorHandler:

    ( *Handle ) = handle;

    membuffer_destroy( &request );

    if( ret_code != UPNP_E_SUCCESS ) {
        httpmsg_destroy( &handle->response.msg );
    }
    return ret_code;
}

/************************************************************************
*	Function :	http_SendStatusResponse
*
*	Parameters :
*		IN SOCKINFO *info :				Socket information object
*		IN int http_status_code :		error code returned while making 
*										or sending the response message
*		IN int request_major_version :	request major version
*		IN int request_minor_version :	request minor version
*
*	Description :	Generate a response message for the status query and
*		send the status response.
*
*	Return : int;
*		0 -- success
*		UPNP_E_OUTOF_MEMORY
*		UPNP_E_SOCKET_WRITE
*		UPNP_E_TIMEDOUT
*
*	Note :
************************************************************************/
int
http_SendStatusResponse( IN SOCKINFO * info,
                         IN int http_status_code,
                         IN int request_major_version,
                         IN int request_minor_version )
{
    int response_major,
      response_minor;
    membuffer membuf;
    int ret;
    int timeout;

    http_CalcResponseVersion( request_major_version, request_minor_version,
                              &response_major, &response_minor );

    membuffer_init( &membuf );
    membuf.size_inc = 70;

    ret = http_MakeMessage( &membuf, response_major, response_minor, "RSCB", http_status_code,  // response start line
                            http_status_code ); // body
    if( ret == 0 ) {
        timeout = HTTP_DEFAULT_TIMEOUT;
        ret = http_SendMessage( info, &timeout, "b",
                                membuf.buf, membuf.length );
    }

    membuffer_destroy( &membuf );

    return ret;
}

/************************************************************************
*	Function :	http_MakeMessage
*
*	Parameters :
*		INOUT membuffer* buf :		buffer with the contents of the 
*									message
*		IN int http_major_version :	HTTP major version
*		IN int http_minor_version :	HTTP minor version
*		IN const char* fmt :		Pattern format 
*		... :	
*
*	Description :	Generate an HTTP message based on the format that is 
*		specified in the input parameters.
*
*		fmt types:
*		's':	arg = const char* C_string
*		'b':	arg1 = const char* buf; arg2 = size_t buf_length 
*				memory ptr
*		'c':	(no args) appends CRLF "\r\n"
*		'd':	arg = int number		// appends decimal number
*		't':	arg = time_t * gmt_time	// appends time in RFC 1123 fmt
*		'D':	(no args) appends HTTP DATE: header
*		'S':	(no args) appends HTTP SERVER: header
*		'U':	(no args) appends HTTP USER-AGENT: header
*		'C':	(no args) appends a HTTP CONNECTION: close header 
*				depending on major,minor version
*		'N':	arg1 = int content_length	// content-length header
*		'Q':	arg1 = http_method_t; arg2 = char* url; 
*				arg3 = int url_length // start line of request
*		'R':	arg = int status_code // adds a response start line
*		'B':	arg = int status_code 
*				appends content-length, content-type and HTML body for given code
*		'T':	arg = char * content_type; format e.g: "text/html";	
*				 content-type header
*
*	Return : int;
*		0 - On Success
*		UPNP_E_OUTOF_MEMORY
*		UPNP_E_INVALID_URL;
*
*	Note :
************************************************************************/
int
http_MakeMessage( INOUT membuffer * buf,
                  IN int http_major_version,
                  IN int http_minor_version,
                  IN const char *fmt,
                  ... )
{
    char c;
    char *s = NULL;
    int num;
    size_t length;
    time_t *loc_time;
    time_t curr_time;
    struct tm *date;
    char *start_str,
     *end_str;
    int status_code;
    const char *status_msg;
    http_method_t method;
    const char *method_str;
    const char *url_str;
    const char *temp_str;
    uri_type url;
    uri_type *uri_ptr;
    int error_code = UPNP_E_OUTOF_MEMORY;

    va_list argp;
    char tempbuf[200];
    const char *weekday_str = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat";
    const char *month_str = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0"
        "Jul\0Aug\0Sep\0Oct\0Nov\0Dec";

    va_start( argp, fmt );

    while( ( c = *fmt++ ) != 0 ) {

        if( c == 's' )          // C string
        {
            s = ( char * )va_arg( argp, char * );

            assert( s );

            //DBGONLY(UpnpPrintf(UPNP_ALL,HTTP,__FILE__,__LINE__,"Adding a string : %s\n", s);) 
            if( membuffer_append( buf, s, strlen( s ) ) != 0 ) {
                goto error_handler;
            }
        } else if( c == 'K' )   // Add Chunky header
        {
            if( membuffer_append
                ( buf, "TRANSFER-ENCODING: chunked\r\n",
                  strlen( "Transfer-Encoding: chunked\r\n" ) ) != 0 ) {
                goto error_handler;
            }
        } else if( c == 'G' )   // Add Range header
        {
            struct SendInstruction *RespInstr;
            RespInstr =
                ( struct SendInstruction * )va_arg( argp,
                                                    struct SendInstruction
                                                    * );
            assert( RespInstr );
            // connection header
            if( membuffer_append
                ( buf, RespInstr->RangeHeader,
                  strlen( RespInstr->RangeHeader ) ) != 0 ) {
                goto error_handler;
            }

        } else if( c == 'b' )   // mem buffer
        {
            s = ( char * )va_arg( argp, char * );

            //DBGONLY(UpnpPrintf(UPNP_ALL,HTTP,__FILE__,__LINE__,"Adding a char Buffer starting with: %c\n", s[0]);)
            assert( s );
            length = ( size_t ) va_arg( argp, size_t );
            if( membuffer_append( buf, s, length ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'c' )     // crlf
        {
            if( membuffer_append( buf, "\r\n", 2 ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'd' )     // integer
        {
            num = ( int )va_arg( argp, int );

            sprintf( tempbuf, "%d", num );
            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 't' || c == 'D' ) // date
        {
            if( c == 'D' ) {
                // header
                start_str = "DATE: ";
                end_str = "\r\n";
                curr_time = time( NULL );
                date = gmtime( &curr_time );
            } else {
                // date value only
                start_str = end_str = "";
                loc_time = ( time_t * ) va_arg( argp, time_t * );
                assert( loc_time );
                date = gmtime( loc_time );
            }

            sprintf( tempbuf, "%s%s, %02d %s %d %02d:%02d:%02d GMT%s",
                     start_str,
                     &weekday_str[date->tm_wday * 4], date->tm_mday,
                     &month_str[date->tm_mon * 4], date->tm_year + 1900,
                     date->tm_hour, date->tm_min, date->tm_sec, end_str );

            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'C' ) {
            if( ( http_major_version > 1 ) ||
                ( http_major_version == 1 && http_minor_version == 1 )
                 ) {
                // connection header
                if( membuffer_append_str( buf, "CONNECTION: close\r\n" ) !=
                    0 ) {
                    goto error_handler;
                }
            }
        }

        else if( c == 'N' ) {
            // content-length header
            num = ( int )va_arg( argp, int );

            assert( num >= 0 );
            if( http_MakeMessage
                ( buf, http_major_version, http_minor_version, "sdc",
                  "CONTENT-LENGTH: ", num ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'S' || c == 'U' ) {
            // SERVER or USER-AGENT header

            temp_str = ( c == 'S' ) ? "SERVER: " : "USER-AGENT: ";
            get_sdk_info( tempbuf, 200 );
            if( http_MakeMessage
                ( buf, http_major_version, http_minor_version, "ss",
                  temp_str, tempbuf ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'R' ) {
            // response start line
            //   e.g.: 'HTTP/1.1 200 OK'
            //

            // code
            status_code = ( int )va_arg( argp, int );

            assert( status_code > 0 );
            sprintf( tempbuf, "HTTP/%d.%d %d ",
                     http_major_version, http_minor_version, status_code );

            // str
            status_msg = http_get_code_text( status_code );
            if( http_MakeMessage
                ( buf, http_major_version, http_minor_version, "ssc",
                  tempbuf, status_msg ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'B' ) {
            // body of a simple reply
            // 

            status_code = ( int )va_arg( argp, int );

            sprintf( tempbuf, "%s%d %s%s",
                     "<html><body><h1>",
                     status_code, http_get_code_text( status_code ),
                     "</h1></body></html>" );
            num = strlen( tempbuf );

            if( http_MakeMessage( buf, http_major_version, http_minor_version, "NTcs", num, // content-length
                                  "text/html",  // content-type
                                  tempbuf ) != 0 )  // body
            {
                goto error_handler;
            }
        }

        else if( c == 'Q' ) {
            // request start line
            // GET /foo/bar.html HTTP/1.1\r\n
            //

            method = ( http_method_t ) va_arg( argp, http_method_t );
            method_str = method_to_str( method );
            url_str = ( const char * )va_arg( argp, const char * );
            num = ( int )va_arg( argp, int );   // length of url_str

            if( http_MakeMessage( buf, http_major_version, http_minor_version, "ssbsdsdc", method_str,  // method
                                  " ", url_str, num,    // url
                                  " HTTP/", http_major_version, ".",
                                  http_minor_version ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'q' ) {
            // request start line and HOST header

            method = ( http_method_t ) va_arg( argp, http_method_t );

            uri_ptr = ( uri_type * ) va_arg( argp, uri_type * );
            assert( uri_ptr );
            if( http_FixUrl( uri_ptr, &url ) != 0 ) {
                error_code = UPNP_E_INVALID_URL;
		printf("http_FixURL failed\n");
                goto error_handler;
            }

            if( http_MakeMessage
                ( buf, http_major_version, http_minor_version, "Q" "sbc",
                  method, url.pathquery.buff, url.pathquery.size, "HOST: ",
                  url.hostport.text.buff, url.hostport.text.size ) != 0 ) {
                goto error_handler;
            }
        }

        else if( c == 'T' ) {
            // content type header
            temp_str = ( const char * )va_arg( argp, const char * );    // type/subtype format

            if( http_MakeMessage
                ( buf, http_major_version, http_minor_version, "ssc",
                  "CONTENT-TYPE: ", temp_str ) != 0 ) {
                goto error_handler;
            }
        }

        else {
            assert( 0 );
        }
    }

    return 0;

  error_handler:
    va_end( argp );
    membuffer_destroy( buf );
    return error_code;
}

/************************************************************************
*	Function :	http_CalcResponseVersion
*
*	Parameters :
*		IN int request_major_vers :		Request major version
*		IN int 

⌨️ 快捷键说明

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