In the latest sources, http_RequestAndResponse and other methods that

use connect() are broken. More specifically, connect() in these methods
is returning with an EINVAL. The programatic cause is that the address_len
argument passed to connect() is different in IPV4 vs IPV6 (as described in:
http://www.opengroup.org/onlinepubs/009695399/functions/connect.html).
The current code always uses the IPV6 size. The fix modifies each use of
connect() to use the correct size based on the address family being used.

Patch submitted by Chandra (inactiveneurons).
This commit is contained in:
Marcelo Roberto Jimenez 2010-09-07 21:34:16 -03:00
parent 97af8b6fdb
commit 21660334e4
2 changed files with 355 additions and 379 deletions

View File

@ -2,6 +2,17 @@
Version 1.6.7 Version 1.6.7
******************************************************************************* *******************************************************************************
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
In the latest sources, http_RequestAndResponse and other methods that
use connect() are broken. More specifically, connect() in these methods
is returning with an EINVAL. The programatic cause is that the address_len
argument passed to connect() is different in IPV4 vs IPV6 (as described in:
http://www.opengroup.org/onlinepubs/009695399/functions/connect.html).
The current code always uses the IPV6 size. The fix modifies each use of
connect() to use the correct size based on the address family being used.
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in upnp/src/gena/gena_ctrlpt.c (this is most Fix compilation error in upnp/src/gena/gena_ctrlpt.c (this is most
likely an error on all platforms). likely an error on all platforms).

View File

@ -176,11 +176,13 @@ http_FixStrUrl( IN const char *urlstr,
* UPNP_E_OUTOF_SOCKET * UPNP_E_OUTOF_SOCKET
* UPNP_E_SOCKET_CONNECT on error * UPNP_E_SOCKET_CONNECT on error
************************************************************************/ ************************************************************************/
int int http_Connect(
http_Connect( IN uri_type * destination_url, IN uri_type *destination_url,
OUT uri_type *url) OUT uri_type *url)
{ {
int connfd; int connfd;
int sockaddr_len;
int ret_connect;
http_FixUrl(destination_url, url); http_FixUrl(destination_url, url);
@ -188,9 +190,11 @@ http_Connect( IN uri_type * destination_url,
if (connfd == -1) { if (connfd == -1) {
return UPNP_E_OUTOF_SOCKET; return UPNP_E_OUTOF_SOCKET;
} }
sockaddr_len = url->hostport.IPaddress.ss_family == AF_INET6 ?
if( connect( connfd, ( struct sockaddr * )&url->hostport.IPaddress, sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
sizeof( url->hostport.IPaddress ) ) == -1 ) { ret_connect = connect(connfd,
(struct sockaddr *)&url->hostport.IPaddress, sockaddr_len);
if (ret_connect == -1) {
#ifdef WIN32 #ifdef WIN32
UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__, UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
"connect error: %d\n", WSAGetLastError()); "connect error: %d\n", WSAGetLastError());
@ -536,8 +540,8 @@ end:
* Error Codes returned by http_SendMessage * Error Codes returned by http_SendMessage
* Error Codes returned by http_RecvMessage * Error Codes returned by http_RecvMessage
************************************************************************/ ************************************************************************/
int int http_RequestAndResponse(
http_RequestAndResponse( IN uri_type * destination, IN uri_type *destination,
IN const char *request, IN const char *request,
IN size_t request_length, IN size_t request_length,
IN http_method_t req_method, IN http_method_t req_method,
@ -546,43 +550,45 @@ http_RequestAndResponse( IN uri_type * destination,
{ {
int tcp_connection; int tcp_connection;
int ret_code; int ret_code;
int sockaddr_len;
int http_error_code; int http_error_code;
SOCKINFO info; SOCKINFO info;
tcp_connection = socket( destination->hostport.IPaddress.ss_family, SOCK_STREAM, 0 ); tcp_connection = socket(
destination->hostport.IPaddress.ss_family, SOCK_STREAM, 0);
if (tcp_connection == -1) { if (tcp_connection == -1) {
parser_response_init(response, req_method); parser_response_init(response, req_method);
return UPNP_E_SOCKET_ERROR; return UPNP_E_SOCKET_ERROR;
} }
if( sock_init( &info, tcp_connection ) != UPNP_E_SUCCESS ) if (sock_init(&info, tcp_connection) != UPNP_E_SUCCESS) {
{
sock_destroy( &info, SD_BOTH );
parser_response_init(response, req_method); parser_response_init(response, req_method);
return UPNP_E_SOCKET_ERROR; ret_code = UPNP_E_SOCKET_ERROR;
goto end_function;
} }
// connect /* connect */
sockaddr_len = destination->hostport.IPaddress.ss_family == AF_INET6 ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
ret_code = connect(info.socket, ret_code = connect(info.socket,
( struct sockaddr * )&destination->hostport. (struct sockaddr *)&(destination->hostport.IPaddress), sockaddr_len);
IPaddress, sizeof( struct sockaddr_storage ) );
if (ret_code == -1) { if (ret_code == -1) {
sock_destroy( &info, SD_BOTH );
parser_response_init(response, req_method); parser_response_init(response, req_method);
return UPNP_E_SOCKET_CONNECT; ret_code = UPNP_E_SOCKET_CONNECT;
goto end_function;
} }
// send request /* send request */
ret_code = http_SendMessage(&info, &timeout_secs, "b", ret_code = http_SendMessage(&info, &timeout_secs, "b",
request, request_length); request, request_length);
if (ret_code != 0) { if (ret_code != 0) {
sock_destroy( &info, SD_BOTH );
parser_response_init(response, req_method); parser_response_init(response, req_method);
return ret_code; goto end_function;
} }
// recv response /* recv response */
ret_code = http_RecvMessage(&info, response, req_method, ret_code = http_RecvMessage(&info, response, req_method,
&timeout_secs, &http_error_code); &timeout_secs, &http_error_code);
sock_destroy( &info, SD_BOTH ); //should shutdown completely end_function:
/* should shutdown completely */
sock_destroy(&info, SD_BOTH);
return ret_code; return ret_code;
} }
@ -1000,63 +1006,56 @@ http_CloseHttpPost( IN void *Handle,
* UPNP_E_SOCKET_ERROR * UPNP_E_SOCKET_ERROR
* UPNP_E_SOCKET_CONNECT * UPNP_E_SOCKET_CONNECT
************************************************************************/ ************************************************************************/
int int http_OpenHttpPost(
http_OpenHttpPost( IN const char *url_str, IN const char *url_str,
IN OUT void **Handle, IN OUT void **Handle,
IN const char *contentType, IN const char *contentType,
IN int contentLength, IN int contentLength,
IN int timeout) IN int timeout)
{ {
int ret_code; int ret_code;
int sockaddr_len;
int tcp_connection; int tcp_connection;
membuffer request; membuffer request;
http_post_handle_t *handle = NULL; http_post_handle_t *handle = NULL;
uri_type url; uri_type url;
if( ( !url_str ) || ( !Handle ) || ( !contentType ) ) { if ( !url_str || !Handle || !contentType) {
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
} }
( *Handle ) = handle; *Handle = handle;
if( ( ret_code = ret_code = MakePostMessage(url_str, &request, &url,
MakePostMessage( url_str, &request, &url, contentLength, contentLength, contentType);
contentType ) ) != UPNP_E_SUCCESS ) { if (ret_code != UPNP_E_SUCCESS) {
return ret_code; return ret_code;
} }
handle = (http_post_handle_t *) malloc(sizeof(http_post_handle_t));
handle = if (!handle) {
( http_post_handle_t * ) malloc( sizeof( http_post_handle_t ) );
if( handle == NULL ) {
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
handle->contentLength = contentLength; 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) { if (tcp_connection == -1) {
ret_code = UPNP_E_SOCKET_ERROR; ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler; goto errorHandler;
} }
if (sock_init(&handle->sock_info, tcp_connection) != UPNP_E_SUCCESS) {
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; ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler; goto errorHandler;
} }
sockaddr_len = url.hostport.IPaddress.ss_family == AF_INET6 ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
ret_code = connect(handle->sock_info.socket, ret_code = connect(handle->sock_info.socket,
( struct sockaddr * )&url.hostport.IPaddress, (struct sockaddr *)&(url.hostport.IPaddress), sockaddr_len);
sizeof( struct sockaddr_storage ) );
if (ret_code == -1) { if (ret_code == -1) {
sock_destroy(&handle->sock_info, SD_BOTH); sock_destroy(&handle->sock_info, SD_BOTH);
ret_code = UPNP_E_SOCKET_CONNECT; ret_code = UPNP_E_SOCKET_CONNECT;
goto errorHandler; goto errorHandler;
} }
// send request /* send request */
ret_code = http_SendMessage(&handle->sock_info, &timeout, "b", ret_code = http_SendMessage(&handle->sock_info, &timeout, "b",
request.buf, request.length); request.buf, request.length);
if (ret_code != 0) { if (ret_code != 0) {
@ -1065,7 +1064,8 @@ http_OpenHttpPost( IN const char *url_str,
errorHandler: errorHandler:
membuffer_destroy(&request); membuffer_destroy(&request);
( *Handle ) = handle; *Handle = handle;
return ret_code; return ret_code;
} }
@ -1565,8 +1565,8 @@ http_OpenHttpGet( IN const char *url_str,
* UPNP_E_SOCKET_ERROR * UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE * UPNP_E_BAD_RESPONSE
************************************************************************/ ************************************************************************/
int int http_OpenHttpGetProxy(
http_OpenHttpGetProxy( IN const char *url_str, IN const char *url_str,
IN const char *proxy_str, IN const char *proxy_str,
IN OUT void **Handle, IN OUT void **Handle,
IN OUT char **contentType, IN OUT char **contentType,
@ -1575,6 +1575,7 @@ http_OpenHttpGetProxy( IN const char *url_str,
IN int timeout) IN int timeout)
{ {
int ret_code; int ret_code;
int sockaddr_len;
int http_error_code; int http_error_code;
memptr ctype; memptr ctype;
int tcp_connection; int tcp_connection;
@ -1585,18 +1586,17 @@ http_OpenHttpGetProxy( IN const char *url_str,
uri_type *peer; uri_type *peer;
parse_status_t status; parse_status_t status;
if( ( !url_str ) || ( !Handle ) || ( !contentType ) if (!url_str || !Handle || !contentType || !httpStatus ) {
|| ( !httpStatus ) ) {
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
} }
( *httpStatus ) = 0; *httpStatus = 0;
( *Handle ) = handle; *Handle = handle;
( *contentType ) = NULL; *contentType = NULL;
( *contentLength ) = 0; *contentLength = 0;
if( ( ret_code = ret_code = MakeGetMessage(url_str, proxy_str, &request, &url);
MakeGetMessage( url_str, proxy_str, &request, &url ) ) != UPNP_E_SUCCESS ) { if (ret_code != UPNP_E_SUCCESS) {
return ret_code; return ret_code;
} }
if (proxy_str) { if (proxy_str) {
@ -1605,89 +1605,75 @@ http_OpenHttpGetProxy( IN const char *url_str,
} else { } else {
peer = &url; peer = &url;
} }
handle = (http_get_handle_t *)malloc(sizeof(http_get_handle_t)); handle = (http_get_handle_t *)malloc(sizeof(http_get_handle_t));
if (!handle) {
if( handle == NULL ) {
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
handle->entity_offset = 0; handle->entity_offset = 0;
handle->cancel = 0; handle->cancel = 0;
parser_response_init(&handle->response, HTTPMETHOD_GET); 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) { if (tcp_connection == -1) {
ret_code = UPNP_E_SOCKET_ERROR; ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler; goto errorHandler;
} }
if (sock_init(&handle->sock_info, tcp_connection) != UPNP_E_SUCCESS) {
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; ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler; goto errorHandler;
} }
sockaddr_len = peer->hostport.IPaddress.ss_family == AF_INET6 ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
ret_code = connect(handle->sock_info.socket, ret_code = connect(handle->sock_info.socket,
( struct sockaddr * )&peer->hostport.IPaddress, (struct sockaddr *)&(peer->hostport.IPaddress), sockaddr_len);
sizeof( struct sockaddr_storage ) );
if (ret_code == -1) { if (ret_code == -1) {
sock_destroy(&handle->sock_info, SD_BOTH); sock_destroy(&handle->sock_info, SD_BOTH);
ret_code = UPNP_E_SOCKET_CONNECT; ret_code = UPNP_E_SOCKET_CONNECT;
goto errorHandler; goto errorHandler;
} }
// send request /* send request */
ret_code = http_SendMessage(&handle->sock_info, &timeout, "b", ret_code = http_SendMessage(&handle->sock_info, &timeout, "b",
request.buf, request.length); request.buf, request.length);
if( ret_code != 0 ) { if (ret_code) {
sock_destroy(&handle->sock_info, SD_BOTH); sock_destroy(&handle->sock_info, SD_BOTH);
goto errorHandler; goto errorHandler;
} }
status = status = ReadResponseLineAndHeaders(&handle->sock_info,
ReadResponseLineAndHeaders( &handle->sock_info, &handle->response, &handle->response, &timeout, &http_error_code);
&timeout, &http_error_code );
if (status != PARSE_OK) { if (status != PARSE_OK) {
ret_code = UPNP_E_BAD_RESPONSE; ret_code = UPNP_E_BAD_RESPONSE;
goto errorHandler; goto errorHandler;
} }
status = parser_get_entity_read_method(&handle->response); status = parser_get_entity_read_method(&handle->response);
if (status != PARSE_CONTINUE_1 && status != PARSE_SUCCESS) {
if( ( status != PARSE_CONTINUE_1 ) && ( status != PARSE_SUCCESS ) ) {
ret_code = UPNP_E_BAD_RESPONSE; ret_code = UPNP_E_BAD_RESPONSE;
goto errorHandler; goto errorHandler;
} }
( *httpStatus ) = handle->response.msg.status_code; *httpStatus = handle->response.msg.status_code;
ret_code = UPNP_E_SUCCESS; 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)) {
== NULL ) { /* no content-type */
*contentType = NULL; // no content-type *contentType = NULL;
} else { } else {
*contentType = ctype.buf; *contentType = ctype.buf;
} }
if (handle->response.position == POS_COMPLETE) { if (handle->response.position == POS_COMPLETE) {
( *contentLength ) = 0; *contentLength = 0;
} else if (handle->response.ent_position == ENTREAD_USING_CHUNKED) { } else if (handle->response.ent_position == ENTREAD_USING_CHUNKED) {
( *contentLength ) = UPNP_USING_CHUNKED; *contentLength = UPNP_USING_CHUNKED;
} else if (handle->response.ent_position == ENTREAD_USING_CLEN) { } else if (handle->response.ent_position == ENTREAD_USING_CLEN) {
( *contentLength ) = handle->response.content_length; *contentLength = handle->response.content_length;
} else if (handle->response.ent_position == ENTREAD_UNTIL_CLOSE) { } else if (handle->response.ent_position == ENTREAD_UNTIL_CLOSE) {
( *contentLength ) = UPNP_UNTIL_CLOSE; *contentLength = UPNP_UNTIL_CLOSE;
} }
errorHandler: errorHandler:
*Handle = handle;
( *Handle ) = handle;
membuffer_destroy(&request); membuffer_destroy(&request);
if (ret_code != UPNP_E_SUCCESS) { if (ret_code != UPNP_E_SUCCESS) {
httpmsg_destroy(&handle->response.msg); httpmsg_destroy(&handle->response.msg);
} }
@ -2201,8 +2187,8 @@ MakeGetMessageEx( const char *url_str,
* UPNP_E_SOCKET_ERROR * UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE * UPNP_E_BAD_RESPONSE
************************************************************************/ ************************************************************************/
int int http_OpenHttpGetEx(
http_OpenHttpGetEx( IN const char *url_str, IN const char *url_str,
IN OUT void **Handle, IN OUT void **Handle,
IN OUT char **contentType, IN OUT char **contentType,
OUT int *contentLength, OUT int *contentLength,
@ -2214,131 +2200,110 @@ http_OpenHttpGetEx( IN const char *url_str,
int http_error_code; int http_error_code;
memptr ctype; memptr ctype;
int tcp_connection; int tcp_connection;
int sockaddr_len;
membuffer request; membuffer request;
http_get_handle_t *handle = NULL; http_get_handle_t *handle = NULL;
uri_type url; uri_type url;
parse_status_t status; parse_status_t status;
int errCode = UPNP_E_SUCCESS; int errCode = UPNP_E_SUCCESS;
/* char rangeBuf[SIZE_RANGE_BUFFER]; */
// char rangeBuf[SIZE_RANGE_BUFFER];
struct SendInstruction rangeBuf; struct SendInstruction rangeBuf;
do { do {
// Checking Input parameters /* Checking Input parameters */
if( ( !url_str ) || ( !Handle ) || if (!url_str || !Handle || !contentType || !httpStatus ) {
( !contentType ) || ( !httpStatus ) ) {
errCode = UPNP_E_INVALID_PARAM; errCode = UPNP_E_INVALID_PARAM;
break; break;
} }
// Initialize output parameters
( *httpStatus ) = 0; /* Initialize output parameters */
( *Handle ) = handle; *httpStatus = 0;
( *contentType ) = NULL; *Handle = handle;
( *contentLength ) = 0; *contentType = NULL;
*contentLength = 0;
if (lowRange > highRange) { if (lowRange > highRange) {
errCode = UPNP_E_INTERNAL_ERROR; errCode = UPNP_E_INTERNAL_ERROR;
break; break;
} }
memset(&rangeBuf, 0, sizeof(rangeBuf)); memset(&rangeBuf, 0, sizeof(rangeBuf));
sprintf( rangeBuf.RangeHeader, "Range: bytes=%d-%d\r\n", sprintf(rangeBuf.RangeHeader,
lowRange, highRange ); "Range: bytes=%d-%d\r\n", lowRange, highRange);
membuffer_init(&request); membuffer_init(&request);
errCode = MakeGetMessageEx(url_str, &request, &url, &rangeBuf);
if( ( errCode = MakeGetMessageEx( url_str, if (errCode != UPNP_E_SUCCESS) {
&request, &url, &rangeBuf ) )
!= UPNP_E_SUCCESS ) {
break; break;
} }
handle = (http_get_handle_t *)malloc(sizeof(http_get_handle_t));
handle = if (!handle) {
( http_get_handle_t * ) malloc( sizeof( http_get_handle_t ) );
if( handle == NULL ) {
errCode = UPNP_E_OUTOF_MEMORY; errCode = UPNP_E_OUTOF_MEMORY;
break; break;
} }
memset(handle, 0, sizeof(*handle)); memset(handle, 0, sizeof(*handle));
handle->entity_offset = 0; handle->entity_offset = 0;
parser_response_init(&handle->response, HTTPMETHOD_GET); parser_response_init(&handle->response, HTTPMETHOD_GET);
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) { if (tcp_connection == -1) {
errCode = UPNP_E_SOCKET_ERROR; errCode = UPNP_E_SOCKET_ERROR;
free(handle); free(handle);
break; break;
} }
if (sock_init(&handle->sock_info, tcp_connection) != UPNP_E_SUCCESS) {
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);
errCode = UPNP_E_SOCKET_ERROR; errCode = UPNP_E_SOCKET_ERROR;
free(handle); free(handle);
break; break;
} }
sockaddr_len = url.hostport.IPaddress.ss_family == AF_INET6 ?
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
errCode = connect(handle->sock_info.socket, errCode = connect(handle->sock_info.socket,
( struct sockaddr * )&url.hostport.IPaddress, (struct sockaddr *)&(url.hostport.IPaddress), sockaddr_len);
sizeof( struct sockaddr_storage ) );
if (errCode == -1) { if (errCode == -1) {
sock_destroy(&handle->sock_info, SD_BOTH); sock_destroy(&handle->sock_info, SD_BOTH);
errCode = UPNP_E_SOCKET_CONNECT; errCode = UPNP_E_SOCKET_CONNECT;
free(handle); free(handle);
break; break;
} }
// send request /* send request */
errCode = http_SendMessage( &handle->sock_info, errCode = http_SendMessage(&handle->sock_info, &timeout,
&timeout,
"b", request.buf, request.length); "b", request.buf, request.length);
if (errCode != UPNP_E_SUCCESS) { if (errCode != UPNP_E_SUCCESS) {
sock_destroy(&handle->sock_info, SD_BOTH); sock_destroy(&handle->sock_info, SD_BOTH);
free(handle); free(handle);
break; break;
} }
status = ReadResponseLineAndHeaders(&handle->sock_info, status = ReadResponseLineAndHeaders(&handle->sock_info,
&handle->response, &handle->response, &timeout, &http_error_code);
&timeout, &http_error_code );
if (status != PARSE_OK) { if (status != PARSE_OK) {
errCode = UPNP_E_BAD_RESPONSE; errCode = UPNP_E_BAD_RESPONSE;
free(handle); free(handle);
break; break;
} }
status = parser_get_entity_read_method(&handle->response); status = parser_get_entity_read_method(&handle->response);
if( ( status != PARSE_CONTINUE_1 ) && ( status != PARSE_SUCCESS ) ) { if (status != PARSE_CONTINUE_1 && status != PARSE_SUCCESS) {
errCode = UPNP_E_BAD_RESPONSE; errCode = UPNP_E_BAD_RESPONSE;
free(handle); free(handle);
break; break;
} }
*httpStatus = handle->response.msg.status_code;
( *httpStatus ) = handle->response.msg.status_code;
errCode = UPNP_E_SUCCESS; errCode = UPNP_E_SUCCESS;
if( httpmsg_find_hdr( &handle->response.msg, if (!httpmsg_find_hdr(&handle->response.msg, HDR_CONTENT_TYPE, &ctype)) {
HDR_CONTENT_TYPE, &ctype ) == NULL ) { /* no content-type */
*contentType = NULL; // no content-type *contentType = NULL;
} else { } else {
*contentType = ctype.buf; *contentType = ctype.buf;
} }
if (handle->response.position == POS_COMPLETE) { if (handle->response.position == POS_COMPLETE) {
( *contentLength ) = 0; *contentLength = 0;
} else if(handle->response.ent_position == ENTREAD_USING_CHUNKED) { } else if(handle->response.ent_position == ENTREAD_USING_CHUNKED) {
( *contentLength ) = UPNP_USING_CHUNKED; *contentLength = UPNP_USING_CHUNKED;
} else if(handle->response.ent_position == ENTREAD_USING_CLEN) { } else if(handle->response.ent_position == ENTREAD_USING_CLEN) {
( *contentLength ) = handle->response.content_length; *contentLength = handle->response.content_length;
} else if(handle->response.ent_position == ENTREAD_UNTIL_CLOSE) { } else if(handle->response.ent_position == ENTREAD_UNTIL_CLOSE) {
( *contentLength ) = UPNP_UNTIL_CLOSE; *contentLength = UPNP_UNTIL_CLOSE;
} }
*Handle = handle;
( *Handle ) = handle;
} while (0); } while (0);
membuffer_destroy(&request); membuffer_destroy(&request);