📄 httpreadwrite.c
字号:
* 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 :************************************************************************/inthttp_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 ); 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; 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** Note :************************************************************************/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 method * * Returns: * UPNP_E_INVALID_URL * Error Codes returned by http_MakeMessage * UPNP_E_SUCCESS ************************************************************************/intMakeGetMessageEx( const char *url_str, membuffer * request, uri_type * url, struct SendInstruction *pRangeSpecifier ){ int errCode = UPNP_E_SUCCESS; char *urlPath = NULL; int hostlen = 0; char *hoststr, *temp; do { DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "DOWNLOAD URL : %s\n", url_str ); ) if( ( errCode = http_FixStrUrl( ( char * )url_str, strlen( url_str ), url ) ) != UPNP_E_SUCCESS ) { break; } // make msg membuffer_init( request ); urlPath = alloca( strlen( url_str ) + 1 ); if( !urlPath ) { errCode = UPNP_E_OUTOF_MEMORY; break; } memset( urlPath, 0, strlen( url_str ) + 1 ); strcpy( urlPath, url_str ); hoststr = strstr( urlPath, "//" ); if( hoststr == NULL ) { errCode = UPNP_E_INVALID_URL; break; } hoststr += 2; temp = strchr( hoststr, '/' ); if( temp == NULL ) { errCode = UPNP_E_INVALID_URL; break; } *temp = '\0'; hostlen = strlen( hoststr );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -