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 + -
显示快捷键?