httpreadwrite.c

来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 2,067 行 · 第 1/5 页

C
2,067
字号
    ( *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 ************************************************************************/inthttp_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: *	'B':	arg = int status_code  *		appends content-length, content-type and HTML body *		for given code *	'b':	arg1 = const char* buf; *		arg2 = size_t buf_length memory ptr *	'C':	(no args) appends a HTTP CONNECTION: close header  *			depending on major,minor version *	'c':	(no args) appends CRLF "\r\n" *	'D':	(no args) appends HTTP DATE: header *	'd':	arg = int number            // appends decimal number *	'G':	arg = range information     // add range header *	'h':	arg = off_t number          // appends off_t number *	'K':	(no args)                   // add chunky header *	'N':	arg1 = off_t content_length // content-length header *	'q':    arg1 = http_method_t        // request start line and HOST header *		arg2 = (uri_type *) *	'Q':	arg1 = http_method_t;       // start line of request *		arg2 = char* url;  *		arg3 = size_t url_length  *	'R':	arg = int status_code       // adds a response start line *	'S':	(no args) appends HTTP SERVER: header *	's':	arg = const char* C_string *	'T':	arg = char * content_type; format *		e.g: "text/html"; content-type header *	't':	arg = time_t * gmt_time     // appends time in RFC 1123 fmt *	'U':	(no args) appends HTTP USER-AGENT: header *      'X':    arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent * * Return: int *	0 - On Success *	UPNP_E_OUTOF_MEMORY *	UPNP_E_INVALID_URL ************************************************************************/inthttp_MakeMessage( INOUT membuffer * buf,                  IN int http_major_version,                  IN int http_minor_version,                  IN const char *fmt,                  ... ){    char c;    char *s = NULL;    size_t num;    off_t bignum;    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 );            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 * );            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, "%"PRIzu, num );            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {                goto error_handler;            }        }        else if( c == 'h' ) {            // off_t            bignum = ( off_t )va_arg( argp, off_t );            sprintf( tempbuf, "%"PRId64, (int64_t)bignum );            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            bignum = ( off_t )va_arg( argp, off_t );            assert( bignum >= 0 );            if (http_MakeMessage(                buf, http_major_version, http_minor_version,                "shc",                "CONTENT-LENGTH: ", bignum ) != 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 );            if (http_MakeMessage(                buf, http_major_version, http_minor_version,                "ss",                temp_str, tempbuf ) != 0 ) {                goto error_handler;            }        } else if( c == 'X' ) {            // C string            s = ( char * )va_arg( argp, char * );            assert( s );            if( membuffer_append_str( buf, "X-User-Agent: ") != 0 ) {                goto error_handler;            }            if( membuffer_append( buf, s, strlen( s ) ) != 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>" );            bignum = strlen( tempbuf );            if (http_MakeMessage(                    buf, http_major_version, http_minor_version,                    "NTcs",                    bignum, // 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 = ( size_t )va_arg( argp, size_t );   // 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;                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 request_minor_vers;	Request minor version *	OUT int* response_major_vers;	Response mojor version *	OUT int* response_minor_vers;	Response minor version * * Description: *	Calculate HTTP response versions based on the request versions. * * Return: void ************************************************************************/voidhttp_CalcResponseVersion( IN int request_major_vers,                          IN int request_minor_vers,                          OUT int *response_major_vers,                          OUT int *response_minor_vers ){    if( ( request_major_vers > 1 ) ||        ( request_major_vers == 1 && request_minor_vers >= 1 )         ) {        *response_major_vers = 1;        *response_minor_vers = 1;    } else {        *response_major_vers = request_major_vers;        *response_minor_vers = request_minor_vers;    }}/************************************************************************* Function: MakeGetMessageEx** 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.** Description:*	Makes the message for the HTTP GET metho

⌨️ 快捷键说明

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