Fixes a bug introduced in a previous commit in http_SendMessage.
The variable num_read was beeing used without beeing initialized. Also, clean up the function return path and make sure va_end() is beeing called.
This commit is contained in:
@@ -418,51 +418,22 @@ ExitFunction:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int http_SendMessage(SOCKINFO *info, int *TimeOut, const char *fmt, ...)
|
||||||
/************************************************************************
|
|
||||||
* Function: http_SendMessage
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN SOCKINFO *info ; Socket information object
|
|
||||||
* IN OUT int * TimeOut ; time out value
|
|
||||||
* IN const char* fmt, ... Pattern format to take actions upon
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Sends a message to the destination based on the
|
|
||||||
* IN const char* fmt parameter
|
|
||||||
* fmt types:
|
|
||||||
* 'f': arg = const char * file name
|
|
||||||
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
|
|
||||||
* E.g.:
|
|
||||||
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
|
|
||||||
* char *filename = "foo.dat";
|
|
||||||
* int status = http_SendMessage( tcpsock, "mf",
|
|
||||||
* buf, strlen(buf),
|
|
||||||
* filename );
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* UPNP_E_OUTOF_MEMORY
|
|
||||||
* UPNP_E_FILE_READ_ERROR
|
|
||||||
* UPNP_E_SUCCESS
|
|
||||||
************************************************************************/
|
|
||||||
int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|
||||||
IN const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
FILE *Fp;
|
FILE *Fp;
|
||||||
va_list argp;
|
va_list argp;
|
||||||
struct SendInstruction *Instr = NULL;
|
struct SendInstruction *Instr = NULL;
|
||||||
size_t num_read;
|
|
||||||
size_t num_written;
|
|
||||||
int nr;
|
|
||||||
int nw;
|
|
||||||
int RetVal = 0;
|
|
||||||
char c;
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t buf_length;
|
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
char *file_buf = NULL;
|
char *file_buf = NULL;
|
||||||
char *ChunkBuf = NULL;
|
char *ChunkBuf = NULL;
|
||||||
char Chunk_Header[CHUNK_HEADER_SIZE];
|
char Chunk_Header[CHUNK_HEADER_SIZE];
|
||||||
|
char c;
|
||||||
|
int nw;
|
||||||
|
int RetVal = 0;
|
||||||
|
size_t buf_length;
|
||||||
|
size_t num_read;
|
||||||
|
size_t num_written;
|
||||||
size_t amount_to_be_read = 0;
|
size_t amount_to_be_read = 0;
|
||||||
/* 10 byte allocated for chunk header. */
|
/* 10 byte allocated for chunk header. */
|
||||||
size_t Data_Buf_Size = WEB_SERVER_BUF_SIZE;
|
size_t Data_Buf_Size = WEB_SERVER_BUF_SIZE;
|
||||||
@@ -471,9 +442,6 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|||||||
while ((c = *fmt++) != 0) {
|
while ((c = *fmt++) != 0) {
|
||||||
if (c == 'I') {
|
if (c == 'I') {
|
||||||
Instr = va_arg(argp, struct SendInstruction *);
|
Instr = va_arg(argp, struct SendInstruction *);
|
||||||
|
|
||||||
assert(Instr);
|
|
||||||
|
|
||||||
if (Instr->ReadSendSize >= 0)
|
if (Instr->ReadSendSize >= 0)
|
||||||
amount_to_be_read = (size_t)Instr->ReadSendSize;
|
amount_to_be_read = (size_t)Instr->ReadSendSize;
|
||||||
else
|
else
|
||||||
@@ -483,8 +451,10 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|||||||
ChunkBuf = malloc((size_t)
|
ChunkBuf = malloc((size_t)
|
||||||
(Data_Buf_Size + CHUNK_HEADER_SIZE +
|
(Data_Buf_Size + CHUNK_HEADER_SIZE +
|
||||||
CHUNK_TAIL_SIZE));
|
CHUNK_TAIL_SIZE));
|
||||||
if (!ChunkBuf)
|
if (!ChunkBuf) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
RetVal = UPNP_E_OUTOF_MEMORY;
|
||||||
|
goto ExitFunction;
|
||||||
|
}
|
||||||
file_buf = ChunkBuf + CHUNK_HEADER_SIZE;
|
file_buf = ChunkBuf + CHUNK_HEADER_SIZE;
|
||||||
} else if (c == 'f') {
|
} else if (c == 'f') {
|
||||||
/* file name */
|
/* file name */
|
||||||
@@ -494,32 +464,33 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|||||||
else
|
else
|
||||||
Fp = fopen(filename, "rb");
|
Fp = fopen(filename, "rb");
|
||||||
if (Fp == NULL) {
|
if (Fp == NULL) {
|
||||||
free(ChunkBuf);
|
RetVal = UPNP_E_FILE_READ_ERROR;
|
||||||
return UPNP_E_FILE_READ_ERROR;
|
goto ExitFunction;
|
||||||
}
|
}
|
||||||
if (Instr && Instr->IsRangeActive && Instr->IsVirtualFile) {
|
if (Instr && Instr->IsRangeActive && Instr->IsVirtualFile) {
|
||||||
if (virtualDirCallback.seek(Fp, Instr->RangeOffset,
|
if (virtualDirCallback.seek(Fp, Instr->RangeOffset,
|
||||||
SEEK_CUR) != 0) {
|
SEEK_CUR) != 0) {
|
||||||
free(ChunkBuf);
|
RetVal = UPNP_E_FILE_READ_ERROR;
|
||||||
return UPNP_E_FILE_READ_ERROR;
|
goto ExitFunction;
|
||||||
}
|
}
|
||||||
} else if (Instr && Instr->IsRangeActive) {
|
} else if (Instr && Instr->IsRangeActive) {
|
||||||
if (fseeko(Fp, Instr->RangeOffset, SEEK_CUR) != 0) {
|
if (fseeko(Fp, Instr->RangeOffset, SEEK_CUR) != 0) {
|
||||||
free(ChunkBuf);
|
RetVal = UPNP_E_FILE_READ_ERROR;
|
||||||
return UPNP_E_FILE_READ_ERROR;
|
goto ExitFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (amount_to_be_read) {
|
while (amount_to_be_read) {
|
||||||
if (Instr) {
|
if (Instr) {
|
||||||
|
int nr;
|
||||||
size_t n = amount_to_be_read >= Data_Buf_Size ?
|
size_t n = amount_to_be_read >= Data_Buf_Size ?
|
||||||
Data_Buf_Size : amount_to_be_read;
|
Data_Buf_Size : amount_to_be_read;
|
||||||
if (Instr->IsVirtualFile) {
|
if (Instr->IsVirtualFile) {
|
||||||
nr = virtualDirCallback.read(Fp, file_buf, n);
|
nr = virtualDirCallback.read(Fp, file_buf, n);
|
||||||
amount_to_be_read -= (size_t)nr;
|
num_read = (size_t)nr;
|
||||||
} else {
|
} else {
|
||||||
num_read = fread(file_buf, 1, n, Fp);
|
num_read = fread(file_buf, 1, n, Fp);
|
||||||
amount_to_be_read -= num_read;
|
|
||||||
}
|
}
|
||||||
|
amount_to_be_read -= num_read;
|
||||||
if (Instr->ReadSendSize < 0) {
|
if (Instr->ReadSendSize < 0) {
|
||||||
/* read until close */
|
/* read until close */
|
||||||
amount_to_be_read = Data_Buf_Size;
|
amount_to_be_read = Data_Buf_Size;
|
||||||
@@ -574,16 +545,14 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|||||||
goto Cleanup_File;
|
goto Cleanup_File;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
Cleanup_File:
|
Cleanup_File:
|
||||||
va_end(argp);
|
|
||||||
if (Instr && Instr->IsVirtualFile) {
|
if (Instr && Instr->IsVirtualFile) {
|
||||||
virtualDirCallback.close(Fp);
|
virtualDirCallback.close(Fp);
|
||||||
} else {
|
} else {
|
||||||
fclose(Fp);
|
fclose(Fp);
|
||||||
}
|
}
|
||||||
free(ChunkBuf);
|
goto ExitFunction;
|
||||||
return RetVal;
|
|
||||||
} else if (c == 'b') {
|
} else if (c == 'b') {
|
||||||
/* memory buffer */
|
/* memory buffer */
|
||||||
buf = va_arg(argp, char *);
|
buf = va_arg(argp, char *);
|
||||||
@@ -596,16 +565,17 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
|
|||||||
"%.*s\nbuf_length=%zd, num_written=%zd\n""------------\n",
|
"%.*s\nbuf_length=%zd, num_written=%zd\n""------------\n",
|
||||||
(int)buf_length, buf, buf_length, num_written);
|
(int)buf_length, buf, buf_length, num_written);
|
||||||
if (num_written != buf_length) {
|
if (num_written != buf_length) {
|
||||||
goto end;
|
RetVal = 0;
|
||||||
|
goto ExitFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
ExitFunction:
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
free(ChunkBuf);
|
free(ChunkBuf);
|
||||||
return 0;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -122,37 +122,37 @@ int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
|
|||||||
OUT int* http_error_code );
|
OUT int* http_error_code );
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/*!
|
||||||
* Function: http_SendMessage
|
* \brief Sends a message to the destination based on the format parameter.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* fmt types:
|
||||||
* IN SOCKINFO *info ; Socket information object
|
* \li \c 'f': arg = "const char *" file name
|
||||||
* IN OUT int * TimeOut ; time out value
|
* \li \c 'b': arg1 = "const char *" mem_buffer; arg2 = "size_t" buffer length.
|
||||||
* IN const char* fmt, ... Pattern format to take actions upon
|
* \li \c 'I': arg = "struct SendInstruction *"
|
||||||
*
|
*
|
||||||
* Description:
|
* E.g.:
|
||||||
* Sends a message to the destination based on the
|
\verbatim
|
||||||
* IN const char* fmt parameter
|
char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
|
||||||
* fmt types:
|
char *filename = "foo.dat";
|
||||||
* 'f': arg = const char * file name
|
int status = http_SendMessage(tcpsock, "bf",
|
||||||
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
|
buf, strlen(buf), // args for memory buffer
|
||||||
* E.g.:
|
filename); // arg for file
|
||||||
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
|
\endverbatim
|
||||||
* char *filename = "foo.dat";
|
|
||||||
* int status = http_SendMessage( tcpsock, "mf",
|
|
||||||
* buf, strlen(buf), // args for memory buffer
|
|
||||||
* filename ); // arg for file
|
|
||||||
*
|
*
|
||||||
* Returns:
|
* \return
|
||||||
* UPNP_E_OUTOF_MEMORY
|
* \li \c UPNP_E_OUTOF_MEMORY
|
||||||
* UPNP_E_FILE_READ_ERROR
|
* \li \c UPNP_E_FILE_READ_ERROR
|
||||||
* UPNP_E_SUCCESS
|
* \li \c UPNP_E_SUCCESS
|
||||||
************************************************************************/
|
*/
|
||||||
int http_SendMessage(
|
int http_SendMessage(
|
||||||
IN SOCKINFO *info,
|
/* [in] Socket information object. */
|
||||||
IN OUT int* timeout_secs,
|
SOCKINFO *info,
|
||||||
IN const char* fmt, ... );
|
/* [in,out] Time out value. */
|
||||||
|
int* timeout_secs,
|
||||||
|
/* [in] Pattern format to take actions upon. */
|
||||||
|
const char* fmt,
|
||||||
|
/* [in] Variable parameter list. */
|
||||||
|
...);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function: http_RequestAndResponse
|
* Function: http_RequestAndResponse
|
||||||
|
Reference in New Issue
Block a user