diff --git a/upnp/inc/upnp.h b/upnp/inc/upnp.h index 898e695..6053220 100644 --- a/upnp/inc/upnp.h +++ b/upnp/inc/upnp.h @@ -2293,7 +2293,7 @@ EXPORT_SPEC int UpnpWriteHttpPost( /*! [in] The buffer to be posted. */ char *buf, /*! [in] The size, in bytes of \b buf. */ - unsigned int *size, + size_t *size, /*! [in] A timeout value sent with the request during which a response is * expected from the server, failing which, an error is reported. If * value is negative, timeout is infinite. */ diff --git a/upnp/src/api/upnpapi.c b/upnp/src/api/upnpapi.c index f8f6fd9..e485b0b 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -2801,7 +2801,7 @@ int UpnpOpenHttpPost( int UpnpWriteHttpPost( void *handle, char *buf, - unsigned int *size, + size_t *size, int timeout) { return http_WriteHttpPost(handle, buf, size, timeout); @@ -2887,21 +2887,18 @@ int UpnpHttpGetProgress(void *Handle, size_t *length, size_t *total) int UpnpDownloadUrlItem(const char *url, char **outBuf, char *contentType) { - int ret_code; - int dummy; + int ret_code; + size_t dummy; - if( url == NULL || outBuf == NULL || contentType == NULL ) { - return UPNP_E_INVALID_PARAM; - } + if (url == NULL || outBuf == NULL || contentType == NULL) + return UPNP_E_INVALID_PARAM; + ret_code = http_Download(url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy, + contentType); + if (ret_code > 0) + /* error reply was received */ + ret_code = UPNP_E_INVALID_URL; - ret_code = http_Download( url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy, - contentType ); - if( ret_code > 0 ) { - /* error reply was received */ - ret_code = UPNP_E_INVALID_URL; - } - - return ret_code; + return ret_code; } diff --git a/upnp/src/genlib/miniserver/miniserver.c b/upnp/src/genlib/miniserver/miniserver.c index 423ae31..c19eeb2 100644 --- a/upnp/src/genlib/miniserver/miniserver.c +++ b/upnp/src/genlib/miniserver/miniserver.c @@ -483,7 +483,7 @@ static int get_port( *port = ntohs(((struct sockaddr_in6*)&sockinfo)->sin6_port); } UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__, - "sockfd = %d, .... port = %d\n", sockfd, port); + "sockfd = %d, .... port = %u\n", sockfd, *port); return 0; } diff --git a/upnp/src/genlib/net/http/httpparser.c b/upnp/src/genlib/net/http/httpparser.c index fb7da4d..d2d7ec6 100644 --- a/upnp/src/genlib/net/http/httpparser.c +++ b/upnp/src/genlib/net/http/httpparser.c @@ -139,11 +139,8 @@ static UPNP_INLINE void scanner_init(OUT scanner_t *scanner, IN membuffer *bufpt * * Description : Finds the separator character. * -* Return : xboolean ; -* -* Note : ************************************************************************/ -static UPNP_INLINE xboolean is_separator_char(IN char c) +static UPNP_INLINE int is_separator_char(IN char c) { return strchr(" \t()<>@,;:\\\"/[]?={}", c) != NULL; } @@ -156,11 +153,8 @@ static UPNP_INLINE xboolean is_separator_char(IN char c) * * Description : Calls the function to indentify separator character * -* Return : xboolean ; -* -* Note : ************************************************************************/ -static UPNP_INLINE xboolean is_identifier_char(IN char c) +static UPNP_INLINE int is_identifier_char(IN char c) { return c >= 32 && c <= 126 && !is_separator_char(c); } @@ -173,11 +167,8 @@ static UPNP_INLINE xboolean is_identifier_char(IN char c) * * Description : Determines if the passed value is a control character * -* Return : xboolean ; -* -* Note : ************************************************************************/ -static UPNP_INLINE xboolean is_control_char(IN char c) +static UPNP_INLINE int is_control_char(IN char c) { return (c >= 0 && c <= 31) || c == 127; } @@ -190,11 +181,8 @@ static UPNP_INLINE xboolean is_control_char(IN char c) * * Description : Checks to see if the passed in value is CR/LF * -* Return : xboolean ; -* -* Note : ************************************************************************/ -static UPNP_INLINE xboolean is_qdtext_char(IN char cc) +static UPNP_INLINE int is_qdtext_char(IN char cc) { unsigned char c = ( unsigned char )cc; @@ -233,131 +221,110 @@ static parse_status_t scanner_get_token( OUT memptr *token, OUT token_type_t *tok_type) { - char *cursor; - char *null_terminator; /* point to null-terminator in buffer */ - char c; - token_type_t token_type; - xboolean got_end_quote; + char *cursor; + char *null_terminator; /* point to null-terminator in buffer */ + char c; + token_type_t token_type; + int got_end_quote; - assert( scanner ); - assert( token ); - assert( tok_type ); + assert(scanner); + assert(token); + assert(tok_type); - /* point to next char in buffer */ - cursor = scanner->msg->buf + scanner->cursor; - null_terminator = scanner->msg->buf + scanner->msg->length; + /* point to next char in buffer */ + cursor = scanner->msg->buf + scanner->cursor; + null_terminator = scanner->msg->buf + scanner->msg->length; + /* not enough chars in input to parse */ + if (cursor == null_terminator) + return PARSE_INCOMPLETE; + c = *cursor; + if (is_identifier_char(c)) { + /* scan identifier */ + token->buf = cursor++; + token_type = TT_IDENTIFIER; + while (is_identifier_char(*cursor)) + cursor++; + if (!scanner->entire_msg_loaded && cursor == null_terminator) + /* possibly more valid chars */ + return PARSE_INCOMPLETE; + /* calc token length */ + token->length = (size_t)(cursor - token->buf); + } else if (c == ' ' || c == '\t') { + token->buf = cursor++; + token_type = TT_WHITESPACE; + while (*cursor == ' ' || *cursor == '\t') + cursor++; + if (!scanner->entire_msg_loaded && cursor == null_terminator) + /* possibly more chars */ + return PARSE_INCOMPLETE; + token->length = (size_t)(cursor - token->buf); + } else if (c == TOKCHAR_CR) { + /* scan CRLF */ + token->buf = cursor++; + if (cursor == null_terminator) + /* not enuf info to determine CRLF */ + return PARSE_INCOMPLETE; + if (*cursor != TOKCHAR_LF) { + /* couldn't match CRLF; match as CR */ + token_type = TT_CTRL; /* ctrl char */ + token->length = 1; + } else { + /* got CRLF */ + token->length = 2; + token_type = TT_CRLF; + cursor++; + } + } else if (c == TOKCHAR_LF) { /* accept \n as CRLF */ + token->buf = cursor++; + token->length = 1; + token_type = TT_CRLF; + } else if (c == '"') { + /* quoted text */ + token->buf = cursor++; + token_type = TT_QUOTEDSTRING; + got_end_quote = FALSE; + while (cursor < null_terminator) { + c = *cursor++; + if (c == '"') { + got_end_quote = TRUE; + break; + } else if (c == '\\') { + if (cursor < null_terminator) { + c = *cursor++; + /*if ( !(c > 0 && c <= 127) ) */ + if (c == 0) + return PARSE_FAILURE; + } + /* else, while loop handles incomplete buf */ + } else if (is_qdtext_char(c)) { + /* just accept char */ + } else + /* bad quoted text */ + return PARSE_FAILURE; + } + if (got_end_quote) + token->length = (size_t)(cursor - token->buf); + else { /* incomplete */ - /* not enough chars in input to parse */ - if( cursor == null_terminator ) { - return PARSE_INCOMPLETE; - } + assert(cursor == null_terminator); + return PARSE_INCOMPLETE; + } + } else if (is_separator_char(c)) { + /* scan separator */ + token->buf = cursor++; + token_type = TT_SEPARATOR; + token->length = 1; + } else if (is_control_char(c)) { + /* scan ctrl char */ + token->buf = cursor++; + token_type = TT_CTRL; + token->length = 1; + } else + return PARSE_FAILURE; - c = *cursor; - if( is_identifier_char( c ) ) { - /* scan identifier */ - - token->buf = cursor++; - token_type = TT_IDENTIFIER; - - while( is_identifier_char( *cursor ) ) { - cursor++; - } - - if( !scanner->entire_msg_loaded && cursor == null_terminator ) { - /* possibly more valid chars */ - return PARSE_INCOMPLETE; - } - /* calc token length */ - token->length = cursor - token->buf; - } else if( c == ' ' || c == '\t' ) { - token->buf = cursor++; - token_type = TT_WHITESPACE; - - while( *cursor == ' ' || *cursor == '\t' ) { - cursor++; - } - - if( !scanner->entire_msg_loaded && cursor == null_terminator ) { - /* possibly more chars */ - return PARSE_INCOMPLETE; - } - token->length = cursor - token->buf; - } else if( c == TOKCHAR_CR ) { - /* scan CRLF */ - - token->buf = cursor++; - if( cursor == null_terminator ) { - /* not enuf info to determine CRLF */ - return PARSE_INCOMPLETE; - } - if( *cursor != TOKCHAR_LF ) { - /* couldn't match CRLF; match as CR */ - token_type = TT_CTRL; /* ctrl char */ - token->length = 1; - } else { - /* got CRLF */ - token->length = 2; - token_type = TT_CRLF; - cursor++; - } - } else if( c == TOKCHAR_LF ) /* accept \n as CRLF */ - { - token->buf = cursor++; - token->length = 1; - token_type = TT_CRLF; - } else if( c == '"' ) { - /* quoted text */ - token->buf = cursor++; - token_type = TT_QUOTEDSTRING; - got_end_quote = FALSE; - - while( cursor < null_terminator ) { - c = *cursor++; - if( c == '"' ) { - got_end_quote = TRUE; - break; - } else if( c == '\\' ) { - if( cursor < null_terminator ) { - c = *cursor++; - /*if ( !(c > 0 && c <= 127) ) */ - if( c == 0 ) { - return PARSE_FAILURE; - } - } - /* else, while loop handles incomplete buf */ - } else if( is_qdtext_char( c ) ) { - /* just accept char */ - } else { - /* bad quoted text */ - return PARSE_FAILURE; - } - } - if( got_end_quote ) { - token->length = cursor - token->buf; - } else /* incomplete */ - { - assert( cursor == null_terminator ); - return PARSE_INCOMPLETE; - } - } else if( is_separator_char( c ) ) { - /* scan separator */ - - token->buf = cursor++; - token_type = TT_SEPARATOR; - token->length = 1; - } else if( is_control_char( c ) ) { - /* scan ctrl char */ - - token->buf = cursor++; - token_type = TT_CTRL; - token->length = 1; - } else { - return PARSE_FAILURE; - } - - scanner->cursor += token->length; /* move to next token */ - *tok_type = token_type; - return PARSE_OK; + scanner->cursor += token->length; /* move to next token */ + *tok_type = token_type; + return PARSE_OK; } /************************************************************************ @@ -596,7 +563,7 @@ static UPNP_INLINE int skip_lws(INOUT scanner_t *scanner) token_type_t tok_type; parse_status_t status; size_t save_pos; - xboolean matched; + int matched; do { save_pos = scanner->cursor; @@ -651,7 +618,7 @@ static UPNP_INLINE parse_status_t match_non_ws_string( memptr token; token_type_t tok_type; parse_status_t status; - xboolean done = FALSE; + int done = FALSE; size_t save_cursor; save_cursor = scanner->cursor; @@ -717,8 +684,8 @@ static UPNP_INLINE parse_status_t match_raw_value( memptr token; token_type_t tok_type; parse_status_t status; - xboolean done = FALSE; - xboolean saw_crlf = FALSE; + int done = FALSE; + int saw_crlf = FALSE; size_t pos_at_crlf = 0; size_t save_pos; char c; @@ -806,42 +773,37 @@ static UPNP_INLINE int match_int( IN int base, OUT int *value) { - memptr token; - token_type_t tok_type; - parse_status_t status; - long num; - char *end_ptr; - size_t save_pos; + memptr token; + token_type_t tok_type; + parse_status_t status; + long num; + char *end_ptr; + size_t save_pos; - save_pos = scanner->cursor; + save_pos = scanner->cursor; + status = scanner_get_token(scanner, &token, &tok_type); + if (status == PARSE_OK) { + if (tok_type == TT_IDENTIFIER) { + errno = 0; + num = strtol(token.buf, &end_ptr, base); + /* all and only those chars in token should be used for num */ + if (num < 0 || end_ptr != token.buf + token.length || + ((num == LONG_MIN || num == LONG_MAX) && (errno == ERANGE))) { + status = PARSE_NO_MATCH; + } + /* save result */ + *value = (int)num; + } else { + /* token must be an identifier */ + status = PARSE_NO_MATCH; + } + } + if (status != PARSE_OK) { + /* restore scanner position for bad values */ + scanner->cursor = save_pos; + } - status = scanner_get_token( scanner, &token, &tok_type ); - if( status == PARSE_OK ) { - if( tok_type == TT_IDENTIFIER ) { - errno = 0; - - num = strtol( token.buf, &end_ptr, base ); - if( ( num < 0 ) - /* all and only those chars in token should be used for num */ - || ( end_ptr != token.buf + token.length ) - || ( ( num == LONG_MIN || num == LONG_MAX ) - && ( errno == ERANGE ) ) - ) { - status = PARSE_NO_MATCH; - } - - *value = num; /* save result */ - } else { - status = PARSE_NO_MATCH; /* token must be an identifier */ - } - } - - if( status != PARSE_OK ) { - /* restore scanner position for bad values */ - scanner->cursor = save_pos; - } - - return status; + return status; } /************************************************************************ @@ -894,7 +856,7 @@ read_until_crlf( INOUT scanner_t * scanner, * Parameters: * INOUT scanner_t* scanner ; Scanner Object * IN char c ; Character to be compared with -* IN xboolean case_sensitive; Flag indicating whether +* IN int case_sensitive; Flag indicating whether * comparison should be case sensitive * * Description: Compares a character to the next char in the scanner; @@ -908,7 +870,7 @@ read_until_crlf( INOUT scanner_t * scanner, static UPNP_INLINE parse_status_t match_char( INOUT scanner_t * scanner, IN char c, - IN xboolean case_sensitive ) + IN int case_sensitive ) { char scan_char; @@ -982,10 +944,10 @@ match_char( INOUT scanner_t * scanner, * * Note : ************************************************************************/ -static int -vfmatch( INOUT scanner_t * scanner, - IN const char *fmt, - va_list argp ) +static int vfmatch( + INOUT scanner_t *scanner, + IN const char *fmt, + va_list argp) { char c; const char *fmt_ptr = fmt; @@ -996,7 +958,7 @@ vfmatch( INOUT scanner_t * scanner, uri_type *uri_ptr; size_t save_pos; int stat; - xboolean case_sensitive = TRUE; + int case_sensitive = TRUE; memptr token; token_type_t tok_type; int base; @@ -1012,15 +974,12 @@ vfmatch( INOUT scanner_t * scanner, ) { if( c == '%' ) { c = *fmt_ptr++; - switch ( c ) { - case 'R': /* raw value */ str_ptr = va_arg( argp, memptr * ); assert( str_ptr != NULL ); status = match_raw_value( scanner, str_ptr ); break; - case 's': /* simple identifier */ str_ptr = va_arg( argp, memptr * ); assert( str_ptr != NULL ); @@ -1031,7 +990,6 @@ vfmatch( INOUT scanner_t * scanner, status = PARSE_NO_MATCH; } break; - case 'c': /* crlf */ status = scanner_get_token( scanner, &token, &tok_type ); @@ -1040,16 +998,13 @@ vfmatch( INOUT scanner_t * scanner, status = PARSE_NO_MATCH; } break; - case 'd': /* integer */ case 'x': /* hex number */ - int_ptr = va_arg( argp, int * ); - - assert( int_ptr != NULL ); - base = ( c == 'd' ? 10 : 16 ); - status = match_int( scanner, base, int_ptr ); + int_ptr = va_arg(argp, int *); + assert(int_ptr != NULL); + base = c == 'd' ? 10 : 16; + status = match_int(scanner, base, int_ptr); break; - case 'S': /* non-whitespace string */ case 'U': /* uri */ if( c == 'S' ) { @@ -1069,26 +1024,21 @@ vfmatch( INOUT scanner_t * scanner, } } break; - case 'L': /* string till eol */ str_ptr = va_arg( argp, memptr * ); assert( str_ptr != NULL ); status = read_until_crlf( scanner, str_ptr ); break; - case ' ': /* match space */ case '%': /* match percentage symbol */ status = match_char( scanner, c, case_sensitive ); break; - case 'n': /* case-sensitive match */ case_sensitive = TRUE; break; - case 'i': /* ignore case */ case_sensitive = FALSE; break; - case 'q': /* quoted string */ str_ptr = ( memptr * ) va_arg( argp, memptr * ); status = @@ -1097,8 +1047,8 @@ vfmatch( INOUT scanner_t * scanner, status = PARSE_NO_MATCH; /* not a quoted string */ } break; - - case 'w': /* optional whitespace */ + case 'w': + /* optional whitespace */ status = scanner_get_token( scanner, &token, &tok_type ); if( status == PARSE_OK && tok_type != TT_WHITESPACE ) { @@ -1106,16 +1056,15 @@ vfmatch( INOUT scanner_t * scanner, scanner->cursor -= token.length; } break; - - case 'P': /* current pos of scanner */ + case 'P': + /* current pos of scanner */ int_ptr = va_arg( argp, int * ); - assert( int_ptr != NULL ); - *int_ptr = scanner->cursor; + *int_ptr = (int)scanner->cursor; break; - /* valid only in matchstr() */ - case '0': /* end of msg? */ + case '0': + /* end of msg? */ /* check that we are 1 beyond last char */ if( scanner->cursor == scanner->msg->length && scanner->msg->buf[scanner->cursor] == '\0' ) { @@ -1124,16 +1073,15 @@ vfmatch( INOUT scanner_t * scanner, status = PARSE_NO_MATCH; } break; - default: - assert( 0 ); /* unknown option */ + /* unknown option */ + assert( 0 ); } } else { switch ( c ) { case ' ': /* LWS* */ status = skip_lws( scanner ); break; - case '\t': /* Whitespace */ status = scanner_get_token( scanner, &token, &tok_type ); @@ -1142,7 +1090,6 @@ vfmatch( INOUT scanner_t * scanner, status = PARSE_NO_MATCH; } break; - default: /* match characters */ { status = match_char( scanner, c, case_sensitive ); @@ -1150,7 +1097,6 @@ vfmatch( INOUT scanner_t * scanner, } } } - if( status != PARSE_OK ) { /* on error, restore original scanner pos */ scanner->cursor = save_pos; @@ -1175,19 +1121,19 @@ vfmatch( INOUT scanner_t * scanner, * PARSE_NO_MATCH * PARSE_INCOMPLETE ************************************************************************/ -static int -match( INOUT scanner_t * scanner, - IN const char *fmt, - ... ) +static int match( + INOUT scanner_t *scanner, + IN const char *fmt, + ...) { - int ret_code; - va_list args; + int ret_code; + va_list args; - va_start( args, fmt ); - ret_code = vfmatch( scanner, fmt, args ); - va_end( args ); + va_start(args, fmt); + ret_code = vfmatch(scanner, fmt, args); + va_end(args); - return ret_code; + return ret_code; } /************************************************************************ @@ -1397,90 +1343,69 @@ parser_parse_requestline( INOUT http_parser_t * parser ) * PARSE_SUCCESS * PARSE_FAILURE ************************************************************************/ -parse_status_t -parser_parse_responseline( INOUT http_parser_t * parser ) +parse_status_t parser_parse_responseline(INOUT http_parser_t *parser) { - parse_status_t status; - http_message_t *hmsg = &parser->msg; - memptr line; - char save_char; - int num_scanned; - int i; - char *p; + parse_status_t status; + http_message_t *hmsg = &parser->msg; + memptr line; + char save_char; + int num_scanned; + int i; + size_t n; + char *p; - assert( parser->position == POS_RESPONSE_LINE ); + assert(parser->position == POS_RESPONSE_LINE); - status = skip_blank_lines( &parser->scanner ); - if( status != PARSE_OK ) { - return status; - } - /* response line */ - /*status = match( &parser->scanner, "%ihttp%w/%w%d\t.\t%d\t%d\t%L%c", */ - /* &hmsg->major_version, &hmsg->minor_version, */ - /* &hmsg->status_code, &hmsg->status_msg ); */ + status = skip_blank_lines(&parser->scanner); + if (status != PARSE_OK) + return status; + /* response line */ + /*status = match( &parser->scanner, "%ihttp%w/%w%d\t.\t%d\t%d\t%L%c", */ + /* &hmsg->major_version, &hmsg->minor_version, */ + /* &hmsg->status_code, &hmsg->status_msg ); */ + status = match(&parser->scanner, "%ihttp%w/%w%L%c", &line); + if (status != PARSE_OK) + return status; + save_char = line.buf[line.length]; + line.buf[line.length] = '\0'; /* null-terminate */ + /* scan http version and ret code */ + num_scanned = sscanf(line.buf, "%d . %d %d", + &hmsg->major_version, &hmsg->minor_version, + &hmsg->status_code); + line.buf[line.length] = save_char; /* restore */ + if (num_scanned != 3 || hmsg->major_version < 0 || + /* HTTP version equals to 1.0 should fail as required by the + * UPnP certification tool */ + hmsg->minor_version < 1 || hmsg->status_code < 0) + /* bad response line */ + return PARSE_FAILURE; + /* point to status msg */ + p = line.buf; + /* skip 3 ints */ + for (i = 0; i < 3; i++) { + /* go to start of num */ + while (!isdigit(*p)) + p++; + /* skip int */ + while (isdigit(*p)) + p++; + } + /* whitespace must exist after status code */ + if (*p != ' ' && *p != '\t') + return PARSE_FAILURE; + /* skip whitespace */ + while (*p == ' ' || *p == '\t') + p++; + /* now, p is at start of status msg */ + n = line.length - (size_t)(p - line.buf); + if (membuffer_assign(&hmsg->status_msg, p, n) != 0) { + /* out of mem */ + parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + parser->position = POS_HEADERS; /* move to headers */ - status = match( &parser->scanner, "%ihttp%w/%w%L%c", &line ); - if( status != PARSE_OK ) { - return status; - } - - save_char = line.buf[line.length]; - line.buf[line.length] = '\0'; /* null-terminate */ - - /* scan http version and ret code */ - num_scanned = sscanf( line.buf, "%d . %d %d", - &hmsg->major_version, &hmsg->minor_version, - &hmsg->status_code ); - - line.buf[line.length] = save_char; /* restore */ - - if( num_scanned != 3 || - hmsg->major_version < 0 || - /* HTTP version equals to 1.0 should fail as required by the - * UPnP certification tool */ - hmsg->minor_version < 1 || hmsg->status_code < 0 ) { - /* bad response line */ - return PARSE_FAILURE; - } - /* */ - /* point to status msg */ - /* */ - - p = line.buf; - - /* skip 3 ints */ - for( i = 0; i < 3; i++ ) { - /* go to start of num */ - while( !isdigit( *p ) ) { - p++; - } - - /* skip int */ - while( isdigit( *p ) ) { - p++; - } - } - - /* whitespace must exist after status code */ - if( *p != ' ' && *p != '\t' ) { - return PARSE_FAILURE; - } - /* skip whitespace */ - while( *p == ' ' || *p == '\t' ) { - p++; - } - - /* now, p is at start of status msg */ - if( membuffer_assign( &hmsg->status_msg, p, - line.length - ( p - line.buf ) ) != 0 ) { - /* out of mem */ - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - - parser->position = POS_HEADERS; /* move to headers */ - - return PARSE_OK; + return PARSE_OK; } /************************************************************************ @@ -1496,152 +1421,128 @@ parser_parse_responseline( INOUT http_parser_t * parser ) * PARSE_SUCCESS * PARSE_FAILURE ************************************************************************/ -parse_status_t -parser_parse_headers( INOUT http_parser_t * parser ) +parse_status_t parser_parse_headers(INOUT http_parser_t *parser) { - parse_status_t status; - memptr token; - memptr hdr_value; - token_type_t tok_type; - scanner_t *scanner = &parser->scanner; - size_t save_pos; - http_header_t *header; - int header_id; - int ret = 0; - int index; - http_header_t *orig_header; - char save_char; - int ret2; + parse_status_t status; + memptr token; + memptr hdr_value; + token_type_t tok_type; + scanner_t *scanner = &parser->scanner; + size_t save_pos; + http_header_t *header; + int header_id; + int ret = 0; + int index; + http_header_t *orig_header; + char save_char; + int ret2; - assert( parser->position == POS_HEADERS || - parser->ent_position == ENTREAD_CHUNKY_HEADERS ); + assert(parser->position == POS_HEADERS || + parser->ent_position == ENTREAD_CHUNKY_HEADERS); - while( TRUE ) { - save_pos = scanner->cursor; - - /* */ - /* check end of headers */ - /* */ - status = scanner_get_token( scanner, &token, &tok_type ); - if( status != PARSE_OK ) { - return status; - } - - if( tok_type == TT_CRLF ) { - - /* end of headers */ - if( ( parser->msg.is_request ) - && ( parser->msg.method == HTTPMETHOD_POST ) ) { - parser->position = POS_COMPLETE; /*post entity parsing */ - /*is handled separately */ - return PARSE_SUCCESS; - } - - parser->position = POS_ENTITY; /* read entity next */ - return PARSE_OK; - } - /* */ - /* not end; read header */ - /* */ - if( tok_type != TT_IDENTIFIER ) { - return PARSE_FAILURE; /* didn't see header name */ - } - - status = match( scanner, " : %R%c", &hdr_value ); - if( status != PARSE_OK ) { - /* pushback tokens; useful only on INCOMPLETE error */ - scanner->cursor = save_pos; - return status; - } - /* */ - /* add header */ - /* */ - - /* find header */ - index = map_str_to_int( token.buf, token.length, Http_Header_Names, - NUM_HTTP_HEADER_NAMES, FALSE ); - if( index != -1 ) { - - /*Check if it is a soap header */ - if( Http_Header_Names[index].id == HDR_SOAPACTION ) { - parser->msg.method = SOAPMETHOD_POST; - } - - header_id = Http_Header_Names[index].id; - orig_header = - httpmsg_find_hdr( &parser->msg, header_id, NULL ); - } else { - header_id = HDR_UNKNOWN; - - save_char = token.buf[token.length]; - token.buf[token.length] = '\0'; - - orig_header = httpmsg_find_hdr_str( &parser->msg, token.buf ); - - token.buf[token.length] = save_char; /* restore */ - } - - if( orig_header == NULL ) { - /* */ - /* add new header */ - /* */ - - header = ( http_header_t * ) malloc( sizeof( http_header_t ) ); - if( header == NULL ) { - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - membuffer_init( &header->name_buf ); - membuffer_init( &header->value ); - - /* value can be 0 length */ - if( hdr_value.length == 0 ) { - hdr_value.buf = "\0"; - hdr_value.length = 1; - } - /* save in header in buffers */ - if( membuffer_assign - ( &header->name_buf, token.buf, token.length ) != 0 - || membuffer_assign( &header->value, hdr_value.buf, - hdr_value.length ) != 0 ) { - /* not enuf mem */ - free (header); - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - - header->name.buf = header->name_buf.buf; - header->name.length = header->name_buf.length; - header->name_id = header_id; - - ListAddTail( &parser->msg.headers, header ); - - /*NNS: ret = dlist_append( &parser->msg.headers, header ); */ + while (TRUE) { + save_pos = scanner->cursor; + /* check end of headers */ + status = scanner_get_token(scanner, &token, &tok_type); + if (status != PARSE_OK) { + return status; + } + if (tok_type == TT_CRLF) { + /* end of headers */ + if ((parser->msg.is_request) + && (parser->msg.method == HTTPMETHOD_POST)) { + parser->position = POS_COMPLETE; /*post entity parsing */ + /*is handled separately */ + return PARSE_SUCCESS; + } + parser->position = POS_ENTITY; /* read entity next */ + return PARSE_OK; + } + /* not end; read header */ + if (tok_type != TT_IDENTIFIER) { + return PARSE_FAILURE; /* didn't see header name */ + } + status = match(scanner, " : %R%c", &hdr_value); + if (status != PARSE_OK) { + /* pushback tokens; useful only on INCOMPLETE error */ + scanner->cursor = save_pos; + return status; + } + /* add header */ + /* find header */ + index = + map_str_to_int(token.buf, token.length, Http_Header_Names, + NUM_HTTP_HEADER_NAMES, FALSE); + if (index != -1) { + /*Check if it is a soap header */ + if (Http_Header_Names[index].id == HDR_SOAPACTION) { + parser->msg.method = SOAPMETHOD_POST; + } + header_id = Http_Header_Names[index].id; + orig_header = + httpmsg_find_hdr(&parser->msg, header_id, NULL); + } else { + header_id = HDR_UNKNOWN; + save_char = token.buf[token.length]; + token.buf[token.length] = '\0'; + orig_header = + httpmsg_find_hdr_str(&parser->msg, token.buf); + token.buf[token.length] = save_char; /* restore */ + } + if (orig_header == NULL) { + /* add new header */ + header = + (http_header_t *) malloc(sizeof(http_header_t)); + if (header == NULL) { + parser->http_error_code = + HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + membuffer_init(&header->name_buf); + membuffer_init(&header->value); + /* value can be 0 length */ + if (hdr_value.length == 0) { + /* FIXME: Is this a bug? buf is not const. */ + hdr_value.buf = "\0"; + hdr_value.length = 1; + } + /* save in header in buffers */ + if (membuffer_assign(&header->name_buf, token.buf, token.length) || + membuffer_assign(&header->value, hdr_value.buf, hdr_value.length)) { + /* not enough mem */ + free(header); + parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + header->name.buf = header->name_buf.buf; + header->name.length = header->name_buf.length; + header->name_id = header_id; + ListAddTail(&parser->msg.headers, header); + /*NNS: ret = dlist_append( &parser->msg.headers, header ); */ /** TODO: remove that? */ - if( ret == UPNP_E_OUTOF_MEMORY ) { - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } + if (ret == UPNP_E_OUTOF_MEMORY) { + parser->http_error_code = + HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } /** end of remove that? */ - } else if( hdr_value.length > 0 ) { - /* */ - /* append value to existing header */ - /* */ - - /* append space */ - ret = membuffer_append_str( &orig_header->value, ", " ); - - /* append continuation of header value */ - ret2 = membuffer_append( &orig_header->value, - hdr_value.buf, hdr_value.length ); - - if( ret == UPNP_E_OUTOF_MEMORY || ret2 == UPNP_E_OUTOF_MEMORY ) { - /* not enuf mem */ - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - } - } /* end while */ + } else if (hdr_value.length > 0) { + /* append value to existing header */ + /* append space */ + ret = membuffer_append_str(&orig_header->value, ", "); + /* append continuation of header value */ + ret2 = membuffer_append(&orig_header->value, + hdr_value.buf, + hdr_value.length); + if (ret == UPNP_E_OUTOF_MEMORY + || ret2 == UPNP_E_OUTOF_MEMORY) { + /* not enuf mem */ + parser->http_error_code = + HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + } + } /* end while */ } @@ -1706,36 +1607,35 @@ parser_parse_entity_using_clen( INOUT http_parser_t * parser ) * PARSE_FAILURE -- entity length > content-length value * PARSE_SUCCESS ************************************************************************/ -static UPNP_INLINE parse_status_t -parser_parse_chunky_body( INOUT http_parser_t * parser ) +static UPNP_INLINE parse_status_t parser_parse_chunky_body( + INOUT http_parser_t *parser) { - parse_status_t status; - size_t save_pos; + parse_status_t status; + size_t save_pos; - /* if 'chunk_size' of bytes have been read; read next chunk */ - if( ( int )( parser->msg.msg.length - parser->scanner.cursor ) >= - parser->chunk_size ) { - /* move to next chunk */ - parser->scanner.cursor += parser->chunk_size; - save_pos = parser->scanner.cursor; - - /*discard CRLF */ - status = match( &parser->scanner, "%c" ); - if( status != PARSE_OK ) { - parser->scanner.cursor -= parser->chunk_size; /*move back */ - /*parser->scanner.cursor = save_pos; */ - return status; - } - - membuffer_delete( &parser->msg.msg, save_pos, - ( parser->scanner.cursor - save_pos ) ); - parser->scanner.cursor = save_pos; - parser->msg.entity.length += parser->chunk_size; /*update temp */ - parser->ent_position = ENTREAD_USING_CHUNKED; - return PARSE_CONTINUE_1; - } else { - return PARSE_INCOMPLETE; /* need more data for chunk */ - } + /* if 'chunk_size' of bytes have been read; read next chunk */ + if ((int)(parser->msg.msg.length - parser->scanner.cursor) >= parser->chunk_size) { + /* move to next chunk */ + parser->scanner.cursor += parser->chunk_size; + save_pos = parser->scanner.cursor; + /* discard CRLF */ + status = match(&parser->scanner, "%c"); + if (status != PARSE_OK) { + /*move back */ + parser->scanner.cursor -= parser->chunk_size; + /*parser->scanner.cursor = save_pos; */ + return status; + } + membuffer_delete(&parser->msg.msg, save_pos, + (parser->scanner.cursor - save_pos)); + parser->scanner.cursor = save_pos; + /*update temp */ + parser->msg.entity.length += parser->chunk_size; + parser->ent_position = ENTREAD_USING_CHUNKED; + return PARSE_CONTINUE_1; + } else + /* need more data for chunk */ + return PARSE_INCOMPLETE; } /************************************************************************ @@ -1943,11 +1843,7 @@ parser_get_entity_read_method( INOUT http_parser_t * parser ) } /* * use content length */ if( httpmsg_find_hdr( hmsg, HDR_CONTENT_LENGTH, &hdr_value ) ) { - parser->content_length = raw_to_int( &hdr_value, 10 ); - if( parser->content_length < 0 ) { - /* bad content-length */ - return PARSE_FAILURE; - } + parser->content_length = (unsigned int)raw_to_int(&hdr_value, 10); parser->ent_position = ENTREAD_USING_CLEN; return PARSE_CONTINUE_1; } @@ -2172,25 +2068,22 @@ parser_append( INOUT http_parser_t * parser, ************************************************************************/ int raw_to_int(IN memptr *raw_value, IN int base) { - long num; - char *end_ptr; - - if( raw_value->length == 0 ) { - return -1; - } - - errno = 0; - num = strtol( raw_value->buf, &end_ptr, base ); - if( ( num < 0 ) - /* all and only those chars in token should be used for num */ - || ( end_ptr != raw_value->buf + raw_value->length ) - || ( ( num == LONG_MIN || num == LONG_MAX ) - && ( errno == ERANGE ) ) - ) { - return -1; - } - return num; + long num; + char *end_ptr; + if (raw_value->length == 0) + return -1; + errno = 0; + num = strtol(raw_value->buf, &end_ptr, base); + if ((num < 0) + /* all and only those chars in token should be used for num */ + || (end_ptr != raw_value->buf + raw_value->length) + || ((num == LONG_MIN || num == LONG_MAX) + && (errno == ERANGE)) + ) { + return -1; + } + return (int)num; } /************************************************************************ @@ -2218,7 +2111,7 @@ int raw_find_str(IN memptr *raw_value, IN const char *str) /* Make it lowercase */ for (i = 0; raw_value->buf[i]; ++i) { - raw_value->buf[i] = tolower(raw_value->buf[i]); + raw_value->buf[i] = (char)tolower(raw_value->buf[i]); } /* null-terminate */ @@ -2235,7 +2128,7 @@ int raw_find_str(IN memptr *raw_value, IN const char *str) } /* return index */ - return ptr - raw_value->buf; + return (int)(ptr - raw_value->buf); } /************************************************************************ diff --git a/upnp/src/genlib/net/http/httpreadwrite.c b/upnp/src/genlib/net/http/httpreadwrite.c index e217d10..52df2f0 100644 --- a/upnp/src/genlib/net/http/httpreadwrite.c +++ b/upnp/src/genlib/net/http/httpreadwrite.c @@ -29,20 +29,17 @@ * ******************************************************************************/ - -/************************************************************************ -* Purpose: This file defines the functionality making use of the http -* It defines functions to receive messages, process messages, send -* messages -************************************************************************/ - +/*! + * \file + * + * Purpose: This file defines the functionality making use of the http. + * It defines functions to receive messages, process messages, send messages. + */ #include "config.h" - #include "httpreadwrite.h" - #include "unixutil.h" #include "upnp.h" #include "upnpapi.h" @@ -53,11 +50,9 @@ #include "UpnpInet.h" #include "webserver.h" - #include #include - #ifndef UPNP_USE_BCBPP #ifndef UPNP_USE_MSVCPP #include @@ -65,7 +60,6 @@ #endif #endif - #ifdef WIN32 #include #define fseeko fseek @@ -80,7 +74,6 @@ #include #endif - /* * Please, do not change these to const int while MSVC cannot understand * const int in array dimensions. @@ -92,13 +85,11 @@ const int CHUNK_TAIL_SIZE = 10; #define CHUNK_HEADER_SIZE 10 #define CHUNK_TAIL_SIZE 10 - #ifndef UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS /* in seconds */ #define DEFAULT_TCP_CONNECT_TIMEOUT 5 - /************************************************************************ * Function : Make_Socket_NoBlocking * @@ -242,7 +233,7 @@ static int private_connect( int http_FixUrl(IN uri_type *url, OUT uri_type *fixed_url) { - char *temp_path = "/"; + const char *temp_path = "/"; *fixed_url = *url; if (token_string_casecmp(&fixed_url->scheme, "http") != 0) { @@ -294,7 +285,7 @@ SOCKET http_Connect( OUT uri_type *url) { SOCKET connfd; - int sockaddr_len; + socklen_t sockaddr_len; int ret_connect; http_FixUrl(destination_url, url); @@ -303,8 +294,8 @@ SOCKET http_Connect( if (connfd == -1) { return UPNP_E_OUTOF_SOCKET; } - sockaddr_len = url->hostport.IPaddress.ss_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); + sockaddr_len = (socklen_t)(url->hostport.IPaddress.ss_family == AF_INET6 ? + sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); ret_connect = private_connect(connfd, (struct sockaddr *)&url->hostport.IPaddress, sockaddr_len); if (ret_connect == -1) { @@ -350,7 +341,7 @@ int http_RecvMessage( int line = 0; parse_status_t status; int num_read; - xboolean ok_on_close = FALSE; + int ok_on_close = FALSE; char buf[2 * 1024]; if (request_method == HTTPMETHOD_UNKNOWN) { @@ -363,7 +354,7 @@ int http_RecvMessage( num_read = sock_read(info, buf, sizeof buf, timeout_secs); if (num_read > 0) { /* got data */ - status = parser_append(parser, buf, num_read); + status = parser_append(parser, buf, (size_t)num_read); if (status == PARSE_SUCCESS) { UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "<<< (RECVD) <<<\n%s\n-----------------\n", @@ -454,180 +445,167 @@ ExitFunction: * UPNP_E_FILE_READ_ERROR * UPNP_E_SUCCESS ************************************************************************/ -int -http_SendMessage( IN SOCKINFO * info, - IN OUT int *TimeOut, - IN const char *fmt, - ... ) +int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut, + IN const char *fmt, ...) { - char c; - char *buf = NULL; - size_t buf_length; - char *filename = NULL; - FILE *Fp; - int num_read; - int num_written; - off_t amount_to_be_read = 0; - va_list argp; - char *file_buf = NULL; - char *ChunkBuf = NULL; - struct SendInstruction *Instr = NULL; - char Chunk_Header[CHUNK_HEADER_SIZE]; - int RetVal = 0; + FILE *Fp; + va_list argp; + struct SendInstruction *Instr = NULL; + size_t num_read; + size_t num_written; + int nr; + int nw; + int RetVal = 0; + char c; + char *buf = NULL; + size_t buf_length; + char *filename = NULL; + char *file_buf = NULL; + char *ChunkBuf = NULL; + char Chunk_Header[CHUNK_HEADER_SIZE]; + size_t amount_to_be_read = 0; + /* 10 byte allocated for chunk header. */ + size_t Data_Buf_Size = WEB_SERVER_BUF_SIZE; - /* 10 byte allocated for chunk header. */ - int Data_Buf_Size = WEB_SERVER_BUF_SIZE; + va_start(argp, fmt); + while ((c = *fmt++) != 0) { + if (c == 'I') { + Instr = va_arg(argp, struct SendInstruction *); - va_start( argp, fmt ); + assert(Instr); - while( ( c = *fmt++ ) != 0 ) { - if( c == 'I' ) { - Instr = va_arg(argp, struct SendInstruction *); - - assert( Instr ); - - if( Instr->ReadSendSize >= 0 ) { - amount_to_be_read = Instr->ReadSendSize; - } else { - amount_to_be_read = Data_Buf_Size; - } - - if( amount_to_be_read < WEB_SERVER_BUF_SIZE ) { - Data_Buf_Size = amount_to_be_read; - } - - ChunkBuf = (char *)malloc( - Data_Buf_Size + CHUNK_HEADER_SIZE + CHUNK_TAIL_SIZE); - if( !ChunkBuf ) { - return UPNP_E_OUTOF_MEMORY; - } - - file_buf = ChunkBuf + CHUNK_HEADER_SIZE; - } else if( c == 'f' ) { - /* file name */ - filename = va_arg(argp, char *); - if( Instr && Instr->IsVirtualFile ) { - Fp = (virtualDirCallback.open)( filename, UPNP_READ ); - } else { - Fp = fopen( filename, "rb" ); - } - if( Fp == NULL ) { - free( ChunkBuf ); - return UPNP_E_FILE_READ_ERROR; - } - - if( Instr && Instr->IsRangeActive && Instr->IsVirtualFile ) { - if( virtualDirCallback.seek( Fp, Instr->RangeOffset, - SEEK_CUR ) != 0 ) { - free( ChunkBuf ); - return UPNP_E_FILE_READ_ERROR; - } - } else if( Instr && Instr->IsRangeActive ) { - if( fseeko( Fp, Instr->RangeOffset, SEEK_CUR ) != 0 ) { - free( ChunkBuf ); - return UPNP_E_FILE_READ_ERROR; - } - } - - while( amount_to_be_read ) { - if( Instr ) { - int n = (amount_to_be_read >= Data_Buf_Size) ? - Data_Buf_Size : amount_to_be_read; - if( Instr->IsVirtualFile ) { - num_read = virtualDirCallback.read( Fp, file_buf, n ); - } else { - num_read = fread( file_buf, 1, n, 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 ) { - char *str = "0\r\n\r\n"; - num_written = sock_write(info, str, strlen(str), 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 ) { - /* Send error nothing we can do. */ - goto Cleanup_File; - } - } else { - /* write data */ - num_written = sock_write( info, file_buf, num_read, TimeOut ); - 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 = va_arg(argp, char *); - buf_length = va_arg(argp, size_t); - if( buf_length > 0 ) { - num_written = sock_write( info, buf, buf_length, TimeOut ); - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - ">>> (SENT) >>>\n" - "%.*s\nbuf_length=%d, num_written=%d\n" - "------------\n", - (int)buf_length, buf, (int)buf_length, num_written ); - if( (size_t)num_written != buf_length ) { - goto end; + if (Instr->ReadSendSize >= 0) + amount_to_be_read = (size_t)Instr->ReadSendSize; + else + amount_to_be_read = Data_Buf_Size; + if (amount_to_be_read < WEB_SERVER_BUF_SIZE) + Data_Buf_Size = amount_to_be_read; + ChunkBuf = malloc((size_t) + (Data_Buf_Size + CHUNK_HEADER_SIZE + + CHUNK_TAIL_SIZE)); + if (!ChunkBuf) + return UPNP_E_OUTOF_MEMORY; + file_buf = ChunkBuf + CHUNK_HEADER_SIZE; + } else if (c == 'f') { + /* file name */ + filename = va_arg(argp, char *); + if (Instr && Instr->IsVirtualFile) + Fp = (virtualDirCallback.open)(filename, UPNP_READ); + else + Fp = fopen(filename, "rb"); + if (Fp == NULL) { + free(ChunkBuf); + return UPNP_E_FILE_READ_ERROR; + } + if (Instr && Instr->IsRangeActive && Instr->IsVirtualFile) { + if (virtualDirCallback.seek(Fp, Instr->RangeOffset, + SEEK_CUR) != 0) { + free(ChunkBuf); + return UPNP_E_FILE_READ_ERROR; + } + } else if (Instr && Instr->IsRangeActive) { + if (fseeko(Fp, Instr->RangeOffset, SEEK_CUR) != 0) { + free(ChunkBuf); + return UPNP_E_FILE_READ_ERROR; + } + } + while (amount_to_be_read) { + if (Instr) { + size_t n = amount_to_be_read >= Data_Buf_Size ? + Data_Buf_Size : amount_to_be_read; + if (Instr->IsVirtualFile) { + nr = virtualDirCallback.read(Fp, file_buf, n); + amount_to_be_read -= (size_t)nr; + } else { + num_read = fread(file_buf, 1, n, Fp); + 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) { + const char *str = "0\r\n\r\n"; + nw = sock_write(info, str, + strlen(str), + 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, "%zx", 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)); */ + nw = sock_write(info, + file_buf - strlen(Chunk_Header), + num_read + strlen(Chunk_Header) + 2, + TimeOut); + num_written = (size_t)nw; + if (nw <= 0 || num_written != num_read + strlen(Chunk_Header) + 2) + /* Send error nothing we can do. */ + goto Cleanup_File; + } else { + /* write data */ + nw = sock_write(info, file_buf, num_read, TimeOut); + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + ">>> (SENT) >>>\n%.*s\n------------\n", + nw, file_buf); + /* Send error nothing we can do */ + num_written = (size_t)nw; + if (nw <= 0 || 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 = va_arg(argp, char *); + buf_length = va_arg(argp, size_t); + if (buf_length > 0) { + nw = sock_write(info, file_buf, num_read, TimeOut); + num_written = (size_t)nw; + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + ">>> (SENT) >>>\n" + "%.*s\nbuf_length=%zd, num_written=%zd\n""------------\n", + (int)buf_length, buf, buf_length, num_written); + if (num_written != buf_length) { + goto end; + } + } } - } - } - } + } -end: - va_end( argp ); - free( ChunkBuf ); - return 0; + end: + va_end(argp); + free(ChunkBuf); + return 0; } @@ -663,7 +641,7 @@ int http_RequestAndResponse( { SOCKET tcp_connection; int ret_code; - int sockaddr_len; + size_t sockaddr_len; int http_error_code; SOCKINFO info; @@ -682,7 +660,8 @@ int http_RequestAndResponse( sockaddr_len = destination->hostport.IPaddress.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); ret_code = private_connect(info.socket, - (struct sockaddr *)&(destination->hostport.IPaddress), sockaddr_len); + (struct sockaddr *)&(destination->hostport.IPaddress), + (socklen_t)sockaddr_len); if (ret_code == -1) { parser_response_init(response, req_method); ret_code = UPNP_E_SOCKET_CONNECT; @@ -726,142 +705,120 @@ end_function: * UPNP_E_SUCCESS * UPNP_E_INVALID_URL ************************************************************************/ -int -http_Download( IN const char *url_str, +int http_Download( IN const char *url_str, IN int timeout_secs, OUT char **document, - OUT int *doc_length, + OUT size_t *doc_length, OUT char *content_type ) { - int ret_code; - uri_type url; - char *msg_start; - char *entity_start; - char *hoststr; - char *temp; - http_parser_t response; - size_t msg_length; - size_t hostlen; - memptr ctype; - size_t copy_len; - membuffer request; - char *urlPath = alloca( strlen( url_str ) + 1 ); + int ret_code; + uri_type url; + char *msg_start; + char *entity_start; + char *hoststr; + char *temp; + http_parser_t response; + size_t msg_length; + size_t 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 ); */ - 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 ); + /*ret_code = parse_uri( (char*)url_str, strlen(url_str), &url ); */ + 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 = '/'; + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HOSTNAME : %s Length : %" PRIzu "\n", hoststr, hostlen); + ret_code = http_MakeMessage(&request, 1, 1, + "Q" "s" "bcDCUc", + HTTPMETHOD_GET, url.pathquery.buff, + url.pathquery.size, "HOST: ", hoststr, + hostlen); + if (ret_code != 0) { + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Makemessage failed\n"); + membuffer_destroy(&request); + return ret_code; + } + 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); - strcpy( urlPath, url_str ); - hoststr = strstr( urlPath, "//" ); - if( hoststr == NULL ) { - return UPNP_E_INVALID_URL; - } + if (ret_code != 0) { + httpmsg_destroy(&response.msg); + membuffer_destroy(&request); + return ret_code; + } + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n"); + 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; - hoststr += 2; - temp = strchr( hoststr, '/' ); - if( temp == NULL ) { - return UPNP_E_INVALID_URL; - } + memcpy(content_type, ctype.buf, copy_len); + content_type[copy_len] = '\0'; + } + } + /* extract doc from msg */ + if ((*doc_length = 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(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); - *temp = '\0'; - hostlen = strlen( hoststr ); - *temp = '/'; - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen ); - - ret_code = http_MakeMessage( - &request, 1, 1, - "Q" "s" "bcDCUc", - HTTPMETHOD_GET, url.pathquery.buff, url.pathquery.size, - "HOST: ", - hoststr, hostlen ); - if( ret_code != 0 ) { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Makemessage failed\n" ); - membuffer_destroy( &request ); - return ret_code; - } - - 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; - } - - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n" ); - 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; + return ret_code; } typedef struct HTTPPOSTHANDLE { - SOCKINFO sock_info; - int contentLength; + SOCKINFO sock_info; + int contentLength; } http_post_handle_t; /************************************************************************ @@ -883,89 +840,70 @@ typedef struct HTTPPOSTHANDLE { * UPNP_E_INVALID_PARAM * UPNP_E_SUCCESS ************************************************************************/ -int -MakePostMessage( const char *url_str, - membuffer * request, - uri_type * url, - int contentLength, - const char *contentType ) +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 ); - size_t hostlen = 0; - char *hoststr, - *temp; + int ret_code = 0; + char *urlPath = alloca(strlen(url_str) + 1); + size_t hostlen = 0; + char *hoststr; + char *temp; - 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 ); + 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 = '/'; + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HOSTNAME : %s Length : %" PRIzu "\n", hoststr, hostlen); + if (contentLength >= 0) + ret_code = http_MakeMessage(request, 1, 1, + "Q" "s" "bcDCU" "T" "Nc", + HTTPMETHOD_POST, + url->pathquery.buff, + url->pathquery.size, "HOST: ", + hoststr, hostlen, contentType, + (off_t) contentLength); + else if (contentLength == UPNP_USING_CHUNKED) + ret_code = http_MakeMessage(request, 1, 1, + "Q" "s" "bcDCU" "TKc", + HTTPMETHOD_POST, + url->pathquery.buff, + url->pathquery.size, "HOST: ", + hoststr, hostlen, contentType); + else if (contentLength == UPNP_UNTIL_CLOSE) + ret_code = http_MakeMessage(request, 1, 1, + "Q" "s" "bcDCU" "Tc", + HTTPMETHOD_POST, + url->pathquery.buff, + url->pathquery.size, "HOST: ", + hoststr, hostlen, contentType); + else + ret_code = UPNP_E_INVALID_PARAM; + if (ret_code != 0) { + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Makemessage failed\n"); + membuffer_destroy(request); + return ret_code; + } + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Buffer:\n%s\n" "----------END--------\n", + request->buf); - 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 = '/'; - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen ); - - if( contentLength >= 0 ) { - ret_code = http_MakeMessage( - request, 1, 1, - "Q" "s" "bcDCU" "T" "Nc", - HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size, - "HOST: ", - hoststr, hostlen, - contentType, - (off_t)contentLength ); - } else if( contentLength == UPNP_USING_CHUNKED ) { - ret_code = http_MakeMessage( - request, 1, 1, - "Q" "s" "bcDCU" "TKc", - HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size, - "HOST: ", - hoststr, hostlen, - contentType ); - } else if( contentLength == UPNP_UNTIL_CLOSE ) { - ret_code = http_MakeMessage( - request, 1, 1, - "Q" "s" "bcDCU" "Tc", - HTTPMETHOD_POST, url->pathquery.buff, url->pathquery.size, - "HOST: ", - hoststr, hostlen, - contentType ); - } else { - ret_code = UPNP_E_INVALID_PARAM; - } - - if( ret_code != 0 ) { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Makemessage failed\n" ); - membuffer_destroy( request ); - - return ret_code; - } - - UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Buffer:\n%s\n" "----------END--------\n", - request->buf); - - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; } /************************************************************************ @@ -987,60 +925,53 @@ MakePostMessage( const char *url_str, * UPNP_E_INVALID_PARAM - Invalid Parameter * -1 - On Socket Error. ************************************************************************/ -int -http_WriteHttpPost( IN void *Handle, +int http_WriteHttpPost( IN void *Handle, IN char *buf, - IN unsigned int *size, + IN size_t *size, IN int timeout ) { - http_post_handle_t *handle = ( http_post_handle_t * ) Handle; - char *tempbuf = NULL; - int tempbufSize = 0; - int freeTempbuf = 0; - int numWritten = 0; + http_post_handle_t *handle = (http_post_handle_t *)Handle; + char *tempbuf = NULL; + size_t tempbufSize = 0; + int freeTempbuf = 0; + int numWritten = 0; - if( ( !handle ) || ( !size ) || ( ( ( *size ) > 0 ) && !buf ) - || ( ( *size ) < 0 ) ) { - if(size) ( *size ) = 0; - return UPNP_E_INVALID_PARAM; - } - if( handle->contentLength == UPNP_USING_CHUNKED ) { - if( ( *size ) ) { - int tempSize = 0; - tempbuf = ( char * )malloc( - *size + CHUNK_HEADER_SIZE + CHUNK_TAIL_SIZE ); - if ( tempbuf == NULL) { - return UPNP_E_OUTOF_MEMORY; - } - - /* begin chunk */ - sprintf( tempbuf, "%x\r\n", ( *size ) ); - tempSize = strlen( tempbuf ); - memcpy( tempbuf + tempSize, buf, ( *size ) ); - memcpy( tempbuf + tempSize + ( *size ), "\r\n", 2 ); - /* end of chunk */ - tempbufSize = tempSize + ( *size ) + 2; - freeTempbuf = 1; - } - } else { - tempbuf = buf; - tempbufSize = ( *size ); - } - - numWritten = - sock_write( &handle->sock_info, tempbuf, tempbufSize, &timeout ); - /*(*size) = sock_write(&handle->sock_info,tempbuf,tempbufSize,&timeout); */ - - if( freeTempbuf ) { - free( tempbuf ); - } - if( numWritten < 0 ) { - ( *size ) = 0; - return numWritten; - } else { - ( *size ) = numWritten; - return UPNP_E_SUCCESS; - } + if (!handle || !size || !buf) { + if (size) + *size = 0; + return UPNP_E_INVALID_PARAM; + } + if (handle->contentLength == UPNP_USING_CHUNKED) { + if (*size) { + size_t tempSize = 0; + tempbuf = malloc(*size + + CHUNK_HEADER_SIZE + CHUNK_TAIL_SIZE); + if (!tempbuf) + return UPNP_E_OUTOF_MEMORY; + /* begin chunk */ + sprintf(tempbuf, "%zx\r\n", *size); + tempSize = strlen(tempbuf); + memcpy(tempbuf + tempSize, buf, *size); + memcpy(tempbuf + tempSize + *size, "\r\n", 2); + /* end of chunk */ + tempbufSize = tempSize + *size + 2; + freeTempbuf = 1; + } + } else { + tempbuf = buf; + tempbufSize = *size; + } + numWritten = + sock_write(&handle->sock_info, tempbuf, tempbufSize, &timeout); + if (freeTempbuf) + free(tempbuf); + if (numWritten < 0) { + *size = 0; + return numWritten; + } else { + *size = (size_t)numWritten; + return UPNP_E_SUCCESS; + } } /************************************************************************ @@ -1061,39 +992,30 @@ http_WriteHttpPost( IN void *Handle, * UPNP_E_SUCCESS - On success * UPNP_E_INVALID_PARAM - Invalid Parameter ************************************************************************/ -int -http_CloseHttpPost( IN void *Handle, - IN OUT int *httpStatus, - IN int timeout ) +int http_CloseHttpPost(IN void *Handle, IN OUT int *httpStatus, IN int timeout) { - int retc = 0; - http_parser_t response; - int http_error_code; + int retc = 0; + http_parser_t response; + int http_error_code; + const char *zcrlf = "0\r\n\r\n"; - http_post_handle_t *handle = Handle; + http_post_handle_t *handle = Handle; + if ((!handle) || (!httpStatus)) + return UPNP_E_INVALID_PARAM; + if (handle->contentLength == UPNP_USING_CHUNKED) + /*send last chunk */ + retc = sock_write(&handle->sock_info, zcrlf, strlen(zcrlf), &timeout); + /*read response */ + parser_response_init(&response, HTTPMETHOD_POST); + retc = http_RecvMessage(&handle->sock_info, &response, + HTTPMETHOD_POST, &timeout, &http_error_code); + *httpStatus = http_error_code; + /*should shutdown completely */ + sock_destroy(&handle->sock_info, SD_BOTH); + httpmsg_destroy(&response.msg); + free(handle); - if( ( !handle ) || ( !httpStatus ) ) { - return UPNP_E_INVALID_PARAM; - } - - if( handle->contentLength == UPNP_USING_CHUNKED ) { - retc = sock_write( &handle->sock_info, "0\r\n\r\n", strlen( "0\r\n\r\n" ), &timeout ); /*send last chunk */ - } - /*read response */ - parser_response_init( &response, HTTPMETHOD_POST ); - - retc = - http_RecvMessage( &handle->sock_info, &response, HTTPMETHOD_POST, - &timeout, &http_error_code ); - - ( *httpStatus ) = http_error_code; - - sock_destroy( &handle->sock_info, SD_BOTH ); /*should shutdown completely */ - - httpmsg_destroy( &response.msg ); - free( handle ); - - return retc; + return retc; } /************************************************************************ @@ -1127,42 +1049,39 @@ int http_OpenHttpPost( IN int timeout) { int ret_code; - int sockaddr_len; + size_t sockaddr_len; SOCKET tcp_connection; membuffer request; http_post_handle_t *handle = NULL; uri_type url; - if ( !url_str || !Handle || !contentType) { + if (!url_str || !Handle || !contentType) return UPNP_E_INVALID_PARAM; - } - *Handle = handle; - ret_code = MakePostMessage(url_str, &request, &url, - contentLength, contentType); - if (ret_code != UPNP_E_SUCCESS) { + contentLength, contentType); + if (ret_code != UPNP_E_SUCCESS) return ret_code; - } - handle = (http_post_handle_t *) malloc(sizeof(http_post_handle_t)); - if (!handle) { + handle = malloc(sizeof(http_post_handle_t)); + if (!handle) return UPNP_E_OUTOF_MEMORY; - } handle->contentLength = contentLength; - tcp_connection = socket(url.hostport.IPaddress.ss_family, SOCK_STREAM, 0); + tcp_connection = socket(url.hostport.IPaddress.ss_family, + SOCK_STREAM, 0); if (tcp_connection == -1) { ret_code = UPNP_E_SOCKET_ERROR; goto errorHandler; } if (sock_init(&handle->sock_info, tcp_connection) != UPNP_E_SUCCESS) { - sock_destroy( &handle->sock_info, SD_BOTH ); + sock_destroy(&handle->sock_info, SD_BOTH); ret_code = UPNP_E_SOCKET_ERROR; goto errorHandler; } sockaddr_len = url.hostport.IPaddress.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); ret_code = private_connect(handle->sock_info.socket, - (struct sockaddr *)&(url.hostport.IPaddress), sockaddr_len); + (struct sockaddr *)&(url.hostport.IPaddress), + (socklen_t)sockaddr_len); if (ret_code == -1) { sock_destroy(&handle->sock_info, SD_BOTH); ret_code = UPNP_E_SOCKET_CONNECT; @@ -1170,12 +1089,11 @@ int http_OpenHttpPost( } /* send request */ ret_code = http_SendMessage(&handle->sock_info, &timeout, "b", - request.buf, request.length); - if (ret_code != 0) { + request.buf, request.length); + if (ret_code != 0) sock_destroy(&handle->sock_info, SD_BOTH); - } -errorHandler: + errorHandler: membuffer_destroy(&request); *Handle = handle; @@ -1207,78 +1125,59 @@ typedef struct HTTPGETHANDLE { * Error Codes returned by http_MakeMessage * UPNP_E_SUCCESS ************************************************************************/ -int -MakeGetMessage( const char *url_str, - const char *proxy_str, - membuffer * request, - uri_type * url ) +int MakeGetMessage(const char *url_str, const char *proxy_str, + membuffer *request, uri_type *url) { - int ret_code; - char *urlPath = alloca( strlen( url_str ) + 1 ); - size_t querylen = 0; - const char *querystr; - size_t hostlen = 0; - char *hoststr, - *temp; + int ret_code; + char *urlPath = alloca(strlen(url_str) + 1); + size_t querylen = 0; + const char *querystr; + size_t hostlen = 0; + char *hoststr, *temp; - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "DOWNLOAD URL : %s\n", url_str ); + 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 = '/'; + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HOSTNAME : %s Length : %" PRIzu "\n", hoststr, hostlen); + if (proxy_str) { + querystr = url_str; + querylen = strlen(querystr); + } else { + querystr = url->pathquery.buff; + querylen = url->pathquery.size; + } + ret_code = http_MakeMessage(request, 1, 1, + "Q" "s" "bcDCUc", + HTTPMETHOD_GET, querystr, querylen, + "HOST: ", hoststr, hostlen); + if (ret_code != 0) { + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Makemessage failed\n"); + membuffer_destroy(request); - ret_code = - http_FixStrUrl( ( char * )url_str, strlen( url_str ), url ); + return ret_code; + } + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Buffer:\n%s\n" "----------END--------\n", + request->buf); - 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 = '/'; - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HOSTNAME : %s Length : %"PRIzu"\n", hoststr, hostlen ); - - if( proxy_str ) { - querystr = url_str; - querylen = strlen( querystr ); - } else { - querystr = url->pathquery.buff; - querylen = url->pathquery.size; - } - - ret_code = http_MakeMessage( - request, 1, 1, - "Q" "s" "bcDCUc", - HTTPMETHOD_GET, querystr, querylen, - "HOST: ", - hoststr, hostlen ); - - if( ret_code != 0 ) { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Makemessage failed\n" ); - membuffer_destroy( request ); - - return ret_code; - } - - UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Buffer:\n%s\n" "----------END--------\n", - request->buf); - - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; } /*! @@ -1301,103 +1200,91 @@ static int ReadResponseLineAndHeaders( /*! HTTP errror code returned. */ IN OUT int *http_error_code) { - parse_status_t status; - int num_read; - char buf[2 * 1024]; - int done = 0; - int ret_code = 0; + parse_status_t status; + int num_read; + char buf[2 * 1024]; + int done = 0; + int ret_code = 0; - /*read response line */ + /*read response line */ + status = parser_parse_responseline(parser); + if (status == PARSE_OK) + done = 1; + else if (status == PARSE_INCOMPLETE) + done = 0; + else + /*error */ + return status; + while (!done) { + num_read = sock_read(info, buf, sizeof(buf), timeout_secs); + if (num_read > 0) { + /* append data to buffer */ + ret_code = + membuffer_append(&parser->msg.msg, buf, (size_t)num_read); + if (ret_code != 0) { + /* set failure status */ + parser->http_error_code = + HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + status = parser_parse_responseline(parser); + if (status == PARSE_OK) { + done = 1; + } else if (status == PARSE_INCOMPLETE) { + done = 0; + } else { + /*error */ + return status; + } + } else if (num_read == 0) { + /* partial msg */ + *http_error_code = HTTP_BAD_REQUEST; /* or response */ + return UPNP_E_BAD_HTTPMSG; + } else { + *http_error_code = parser->http_error_code; + return num_read; + } + } + done = 0; + status = parser_parse_headers(parser); + if ((status == PARSE_OK) && (parser->position == POS_ENTITY)) + done = 1; + else if (status == PARSE_INCOMPLETE) + done = 0; + else + /*error */ + return status; + /*read headers */ + while (!done) { + num_read = sock_read(info, buf, sizeof(buf), timeout_secs); + if (num_read > 0) { + /* append data to buffer */ + ret_code = + membuffer_append(&parser->msg.msg, buf, (size_t)num_read); + if (ret_code != 0) { + /* set failure status */ + parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; + return PARSE_FAILURE; + } + status = parser_parse_headers(parser); + if (status == PARSE_OK && parser->position == POS_ENTITY) + done = 1; + else if (status == PARSE_INCOMPLETE) + done = 0; + else + /*error */ + return status; + } else if (num_read == 0) { + /* partial msg */ + *http_error_code = HTTP_BAD_REQUEST; /* or response */ + return UPNP_E_BAD_HTTPMSG; + } else { + *http_error_code = parser->http_error_code; + return num_read; + } + } - status = parser_parse_responseline( parser ); - if( status == PARSE_OK ) { - done = 1; - } else if( status == PARSE_INCOMPLETE ) { - done = 0; - } else { - /*error */ - return status; - } - - while( !done ) { - num_read = sock_read( info, buf, sizeof( buf ), timeout_secs ); - if( num_read > 0 ) { - /* append data to buffer */ - ret_code = membuffer_append( &parser->msg.msg, buf, num_read ); - if( ret_code != 0 ) { - /* set failure status */ - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - status = parser_parse_responseline( parser ); - if( status == PARSE_OK ) { - done = 1; - } else if( status == PARSE_INCOMPLETE ) { - done = 0; - } else { - /*error */ - return status; - } - } else if( num_read == 0 ) { - - /* partial msg */ - *http_error_code = HTTP_BAD_REQUEST; /* or response */ - return UPNP_E_BAD_HTTPMSG; - - } else { - *http_error_code = parser->http_error_code; - return num_read; - } - } - - done = 0; - - status = parser_parse_headers( parser ); - if( ( status == PARSE_OK ) && ( parser->position == POS_ENTITY ) ) { - - done = 1; - } else if( status == PARSE_INCOMPLETE ) { - done = 0; - } else { - /*error */ - return status; - } - - /*read headers */ - while( !done ) { - num_read = sock_read( info, buf, sizeof( buf ), timeout_secs ); - if( num_read > 0 ) { - /* append data to buffer */ - ret_code = membuffer_append( &parser->msg.msg, buf, num_read ); - if( ret_code != 0 ) { - /* set failure status */ - parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR; - return PARSE_FAILURE; - } - status = parser_parse_headers( parser ); - if( ( status == PARSE_OK ) - && ( parser->position == POS_ENTITY ) ) { - - done = 1; - } else if( status == PARSE_INCOMPLETE ) { - done = 0; - } else { - /*error */ - return status; - } - } else if( num_read == 0 ) { - - /* partial msg */ - *http_error_code = HTTP_BAD_REQUEST; /* or response */ - return UPNP_E_BAD_HTTPMSG; - - } else { - *http_error_code = parser->http_error_code; - return num_read; - } - } - - return PARSE_OK; + return PARSE_OK; } /************************************************************************ @@ -1426,105 +1313,95 @@ int http_ReadHttpGet( IN OUT size_t *size, IN int timeout) { - http_get_handle_t *handle = Handle; + http_get_handle_t *handle = Handle; + parse_status_t status; + int num_read; + int ok_on_close = FALSE; + char tempbuf[2 * 1024]; + int ret_code = 0; - parse_status_t status; - int num_read; - xboolean ok_on_close = FALSE; - char tempbuf[2 * 1024]; + if (!handle || !size || (*size > 0 && !buf)) { + if (size) + *size = 0; + return UPNP_E_INVALID_PARAM; + } + /* first parse what has already been gotten */ + if (handle->response.position != POS_COMPLETE) + status = parser_parse_entity(&handle->response); + else + status = PARSE_SUCCESS; + if (status == PARSE_INCOMPLETE_ENTITY) + /* read until close */ + ok_on_close = TRUE; + else if ((status != PARSE_SUCCESS) + && (status != PARSE_CONTINUE_1) + && (status != PARSE_INCOMPLETE)) { + /*error */ + *size = 0; + return UPNP_E_BAD_RESPONSE; + } + /* read more if necessary entity */ + while (handle->response.msg.entity_offset + *size > + handle->response.msg.entity.length && + !handle->cancel && + handle->response.position != POS_COMPLETE) { + num_read = sock_read(&handle->sock_info, tempbuf, + sizeof(tempbuf), &timeout); + if (num_read > 0) { + /* append data to buffer */ + ret_code = membuffer_append(&handle->response.msg.msg, + tempbuf, (size_t)num_read); + if (ret_code != 0) { + /* set failure status */ + handle->response.http_error_code = + HTTP_INTERNAL_SERVER_ERROR; + *size = 0; + return PARSE_FAILURE; + } + status = parser_parse_entity(&handle->response); + if (status == PARSE_INCOMPLETE_ENTITY) { + /* read until close */ + ok_on_close = TRUE; + } else if ((status != PARSE_SUCCESS) + && (status != PARSE_CONTINUE_1) + && (status != PARSE_INCOMPLETE)) { + /*error */ + *size = 0; + return UPNP_E_BAD_RESPONSE; + } + } else if (num_read == 0) { + if (ok_on_close) { + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "<<< (RECVD) <<<\n%s\n-----------------\n", + handle->response.msg.msg.buf); + handle->response.position = POS_COMPLETE; + } else { + /* partial msg */ + *size = 0; + handle->response.http_error_code = HTTP_BAD_REQUEST; /* or response */ + return UPNP_E_BAD_HTTPMSG; + } + } else { + *size = 0; + return num_read; + } + } + if (handle->response.msg.entity_offset + *size > + handle->response.msg.entity.length) + *size = handle->response.msg.entity.length - + handle->response.msg.entity_offset; + memcpy(buf, &handle->response.msg.msg.buf[handle->response.entity_start_position], + *size); + /* FIXME: testing size AFTER memcopy? Weird... */ + if (*size > 0) + membuffer_delete(&handle->response.msg.msg, + handle->response.entity_start_position, *size); + handle->response.msg.entity_offset += *size; + if (handle->cancel) { + return UPNP_E_CANCELED; + } - int ret_code = 0; - - if( !handle || !size || (*size > 0 && !buf) || *size < 0) { - if(size) { - *size = 0; - } - return UPNP_E_INVALID_PARAM; - } - /*first parse what has already been gotten */ - if( handle->response.position != POS_COMPLETE ) { - status = parser_parse_entity( &handle->response ); - } else { - status = PARSE_SUCCESS; - } - - if( status == PARSE_INCOMPLETE_ENTITY ) { - /* read until close */ - ok_on_close = TRUE; - } else if( ( status != PARSE_SUCCESS ) - && ( status != PARSE_CONTINUE_1 ) - && ( status != PARSE_INCOMPLETE ) ) { - /*error */ - *size = 0; - return UPNP_E_BAD_RESPONSE; - } - /*read more if necessary entity */ - while( ( ( handle->response.msg.entity_offset + *size ) > - handle->response.msg.entity.length ) - && ( ! handle->cancel ) - && ( handle->response.position != POS_COMPLETE ) ) { - num_read = - sock_read( &handle->sock_info, tempbuf, sizeof( tempbuf ), - &timeout ); - if( num_read > 0 ) { - /* append data to buffer */ - ret_code = membuffer_append( &handle->response.msg.msg, - tempbuf, num_read ); - if( ret_code != 0 ) { - /* set failure status */ - handle->response.http_error_code = - HTTP_INTERNAL_SERVER_ERROR; - *size = 0; - return PARSE_FAILURE; - } - status = parser_parse_entity( &handle->response ); - if( status == PARSE_INCOMPLETE_ENTITY ) { - /* read until close */ - ok_on_close = TRUE; - } else if( ( status != PARSE_SUCCESS ) - && ( status != PARSE_CONTINUE_1 ) - && ( status != PARSE_INCOMPLETE ) ) { - /*error */ - *size = 0; - return UPNP_E_BAD_RESPONSE; - } - } else if( num_read == 0 ) { - if( ok_on_close ) { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "<<< (RECVD) <<<\n%s\n-----------------\n", - handle->response.msg.msg.buf ); - handle->response.position = POS_COMPLETE; - } else { - /* partial msg */ - *size = 0; - handle->response.http_error_code = HTTP_BAD_REQUEST; /* or response */ - return UPNP_E_BAD_HTTPMSG; - } - } else { - *size = 0; - return num_read; - } - } - - if ((handle->response.msg.entity_offset + *size) > handle->response.msg.entity.length) { - *size = handle->response.msg.entity.length - handle->response.msg.entity_offset; - } - - memcpy(buf, - &handle->response.msg.msg.buf[handle->response.entity_start_position], - *size); - if (*size > 0) { - membuffer_delete(&handle->response.msg.msg, - handle->response.entity_start_position, - *size); - } - - handle->response.msg.entity_offset += *size; - if (handle->cancel) { - return UPNP_E_CANCELED; - } - - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; } /************************************************************************ @@ -1571,18 +1448,15 @@ int http_HttpGetProgress( * UPNP_E_SUCCESS - On Success * UPNP_E_INVALID_PARAM - Invalid Parameter ************************************************************************/ -int -http_CancelHttpGet( IN void *Handle ) +int http_CancelHttpGet(IN void *Handle) { - http_get_handle_t *handle = Handle; + http_get_handle_t *handle = Handle; - if( !handle ) { - return UPNP_E_INVALID_PARAM; - } + if (!handle) + return UPNP_E_INVALID_PARAM; + handle->cancel = 1; - handle->cancel = 1; - - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; } @@ -1600,94 +1474,38 @@ http_CancelHttpGet( IN void *Handle ) * UPNP_E_SUCCESS - On Success * UPNP_E_INVALID_PARAM - Invalid Parameter ************************************************************************/ -int -http_CloseHttpGet( IN void *Handle ) +int http_CloseHttpGet(IN void *Handle) { - http_get_handle_t *handle = Handle; + http_get_handle_t *handle = Handle; - if( !handle ) { - return UPNP_E_INVALID_PARAM; - } + if (!handle) + return UPNP_E_INVALID_PARAM; + /*should shutdown completely */ + sock_destroy(&handle->sock_info, SD_BOTH); + httpmsg_destroy(&handle->response.msg); + free(handle); - sock_destroy( &handle->sock_info, SD_BOTH ); /*should shutdown completely */ - httpmsg_destroy( &handle->response.msg ); - free( handle ); - return UPNP_E_SUCCESS; + return UPNP_E_SUCCESS; } -/************************************************************************ - * Function: http_OpenHttpGet - * - * Parameters: - * IN const char *url_str: String as a URL - * IN OUT void **Handle: Pointer to buffer to store HTTP - * post handle - * IN OUT char **contentType: Type of content - * OUT int *contentLength: length of content - * OUT int *httpStatus: HTTP status returned on receiving a - * response message - * IN int timeout: time out value - * - * Description: - * Makes the HTTP GET message, connects to the peer, - * sends the HTTP GET request, gets the response and parses the - * response. - * - * Return: int - * UPNP_E_SUCCESS - On Success - * UPNP_E_INVALID_PARAM - Invalid Paramters - * UPNP_E_OUTOF_MEMORY - * UPNP_E_SOCKET_ERROR - * UPNP_E_BAD_RESPONSE - ************************************************************************/ -int -http_OpenHttpGet( IN const char *url_str, +int http_OpenHttpGet( IN const char *url_str, IN OUT void **Handle, IN OUT char **contentType, OUT int *contentLength, OUT int *httpStatus, - IN int timeout ) + IN int timeout) { - return http_OpenHttpGetProxy(url_str, NULL, Handle, contentType, contentLength, httpStatus, timeout); + return http_OpenHttpGetProxy( + url_str, NULL, Handle, contentType, contentLength, httpStatus, + timeout); } -/************************************************************************ - * Function: http_OpenHttpGetProxy - * - * Parameters: - * IN const char *url_str; String as a URL - * IN const char *proxy_str; String as a URL - * IN OUT void **Handle; Pointer to buffer to store HTTP - * post handle - * IN OUT char **contentType; Type of content - * OUT int *contentLength; length of content - * OUT int *httpStatus; HTTP status returned on receiving a - * response message - * IN int timeout: time out value - * - * Description: - * Makes the HTTP GET message, connects to the peer, - * sends the HTTP GET request, gets the response and parses the response. - * If a proxy URL is defined then the connection is made there. - * - * Return: int - * UPNP_E_SUCCESS - On Success - * UPNP_E_INVALID_PARAM - Invalid Paramters - * UPNP_E_OUTOF_MEMORY - * UPNP_E_SOCKET_ERROR - * UPNP_E_BAD_RESPONSE - ************************************************************************/ -int http_OpenHttpGetProxy( - IN const char *url_str, - IN const char *proxy_str, - IN OUT void **Handle, - IN OUT char **contentType, - OUT int *contentLength, - OUT int *httpStatus, - IN int timeout) +int http_OpenHttpGetProxy(const char *url_str, const char *proxy_str, + void **Handle, char **contentType, int *contentLength, + int *httpStatus, int timeout) { int ret_code; - int sockaddr_len; + size_t sockaddr_len; int http_error_code; memptr ctype; SOCKET tcp_connection; @@ -1698,32 +1516,30 @@ int http_OpenHttpGetProxy( uri_type *peer; parse_status_t status; - if (!url_str || !Handle || !contentType || !httpStatus ) { + if (!url_str || !Handle || !contentType || !httpStatus) return UPNP_E_INVALID_PARAM; - } - *httpStatus = 0; *Handle = handle; *contentType = NULL; *contentLength = 0; - ret_code = MakeGetMessage(url_str, proxy_str, &request, &url); - if (ret_code != UPNP_E_SUCCESS) { + if (ret_code != UPNP_E_SUCCESS) return ret_code; - } if (proxy_str) { - ret_code = http_FixStrUrl((char *)proxy_str, strlen(proxy_str), &proxy); + ret_code = + http_FixStrUrl((char *)proxy_str, strlen(proxy_str), + &proxy); peer = &proxy; } else { peer = &url; } - handle = (http_get_handle_t *)malloc(sizeof(http_get_handle_t)); - if (!handle) { + handle = malloc(sizeof(http_get_handle_t)); + if (!handle) return UPNP_E_OUTOF_MEMORY; - } handle->cancel = 0; parser_response_init(&handle->response, HTTPMETHOD_GET); - tcp_connection = socket(peer->hostport.IPaddress.ss_family, SOCK_STREAM, 0); + tcp_connection = + socket(peer->hostport.IPaddress.ss_family, SOCK_STREAM, 0); if (tcp_connection == -1) { ret_code = UPNP_E_SOCKET_ERROR; goto errorHandler; @@ -1734,9 +1550,10 @@ int http_OpenHttpGetProxy( goto errorHandler; } sockaddr_len = peer->hostport.IPaddress.ss_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); + sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); ret_code = private_connect(handle->sock_info.socket, - (struct sockaddr *)&(peer->hostport.IPaddress), sockaddr_len); + (struct sockaddr *)&(peer->hostport.IPaddress), + (socklen_t) sockaddr_len); if (ret_code == -1) { sock_destroy(&handle->sock_info, SD_BOTH); ret_code = UPNP_E_SOCKET_CONNECT; @@ -1744,14 +1561,14 @@ int http_OpenHttpGetProxy( } /* send request */ ret_code = http_SendMessage(&handle->sock_info, &timeout, "b", - request.buf, request.length); + request.buf, request.length); if (ret_code) { sock_destroy(&handle->sock_info, SD_BOTH); goto errorHandler; } - status = ReadResponseLineAndHeaders(&handle->sock_info, - &handle->response, &timeout, &http_error_code); + &handle->response, &timeout, + &http_error_code); if (status != PARSE_OK) { ret_code = UPNP_E_BAD_RESPONSE; goto errorHandler; @@ -1761,33 +1578,27 @@ int http_OpenHttpGetProxy( ret_code = UPNP_E_BAD_RESPONSE; goto errorHandler; } - *httpStatus = handle->response.msg.status_code; ret_code = UPNP_E_SUCCESS; - - if (!httpmsg_find_hdr(&handle->response.msg, HDR_CONTENT_TYPE, &ctype)) { + if (!httpmsg_find_hdr(&handle->response.msg, HDR_CONTENT_TYPE, &ctype)) /* no content-type */ *contentType = NULL; - } else { + else *contentType = ctype.buf; - } - - if (handle->response.position == POS_COMPLETE) { + if (handle->response.position == POS_COMPLETE) *contentLength = 0; - } else if (handle->response.ent_position == ENTREAD_USING_CHUNKED) { + 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) { + else if (handle->response.ent_position == ENTREAD_USING_CLEN) + *contentLength = (int)handle->response.content_length; + else if (handle->response.ent_position == ENTREAD_UNTIL_CLOSE) *contentLength = UPNP_UNTIL_CLOSE; - } -errorHandler: + errorHandler: *Handle = handle; membuffer_destroy(&request); - if (ret_code != UPNP_E_SUCCESS) { + if (ret_code != UPNP_E_SUCCESS) httpmsg_destroy(&handle->response.msg); - } return ret_code; } @@ -1811,358 +1622,248 @@ errorHandler: * UPNP_E_SOCKET_WRITE * UPNP_E_TIMEDOUT ************************************************************************/ -int -http_SendStatusResponse( IN SOCKINFO * info, - IN int http_status_code, - IN int request_major_version, - IN int request_minor_version ) +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; + int response_major, response_minor; + membuffer membuf; + int ret; + int timeout; - http_CalcResponseVersion( request_major_version, request_minor_version, - &response_major, &response_minor ); + http_CalcResponseVersion(request_major_version, request_minor_version, + &response_major, &response_minor); + membuffer_init(&membuf); + membuf.size_inc = 70; + /* response start line */ + ret = http_MakeMessage(&membuf, response_major, response_minor, "RSCB", + http_status_code, http_status_code); + if (ret == 0) { + timeout = HTTP_DEFAULT_TIMEOUT; + ret = http_SendMessage(info, &timeout, "b", + membuf.buf, membuf.length); + } + membuffer_destroy(&membuf); - 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; + 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 - * 'L': arg = language information -- add Content-Language header if - * Accept-Language header is not empty and if - * WEB_SERVER_CONTENT_LANGUAGE is not empty - * '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 - ************************************************************************/ -int -http_MakeMessage( INOUT membuffer * buf, - IN int http_major_version, - IN int http_minor_version, - IN const char *fmt, - ... ) +int http_MakeMessage(membuffer *buf, int http_major_version, + int http_minor_version, 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; + 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; + const char *start_str; + const char *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_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))) + 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"))) + 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))) + 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)) + goto error_handler; + } else if (c == 'c') { + /* crlf */ + if (membuffer_append(buf, "\r\n", 2)) + goto error_handler; + } else if (c == 'd') { + /* integer */ + num = (size_t)va_arg(argp, int); + sprintf(tempbuf, "%" PRIzu, num); + if (membuffer_append(buf, tempbuf, strlen(tempbuf))) + 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))) + 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))) + goto error_handler; + } else if (c == 'L') { + /* Add CONTENT-LANGUAGE header only if WEB_SERVER_CONTENT_LANGUAGE */ + /* is not empty and if Accept-Language header is not empty */ + struct SendInstruction *RespInstr; + RespInstr = (struct SendInstruction *) + va_arg(argp, struct SendInstruction *); + assert(RespInstr); + if (strcmp(RespInstr->AcceptLanguageHeader, "") && + strcmp(WEB_SERVER_CONTENT_LANGUAGE, "") && + http_MakeMessage(buf, http_major_version, + http_minor_version, "ssc", + "CONTENT-LANGUAGE: ", + WEB_SERVER_CONTENT_LANGUAGE) != 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")) + 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", + "

", + status_code, http_get_code_text(status_code), + "

"); + bignum = (off_t)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); + } + } - va_start( argp, fmt ); + return 0; - 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 == 'L' ) { - /* Add CONTENT-LANGUAGE header only if WEB_SERVER_CONTENT_LANGUAGE */ - /* is not empty and if Accept-Language header is not empty */ - struct SendInstruction *RespInstr; - RespInstr = (struct SendInstruction *) - va_arg( argp, struct SendInstruction *); - assert( RespInstr ); - if (strcmp( RespInstr->AcceptLanguageHeader, "" ) && - strcmp( WEB_SERVER_CONTENT_LANGUAGE, "" ) && http_MakeMessage( - buf, http_major_version, http_minor_version, - "ssc", - "CONTENT-LANGUAGE: ", WEB_SERVER_CONTENT_LANGUAGE ) != 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", - "

", - status_code, http_get_code_text( status_code ), - "

" ); - 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; + error_handler: + va_end(argp); + membuffer_destroy(buf); + return error_code; } @@ -2180,21 +1881,19 @@ error_handler: * * Return: void ************************************************************************/ -void -http_CalcResponseVersion( IN int request_major_vers, +void http_CalcResponseVersion( IN int request_major_vers, IN int request_minor_vers, OUT int *response_major_vers, - OUT int *response_minor_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; - } + 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; + } } /************************************************************************ @@ -2214,78 +1913,67 @@ http_CalcResponseVersion( IN int request_major_vers, * Error Codes returned by http_MakeMessage * UPNP_E_SUCCESS ************************************************************************/ -int -MakeGetMessageEx( const char *url_str, +int MakeGetMessageEx( const char *url_str, membuffer * request, uri_type * url, - struct SendInstruction *pRangeSpecifier ) + struct SendInstruction *pRangeSpecifier) { - int errCode = UPNP_E_SUCCESS; - char *urlPath = NULL; - size_t hostlen = 0; - char *hoststr, - *temp; + int errCode = UPNP_E_SUCCESS; + char *urlPath = NULL; + size_t hostlen = 0; + char *hoststr, *temp; - do { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "DOWNLOAD URL : %s\n", url_str ); + do { + 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); + *temp = '/'; + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HOSTNAME : %s Length : %" PRIzu "\n", + hoststr, hostlen); + errCode = http_MakeMessage(request, 1, 1, + "Q" "s" "bc" "GDCUc", + HTTPMETHOD_GET, url->pathquery.buff, + url->pathquery.size, "HOST: ", + hoststr, hostlen, pRangeSpecifier); + if (errCode != 0) { + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Makemessage failed\n"); + membuffer_destroy(request); + return errCode; + } + } while (0); + UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, + "HTTP Buffer:\n%s\n" "----------END--------\n", + request->buf); - 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 ); - *temp = '/'; - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HOSTNAME : %s Length : %"PRIzu"\n", - hoststr, hostlen ); - - errCode = http_MakeMessage( - request, 1, 1, - "Q" "s" "bc" "GDCUc", - HTTPMETHOD_GET, url->pathquery.buff, url->pathquery.size, - "HOST: ", - hoststr, hostlen, - pRangeSpecifier ); - - if( errCode != 0 ) { - UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Makemessage failed\n" ); - membuffer_destroy( request ); - - return errCode; - } - } while( 0 ); - - UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__, - "HTTP Buffer:\n%s\n" "----------END--------\n", - request->buf); - - return errCode; + return errCode; } #define SIZE_RANGE_BUFFER 50 @@ -2328,7 +2016,7 @@ int http_OpenHttpGetEx( int http_error_code; memptr ctype; SOCKET tcp_connection; - int sockaddr_len; + size_t sockaddr_len; membuffer request; http_get_handle_t *handle = NULL; uri_type url; @@ -2343,13 +2031,11 @@ int http_OpenHttpGetEx( errCode = UPNP_E_INVALID_PARAM; break; } - /* Initialize output parameters */ *httpStatus = 0; *Handle = handle; *contentType = NULL; *contentLength = 0; - if (lowRange > highRange) { errCode = UPNP_E_INTERNAL_ERROR; break; @@ -2359,9 +2045,8 @@ int http_OpenHttpGetEx( "Range: bytes=%d-%d\r\n", lowRange, highRange); membuffer_init(&request); errCode = MakeGetMessageEx(url_str, &request, &url, &rangeBuf); - if (errCode != UPNP_E_SUCCESS) { + if (errCode != UPNP_E_SUCCESS) break; - } handle = (http_get_handle_t *)malloc(sizeof(http_get_handle_t)); if (!handle) { errCode = UPNP_E_OUTOF_MEMORY; @@ -2384,7 +2069,8 @@ int http_OpenHttpGetEx( sockaddr_len = url.hostport.IPaddress.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); errCode = private_connect(handle->sock_info.socket, - (struct sockaddr *)&(url.hostport.IPaddress), sockaddr_len); + (struct sockaddr *)&(url.hostport.IPaddress), + (socklen_t)sockaddr_len); if (errCode == -1) { sock_destroy(&handle->sock_info, SD_BOTH); errCode = UPNP_E_SOCKET_CONNECT; @@ -2415,21 +2101,19 @@ int http_OpenHttpGetEx( *httpStatus = handle->response.msg.status_code; errCode = UPNP_E_SUCCESS; - if (!httpmsg_find_hdr(&handle->response.msg, HDR_CONTENT_TYPE, &ctype)) { + if (!httpmsg_find_hdr(&handle->response.msg, HDR_CONTENT_TYPE, &ctype)) /* no content-type */ *contentType = NULL; - } else { + else *contentType = ctype.buf; - } - if (handle->response.position == POS_COMPLETE) { + if (handle->response.position == POS_COMPLETE) *contentLength = 0; - } else if(handle->response.ent_position == ENTREAD_USING_CHUNKED) { + 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) { + else if(handle->response.ent_position == ENTREAD_USING_CLEN) + *contentLength = (int)handle->response.content_length; + else if(handle->response.ent_position == ENTREAD_UNTIL_CLOSE) *contentLength = UPNP_UNTIL_CLOSE; - } *Handle = handle; } while (0); @@ -2452,36 +2136,30 @@ int http_OpenHttpGetEx( * UPNP_INLINE void ************************************************************************/ /* 'info' should have a size of at least 100 bytes */ -void -get_sdk_info( OUT char *info ) +void get_sdk_info(OUT char *info) { #ifdef WIN32 - OSVERSIONINFO versioninfo; - versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + OSVERSIONINFO versioninfo; + versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&versioninfo)!=0) { - sprintf( info, - "%d.%d.%d %d/%s, UPnP/1.0, Portable SDK for UPnP devices/"PACKAGE_VERSION"\r\n", - versioninfo.dwMajorVersion, - versioninfo.dwMinorVersion, - versioninfo.dwBuildNumber, - versioninfo.dwPlatformId, - versioninfo.szCSDVersion ); - } else { - *info = '\0'; - } + if (GetVersionEx(&versioninfo) != 0) + sprintf(info, + "%d.%d.%d %d/%s, UPnP/1.0, Portable SDK for UPnP devices/" + PACKAGE_VERSION "\r\n", versioninfo.dwMajorVersion, + versioninfo.dwMinorVersion, versioninfo.dwBuildNumber, + versioninfo.dwPlatformId, versioninfo.szCSDVersion); + else + *info = '\0'; #else - int ret_code; - struct utsname sys_info; + int ret_code; + struct utsname sys_info; - ret_code = uname( &sys_info ); - if( ret_code == -1 ) { - *info = '\0'; - } - sprintf( info, - "%s/%s, UPnP/1.0, Portable SDK for UPnP devices/"PACKAGE_VERSION "\r\n", - sys_info.sysname, - sys_info.release ); + ret_code = uname(&sys_info); + if (ret_code == -1) + *info = '\0'; + sprintf(info, + "%s/%s, UPnP/1.0, Portable SDK for UPnP devices/" + PACKAGE_VERSION "\r\n", sys_info.sysname, sys_info.release); #endif } diff --git a/upnp/src/genlib/net/http/webserver.c b/upnp/src/genlib/net/http/webserver.c index 32fe51d..d1aaef6 100644 --- a/upnp/src/genlib/net/http/webserver.c +++ b/upnp/src/genlib/net/http/webserver.c @@ -397,8 +397,8 @@ static void alias_release( ithread_mutex_unlock(&gWebMutex); return; } - assert(alias->ct > 0); - *alias->ct = *alias->ct - 1; + assert(*alias->ct > 0); + *alias->ct -= 1; if (*alias->ct <= 0) { membuffer_destroy(&alias->doc); membuffer_destroy(&alias->name); diff --git a/upnp/src/genlib/net/sock.c b/upnp/src/genlib/net/sock.c index 356a678..5057a64 100644 --- a/upnp/src/genlib/net/sock.c +++ b/upnp/src/genlib/net/sock.c @@ -107,7 +107,7 @@ static int sock_read_write( /*! Buffer to get data to or send data from. */ OUT char *buffer, /*! Size of the buffer. */ - IN size_t bufsize, + IN int bufsize, /*! timeout value. */ IN int *timeoutSecs, /*! Boolean value specifying read or write option. */ @@ -120,36 +120,34 @@ static int sock_read_write( long numBytes; time_t start_time = time(NULL); SOCKET sockfd = info->socket; - long bytes_sent = 0, byte_left = 0, num_written; + long bytes_sent = 0; + long byte_left = 0; + long num_written; FD_ZERO(&readSet); FD_ZERO(&writeSet); - if (bRead) { + if (bRead) FD_SET(sockfd, &readSet); - } else { + else FD_SET(sockfd, &writeSet); - } timeout.tv_sec = *timeoutSecs; timeout.tv_usec = 0; while (TRUE) { - if (*timeoutSecs < 0) { + if (*timeoutSecs < 0) retCode = select(sockfd + 1, &readSet, &writeSet, NULL, NULL); - } else { + else retCode = select(sockfd + 1, &readSet, &writeSet, NULL, &timeout); - } - if (retCode == 0) { + if (retCode == 0) return UPNP_E_TIMEDOUT; - } if (retCode == -1) { if (errno == EINTR) continue; return UPNP_E_SOCKET_ERROR; - } else { + } else /* read or write. */ break; - } } #ifdef SO_NOSIGPIPE { @@ -161,21 +159,21 @@ static int sock_read_write( #endif if (bRead) { /* read data. */ - numBytes = (long)recv(sockfd, buffer, bufsize, MSG_NOSIGNAL); + numBytes = (long)recv(sockfd, buffer, (size_t)bufsize, MSG_NOSIGNAL); } else { byte_left = bufsize; bytes_sent = 0; while (byte_left > 0) { /* write data. */ num_written = send(sockfd, - buffer + bytes_sent, byte_left, + buffer + bytes_sent, (size_t)byte_left, MSG_DONTROUTE | MSG_NOSIGNAL); if (num_written == -1) { #ifdef SO_NOSIGPIPE setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen); #endif - return num_written; + return (int)num_written; } byte_left = byte_left - num_written; bytes_sent += num_written; @@ -186,26 +184,24 @@ static int sock_read_write( setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen); } #endif - if (numBytes < 0) { + if (numBytes < 0) return UPNP_E_SOCKET_ERROR; - } /* subtract time used for reading/writing. */ - if (*timeoutSecs != 0) { - *timeoutSecs -= time(NULL) - start_time; - } + if (*timeoutSecs != 0) + *timeoutSecs -= (int)(time(NULL) - start_time); - return numBytes; + return (int)numBytes; } -int sock_read(IN SOCKINFO *info, OUT char *buffer, IN size_t bufsize, +int sock_read(IN SOCKINFO *info, OUT char *buffer, IN int bufsize, INOUT int *timeoutSecs) { return sock_read_write(info, buffer, bufsize, timeoutSecs, TRUE); } -int sock_write(IN SOCKINFO *info, IN char *buffer, IN size_t bufsize, +int sock_write(IN SOCKINFO *info, IN const char *buffer, IN int bufsize, INOUT int *timeoutSecs) { - return sock_read_write(info, buffer, bufsize, timeoutSecs, FALSE); + return sock_read_write(info, (char *)buffer, bufsize, timeoutSecs, FALSE); } diff --git a/upnp/src/genlib/net/uri/uri.c b/upnp/src/genlib/net/uri/uri.c index 89fa47c..1491351 100644 --- a/upnp/src/genlib/net/uri/uri.c +++ b/upnp/src/genlib/net/uri/uri.c @@ -271,197 +271,170 @@ void print_uri(uri_type *in) #ifdef DEBUG void print_token(token * in) { - int i = 0; - printf( "Token Size : %"PRIzu"\n\'", in->size ); - for( i = 0; i < in->size; i++ ) { - putchar( in->buff[i] ); - } - putchar( '\'' ); - putchar( '\n' ); + size_t i = 0; + + printf("Token Size : %" PRIzu "\n\'", in->size); + for (i = 0; i < in->size; i++) + putchar(in->buff[i]); + putchar('\''); + putchar('\n'); } #endif /* DEBUG */ -int token_string_casecmp(token *in1, char *in2) +int token_string_casecmp(token *in1, const char *in2) { size_t in2_length = strlen(in2); - - if (in1->size != in2_length) { + if (in1->size != in2_length) return 1; - } else { + else return strncasecmp(in1->buff, in2, in1->size); - } } int token_string_cmp(token * in1, char *in2) { size_t in2_length = strlen(in2); - - if (in1->size != in2_length) { + if (in1->size != in2_length) return 1; - } else { + else return strncmp(in1->buff, in2, in1->size); - } } - int token_cmp(token *in1, token *in2) { - if (in1->size != in2->size) { + if (in1->size != in2->size) return 1; - } else { + else return memcmp(in1->buff, in2->buff, in1->size); - } } - int parse_hostport( const char *in, size_t max, hostport_type *out) { - char workbuf[256]; - char* c; - struct sockaddr_in* sai4 = (struct sockaddr_in*)&out->IPaddress; - struct sockaddr_in6* sai6 = (struct sockaddr_in6*)&out->IPaddress; - char *srvname = NULL; - char *srvport = NULL; - char *last_dot = NULL; - unsigned short int port; - int af = AF_UNSPEC; - int hostport_size; - int has_port = 0; - int ret; + char workbuf[256]; + char *c; + struct sockaddr_in *sai4 = (struct sockaddr_in *)&out->IPaddress; + struct sockaddr_in6 *sai6 = (struct sockaddr_in6 *)&out->IPaddress; + char *srvname = NULL; + char *srvport = NULL; + char *last_dot = NULL; + unsigned short int port; + int af = AF_UNSPEC; + size_t hostport_size; + int has_port = 0; + int ret; - memset( out, 0, sizeof(hostport_type) ); + memset(out, 0, sizeof(hostport_type)); + /* Work on a copy of the input string. */ + strncpy(workbuf, in, sizeof(workbuf)); + c = workbuf; + if (*c == '[') { + /* IPv6 addresses are enclosed in square brackets. */ + srvname = ++c; + while (*c != '\0' && *c != ']') + c++; + if (*c == '\0') + /* did not find closing bracket. */ + return UPNP_E_INVALID_URL; + /* NULL terminate the srvname and then increment c. */ + *c++ = '\0'; /* overwrite the ']' */ + if (*c == ':') { + has_port = 1; + c++; + } + af = AF_INET6; + } else { + /* IPv4 address -OR- host name. */ + srvname = c; + while (*c != ':' && *c != '/' && + (isalnum(*c) || *c == '.' || *c == '-')) { + if (*c == '.') + last_dot = c; + c++; + } + has_port = (*c == ':') ? 1 : 0; + /* NULL terminate the srvname */ + *c = '\0'; + if (has_port == 1) + c++; + if (last_dot != NULL && isdigit(*(last_dot + 1))) + /* Must be an IPv4 address. */ + af = AF_INET; + else { + /* Must be a host name. */ + struct addrinfo hints, *res, *res0; - /* Work on a copy of the input string. */ - strncpy( workbuf, in, sizeof(workbuf) ); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - c = workbuf; - if( *c == '[' ) { - /* IPv6 addresses are enclosed in square brackets. */ - srvname = ++c; - while( *c != '\0' && *c != ']' ) { - c++; - } - if( *c == '\0' ) { - /* did not find closing bracket. */ - return UPNP_E_INVALID_URL; - } - /* NULL terminate the srvname and then increment c. */ - *c++ = '\0'; /* overwrite the ']' */ - if( *c == ':' ) { - has_port = 1; - c++; - } - af = AF_INET6; - } - else { - /* IPv4 address -OR- host name. */ - srvname = c; - while( (*c != ':') && (*c != '/') && ( (isalnum(*c)) || (*c == '.') || (*c == '-') ) ) { - if( *c == '.' ) - last_dot = c; - c++; - } - has_port = (*c == ':') ? 1 : 0; - /* NULL terminate the srvname */ - *c = '\0'; - if( has_port == 1 ) - c++; + ret = getaddrinfo(srvname, NULL, &hints, &res0); + if (ret == 0) { + for (res = res0; res; res = res->ai_next) { + if (res->ai_family == AF_INET || + res->ai_family == AF_INET6) { + /* Found a valid IPv4 or IPv6 address. */ + memcpy(&out->IPaddress, + res->ai_addr, + res->ai_addrlen); + break; + } + } + freeaddrinfo(res0); + if (res == NULL) + /* Didn't find an AF_INET or AF_INET6 address. */ + return UPNP_E_INVALID_URL; + } else + /* getaddrinfo failed. */ + return UPNP_E_INVALID_URL; + } + } + /* Check if a port is specified. */ + if (has_port == 1) { + /* Port is specified. */ + srvport = c; + while (*c != '\0' && isdigit(*c)) + c++; + port = (unsigned short int)atoi(srvport); + if (port == 0) + /* Bad port number. */ + return UPNP_E_INVALID_URL; + } else + /* Port was not specified, use default port. */ + port = 80; + /* The length of the host and port string can be calculated by */ + /* subtracting pointers. */ + hostport_size = (size_t)(c - workbuf); + /* Fill in the 'out' information. */ + if (af == AF_INET) { + sai4->sin_family = AF_INET; + sai4->sin_port = htons(port); + ret = inet_pton(AF_INET, srvname, &sai4->sin_addr); + } else if (af == AF_INET6) { + sai6->sin6_family = AF_INET6; + sai6->sin6_port = htons(port); + sai6->sin6_scope_id = gIF_INDEX; + ret = inet_pton(AF_INET6, srvname, &sai6->sin6_addr); + } else { + /* IP address was set by the hostname (getaddrinfo). */ + /* Override port: */ + if (out->IPaddress.ss_family == AF_INET) + sai4->sin_port = htons(port); + else + sai6->sin6_port = htons(port); + ret = 1; + } + /* Check if address was converted successfully. */ + if (ret <= 0) + return UPNP_E_INVALID_URL; + out->text.size = hostport_size; + out->text.buff = in; - if( last_dot != NULL && isdigit(*(last_dot+1)) ) { - /* Must be an IPv4 address. */ - af = AF_INET; - } - else { - /* Must be a host name. */ - struct addrinfo hints, *res, *res0; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - ret = getaddrinfo(srvname, NULL, &hints, &res0); - if( ret == 0 ) { - for (res = res0; res; res = res->ai_next) { - if( res->ai_family == AF_INET || - res->ai_family == AF_INET6 ) { - /* Found a valid IPv4 or IPv6 address. */ - memcpy( &out->IPaddress, res->ai_addr, - res->ai_addrlen ); - break; - } - } - freeaddrinfo(res0); - - if( res == NULL ) { - /* Didn't find an AF_INET or AF_INET6 address. */ - return UPNP_E_INVALID_URL; - } - } - else { - /* getaddrinfo failed. */ - return UPNP_E_INVALID_URL; - } - } - } - - /* Check if a port is specified. */ - if( has_port == 1 ) { - /* Port is specified. */ - srvport = c; - while( *c != '\0' && isdigit(*c) ) { - c++; - } - port = (unsigned short int)atoi(srvport); - if( port == 0 ) { - /* Bad port number. */ - return UPNP_E_INVALID_URL; - } - } - else { - /* Port was not specified, use default port. */ - port = 80; - } - - /* The length of the host and port string can be calculated by */ - /* subtracting pointers. */ - hostport_size = (int)(c - workbuf); - - /* Fill in the 'out' information. */ - if( af == AF_INET ) { - sai4->sin_family = AF_INET; - sai4->sin_port = htons(port); - ret = inet_pton(AF_INET, srvname, &sai4->sin_addr); - } - else if( af == AF_INET6 ) { - sai6->sin6_family = AF_INET6; - sai6->sin6_port = htons(port); - sai6->sin6_scope_id = gIF_INDEX; - ret = inet_pton(AF_INET6, srvname, &sai6->sin6_addr); - } else { - /* IP address was set by the hostname (getaddrinfo). */ - /* Override port: */ - if( out->IPaddress.ss_family == AF_INET ) - sai4->sin_port = htons(port); - else - sai6->sin6_port = htons(port); - ret = 1; - } - - /* Check if address was converted successfully. */ - if (ret <= 0) { - return UPNP_E_INVALID_URL; - } - - out->text.size = hostport_size; - out->text.buff = in; - - return hostport_size; - max = max; + return (int)hostport_size; + max = max; } /*! diff --git a/upnp/src/inc/httpreadwrite.h b/upnp/src/inc/httpreadwrite.h index 713d826..a05c7ca 100644 --- a/upnp/src/inc/httpreadwrite.h +++ b/upnp/src/inc/httpreadwrite.h @@ -206,7 +206,7 @@ int http_RequestAndResponse( * 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 size_t* doc_length; length of the extracted document * OUT char* content_type; Type of content * * Description: @@ -221,7 +221,7 @@ int http_Download( IN const char* url, IN int timeout_secs, OUT char** document, - OUT int* doc_length, + OUT size_t *doc_length, OUT char* content_type ); @@ -232,7 +232,7 @@ int http_Download( * IN void *Handle: Handle to the http post object * IN char *buf: Buffer to send to peer, if format used * is not UPNP_USING_CHUNKED, - * IN unsigned int *size: Size of the data to be sent. + * IN size_t *size: Size of the data to be sent. * IN int timeout: time out value * * Description: @@ -246,7 +246,7 @@ int http_Download( ************************************************************************/ int http_WriteHttpPost(IN void *Handle, IN char *buf, - IN unsigned int *size, + IN size_t *size, IN int timeout); @@ -350,7 +350,6 @@ int http_HttpGetProgress( OUT size_t *length, OUT size_t *total); - /************************************************************************ * Function: http_CloseHttpGet * @@ -367,74 +366,61 @@ int http_HttpGetProgress( ************************************************************************/ int http_CloseHttpGet(IN void *Handle); - -/************************************************************************ - * Function: http_OpenHttpGet +/*! + * \brief Makes the HTTP GET message, connects to the peer, + * sends the HTTP GET request, gets the response and parses the response. * - * Parameters: - * IN const char *url_str: String as a URL - * IN OUT void **Handle: Pointer to buffer to store HTTP - * post handle - * IN OUT char **contentType: Type of content - * OUT int *contentLength: length of content - * OUT int *httpStatus: HTTP status returned on receiving a - * response message - * IN int timeout: time out value + * If a proxy URL is defined then the connection is made there. * - * Description: - * Makes the HTTP GET message, connects to the peer, - * sends the HTTP GET request, gets the response and parses the - * response. - * - * Return: int - * UPNP_E_SUCCESS - On Success - * UPNP_E_INVALID_PARAM - Invalid Paramters - * UPNP_E_OUTOF_MEMORY - * UPNP_E_SOCKET_ERROR - * UPNP_E_BAD_RESPONSE - ************************************************************************/ + * \return integer + * \li \c UPNP_E_SUCCESS - On Success + * \li \c UPNP_E_INVALID_PARAM - Invalid Paramters + * \li \c UPNP_E_OUTOF_MEMORY + * \li \c UPNP_E_SOCKET_ERROR + * \li \c UPNP_E_BAD_RESPONSE + */ int http_OpenHttpGet( - IN const char *url_str, - IN OUT void **Handle, - IN OUT char **contentType, - OUT int *contentLength, - OUT int *httpStatus, - IN int timeout); + /* [in] String as a URL. */ + const char *url_str, + /* [in,out] Pointer to buffer to store HTTP post handle. */ + void **Handle, + /* [in,out] Type of content. */ + char **contentType, + /* [out] length of content. */ + int *contentLength, + /* [out] HTTP status returned on receiving a response message. */ + int *httpStatus, + /* [in] time out value. */ + int timeout); - -/************************************************************************ - * Function: http_OpenHttpGetProxy +/*! + * \brief Makes the HTTP GET message, connects to the peer, + * sends the HTTP GET request, gets the response and parses the response. * - * Parameters: - * IN const char *url_str; String as a URL - * IN const char *proxy_str; String as a URL - * IN OUT void **Handle; Pointer to buffer to store HTTP - * post handle - * IN OUT char **contentType; Type of content - * OUT int *contentLength; length of content - * OUT int *httpStatus; HTTP status returned on receiving a - * response message - * IN int timeout: time out value + * If a proxy URL is defined then the connection is made there. * - * Description: - * Makes the HTTP GET message, connects to the peer, - * sends the HTTP GET request, gets the response and parses the response. - * If a proxy URL is defined then the connection is made there. - * - * Return: int - * UPNP_E_SUCCESS - On Success - * UPNP_E_INVALID_PARAM - Invalid Paramters - * UPNP_E_OUTOF_MEMORY - * UPNP_E_SOCKET_ERROR - * UPNP_E_BAD_RESPONSE - ************************************************************************/ -int http_OpenHttpGetProxy(IN const char *url_str, - IN const char *proxy_str, - IN OUT void **Handle, - IN OUT char **contentType, - OUT int *contentLength, - OUT int *httpStatus, - IN int timeout); + * \return integer + * \li \c UPNP_E_SUCCESS - On Success + * \li \c UPNP_E_INVALID_PARAM - Invalid Paramters + * \li \c UPNP_E_OUTOF_MEMORY + * \li \c UPNP_E_SOCKET_ERROR + * \li \c UPNP_E_BAD_RESPONSE + */ +int http_OpenHttpGetProxy( + /* [in] String as a URL. */ + const char *url_str, + /* [in] String as a URL. */ + const char *proxy_str, + /* [in,out] Pointer to buffer to store HTTP post handle. */ + void **Handle, + /* [in,out] Type of content. */ + char **contentType, + /* [out] length of content. */ + int *contentLength, + /* [out] HTTP status returned on receiving a response message. */ + int *httpStatus, + /* [in] time out value. */ + int timeout); /************************************************************************ @@ -463,61 +449,55 @@ int http_SendStatusResponse( IN int request_major_version, IN int request_minor_version ); - -/************************************************************************ - * Function: http_MakeMessage +/*! + * \brief Generate an HTTP message based on the format that is specified in + * the input parameters. * - * 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 - * ...; +\verbatim +Format 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 + 'L': arg = language information -- add Content-Language header if Accept-Language header is not empty and if + WEB_SERVER_CONTENT_LANGUAGE is not empty + '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 +\endverbatim * - * 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 - ************************************************************************/ + * \return + * \li \c 0 - On Success + * \li \c UPNP_E_OUTOF_MEMORY + * \li \c UPNP_E_INVALID_URL + */ int http_MakeMessage( + /* [in,out] Buffer with the contents of the message. */ INOUT membuffer* buf, + /* [in] HTTP major version. */ IN int http_major_version, + /* [in] HTTP minor version. */ IN int http_minor_version, - IN const char* fmt, ... ); + /* [in] Pattern format. */ + IN const char* fmt, + /* [in] Format arguments. */ + ... ); /************************************************************************ diff --git a/upnp/src/inc/sock.h b/upnp/src/inc/sock.h index 7379384..2fbf75d 100644 --- a/upnp/src/inc/sock.h +++ b/upnp/src/inc/sock.h @@ -110,7 +110,7 @@ int sock_read( /*! Buffer to get data to. */ OUT char* buffer, /*! Size of the buffer. */ - IN size_t bufsize, + IN int bufsize, /*! timeout value. */ INOUT int *timeoutSecs); @@ -126,9 +126,9 @@ int sock_write( /*! Socket Information Object. */ IN SOCKINFO *info, /*! Buffer to send data from. */ - IN char* buffer, + IN const char *buffer, /*! Size of the buffer. */ - IN size_t bufsize, + IN int bufsize, /*! timeout value. */ INOUT int *timeoutSecs); diff --git a/upnp/src/inc/uri.h b/upnp/src/inc/uri.h index 8b3d055..857f53e 100644 --- a/upnp/src/inc/uri.h +++ b/upnp/src/inc/uri.h @@ -247,7 +247,7 @@ int token_string_casecmp( /*! [in] Token object whose buffer is to be compared. */ token *in1, /*! [in] String of characters to compare with. */ - char *in2); + const char *in2); /*! * \brief Compares a null terminated string to a token (exact). diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index 52b4560..1080bed 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -157,7 +157,6 @@ int AdvertiseAndReply( if (NumCopy != 0) imillisleep(SSDP_PAUSE); NumCopy++; - for (i = 0;; i++) { UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Entering new device list with i = %lu\n\n", i); @@ -168,31 +167,29 @@ int AdvertiseAndReply( break; } dbgStr = ixmlNode_getNodeName(tmpNode); - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Extracting device type once for %s\n", dbgStr); ixmlNodeList_free(nodeList); nodeList = ixmlElement_getElementsByTagName( (IXML_Element *)tmpNode, "deviceType"); - if (!nodeList) continue; - + if (!nodeList) + continue; UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Extracting UDN for %s\n", dbgStr); dbgStr = ixmlNode_getNodeName(tmpNode); - UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Extracting device type\n"); tmpNode2 = ixmlNodeList_item(nodeList, 0); - if (!tmpNode2) continue; - + if (!tmpNode2) + continue; textNode = ixmlNode_getFirstChild(tmpNode2); if (!textNode) continue; UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Extracting device type \n"); tmpStr = ixmlNode_getNodeValue(textNode); - if (!tmpStr) continue; - + if (!tmpStr) + continue; strcpy(devType, tmpStr); UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Extracting device type = %s\n", devType); @@ -201,7 +198,6 @@ int AdvertiseAndReply( "TempNode is NULL\n"); } dbgStr = ixmlNode_getNodeName(tmpNode); - UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Extracting UDN for %s\n", dbgStr); ixmlNodeList_free(nodeList); @@ -226,8 +222,8 @@ int AdvertiseAndReply( } tmpStr = ixmlNode_getNodeValue(textNode); if (!tmpStr) { - UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, - "UDN not found!\n"); + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, + __LINE__, "UDN not found!\n"); continue; } strcpy(UDNstr, tmpStr); @@ -237,11 +233,13 @@ int AdvertiseAndReply( /* send the device advertisement */ if (AdFlag == 1) { DeviceAdvertisement(devType, i == 0, - UDNstr, SInfo->DescURL, Exp, SInfo->DeviceAf ); + UDNstr, SInfo->DescURL, Exp, + SInfo->DeviceAf); } else { /* AdFlag == -1 */ DeviceShutdown(devType, i == 0, UDNstr, - SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf ); + SERVER, SInfo->DescURL, Exp, + SInfo->DeviceAf); } } else { switch (SearchType) { diff --git a/upnp/src/uuid/sysdep.c b/upnp/src/uuid/sysdep.c index a1762fc..2eae522 100644 --- a/upnp/src/uuid/sysdep.c +++ b/upnp/src/uuid/sysdep.c @@ -31,21 +31,19 @@ system dependent call to get IEEE node ID. This sample implementation generates a random node ID */ -void -get_ieee_node_identifier(uuid_node_t *node) +void get_ieee_node_identifier(uuid_node_t *node) { - unsigned char seed[16]; - static int inited = 0; - static uuid_node_t saved_node; + unsigned char seed[16]; + static int inited = 0; + static uuid_node_t saved_node; - if (!inited) { - get_random_info(seed); - seed[0] |= 0x80; - memcpy(&saved_node, seed, sizeof (uuid_node_t)); - inited = 1; - }; - - *node = saved_node; + if (!inited) { + get_random_info(seed); + seed[0] |= 0x80; + memcpy(&saved_node, seed, sizeof(uuid_node_t)); + inited = 1; + }; + *node = saved_node; }; /*-----------------------------------------------------------------------------*/ @@ -57,31 +55,25 @@ get_ieee_node_identifier(uuid_node_t *node) #ifdef WIN32 -void -get_system_time( uuid_time_t * uuid_time ) +void get_system_time(uuid_time_t *uuid_time) { - ULARGE_INTEGER time; - - GetSystemTimeAsFileTime( ( FILETIME * ) & time ); - - /* - NT keeps time in FILETIME format which is 100ns ticks since - Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. - The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) - + 18 years and 5 leap days. - */ - - time.QuadPart += ( unsigned __int64 )( 1000 * 1000 * 10 ) /* seconds */ - * ( unsigned __int64 )( 60 * 60 * 24 ) /* days */ - * ( unsigned __int64 )( 17 + 30 + 31 + 365 * 18 + 5 ); /* # of days */ - - *uuid_time = time.QuadPart; + ULARGE_INTEGER time; + GetSystemTimeAsFileTime((FILETIME *) & time); + /* + NT keeps time in FILETIME format which is 100ns ticks since + Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + + 18 years and 5 leap days. + */ + time.QuadPart += (unsigned __int64)(1000 * 1000 * 10) /* seconds */ + *(unsigned __int64)(60 * 60 * 24) /* days */ + *(unsigned __int64)(17 + 30 + 31 + 365 * 18 + 5); /* # of days */ + *uuid_time = time.QuadPart; }; /*-----------------------------------------------------------------------------*/ -void -get_random_info(char seed[16]) +void get_random_info(char seed[16]) { MD5_CTX c; typedef struct { @@ -121,25 +113,22 @@ get_random_info(char seed[16]) #else /* WIN32 */ /*-----------------------------------------------------------------------------*/ -void -get_system_time(uuid_time_t *uuid_time) +void get_system_time(uuid_time_t *uuid_time) { - struct timeval tp; + struct timeval tp; - gettimeofday( &tp, ( struct timezone * )0 ); - - /* - Offset between UUID formatted times and Unix formatted times. - UUID UTC base time is October 15, 1582. - Unix base time is January 1, 1970. - */ - *uuid_time = ( tp.tv_sec * 10000000 ) + ( tp.tv_usec * 10 ) + - I64( 0x01B21DD213814000 ); + gettimeofday(&tp, (struct timezone *)0); + /* + Offset between UUID formatted times and Unix formatted times. + UUID UTC base time is October 15, 1582. + Unix base time is January 1, 1970. + */ + *uuid_time = (uuid_time_t) (tp.tv_sec * 10000000 + tp.tv_usec * 10 + + I64(0x01B21DD213814000)); }; /*-----------------------------------------------------------------------------*/ -void -get_random_info(unsigned char seed[16]) +void get_random_info(unsigned char seed[16]) { MD5_CTX c; typedef struct {