Embeded HTTPd daemon source reference 로서
pSOS가 탑재된 platform에서 다음의 command로 내부에 존재하는
HDD directory내용을 expoler에 표시하여 주는 기능을 수행한다.
----------------------------------------------------------------
Command
----------------------------------------------------------------
http://xxx.xxx.xxx.xxx:8088/Dir.do
임의의 lan port를 제공하는 embed platform에 Web server를 올려야 하는 경우
간단하게 사용할 수 잇다.
----------------------------------------------------------------
Main thread
----------------------------------------------------------------
/**
* Function Name : JLW_Httpd_AcceptServer
*
* Function Description :
* Input : void *param
* Output :
* Return :
*/
void JLW_Httpd_AcceptServer(void *param)
{
XONS_SOCKET mainSock, childSock;
XONS_SOCKADDR_IN mainAddr, childAddr;
int opt = 1, addrLen;
LogDebug("JLW_Httpd_AcceptServer() start port = %d", s_httpdServInfo.port);
while (1)
{
if ((mainSock = XOAL_NS_Socket(XONS_AF_INET, XONS_SOCK_STREAM, XONS_IPPROTO_TCP)) == XONS_INVALID_SOCKET)
{
LogDebug("JLW_Httpd_AcceptServer() main socket open error");
XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
continue;
}
LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Socket open %d", mainSock);
opt = 1;
if (XOAL_NS_SetSockOpt(mainSock, XONS_SOL_SOCKET, XONS_SO_REUSEADDR, (char *)&opt, sizeof(int)) == XONS_SOCKET_ERROR)
{
LogDebug("JLW_Httpd_AcceptServer() main socket setsockopt error");
XOAL_NS_CloseSocket(mainSock);
XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
continue;
}
LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_SetSockOpt OK");
memset((char *)&mainAddr, '\0', sizeof(XONS_SOCKADDR_IN));
mainAddr.sin_family = XONS_AF_INET;
mainAddr.sin_addr.s_addr = XONS_INADDR_ANY;
mainAddr.sin_port = XOAL_NS_htons(s_httpdServInfo.port);
if (XOAL_NS_Bind(mainSock, (XONS_SOCKADDR *)&mainAddr, sizeof(mainAddr)) == XONS_SOCKET_ERROR)
{
LogDebug("JLW_Httpd_AcceptServer() main socket bind error");
XOAL_NS_CloseSocket(mainSock);
XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
continue;
}
LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Bind OK");
if (XOAL_NS_Listen(mainSock, 100) == XONS_SOCKET_ERROR)
{
LogDebug("Httpd_AcceptServer() main socket listen error");
XOAL_NS_CloseSocket(mainSock);
XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
continue;
}
LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Listen OK");
while (1)
{
addrLen = sizeof(XONS_SOCKADDR_IN);
memset((char *)&childAddr, '\0', addrLen);
if ((childSock = XOAL_NS_Accept(mainSock, (struct sockaddr *)&childAddr, (int *)&addrLen)) == XONS_INVALID_SOCKET)
{
LogDebug("JLW_Httpd_AcceptServer() main socket accept error");
break;
}
LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Accept %d", childSock);
JLW_HttpdWork(childSock, &s_httpdServInfo);
XOAL_NS_CloseSocket(childSock);
}
XOAL_NS_CloseSocket(mainSock);
}
}
/**
* Function Name : JLW_HttpdSendBasic
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_WorkBuff *headBuff
JLW_WorkBuff *BodyBuff
int sendTimeout
* Output :
* Return : int : send result
*/
int JLW_HttpdSendBasic(XONS_SOCKET sock, JLW_WorkBuff *headBuff, JLW_WorkBuff *BodyBuff, int sendTimeout)
{
int retVal;
if ((retVal = JLW_Httpd_Send(sock, headBuff, sendTimeout)))
return retVal;
if (BodyBuff->len)
return JLW_Httpd_Send(sock, BodyBuff, sendTimeout);
else
return retVal;
}
/**
* Function Name : JLW_Httpd_Send
*
* Function Description :
* Input :
XONS_SOCKET sock
strNetBuff *sendBuff
int sendTimeout
* Output :
* Return : int : send result
*/
int JLW_Httpd_Send(XONS_SOCKET sock, JLW_WorkBuff *sendBuff, int sendTimeout)
{
XONS_FDSET writeFds, exceptFds;
XONS_TIMEVAL timeout;
int sendLen, posi, len;
// LogDebug("JLW_Httpd_Send() sendTimeout=%d", sendTimeout);
posi = 0;
sendLen = sendBuff->len;
while (posi < sendLen)
{
#ifdef __XOAL__SELECT__OK__
if (sendTimeout > 0)
{
XOAL_NS_FD_ZERO(&writeFds);
XOAL_NS_FD_ZERO(&exceptFds);
XOAL_NS_FD_SET(sock, &writeFds);
XOAL_NS_FD_SET(sock, &exceptFds);
timeout.tv_sec = sendTimeout / 1000;
timeout.tv_usec = sendTimeout % 1000;
// if (XOAL_NS_Select(sock + 1, NULL, &writeFds, &exceptFds, &timeout) <= 0 || XOAL_NS_FD_ISSET(sock, &exceptFds))
if (XOAL_NS_Select(sock + 1, NULL, &writeFds, NULL, &timeout) <= 0)
{
LogDebug("JLW_Httpd_Send() XOAL_NS_Select writeFds error");
return JLW_NET_SELECT_FAIL;
}
}
#endif
if ((len = XOAL_NS_Send(sock, sendBuff->buff + posi, sendLen-posi, 0)) <= 0)
{
LogDebug("JLW_Httpd_Send() XOAL_NS_Send error %d", len);
return JLW_NET_SEND_FAIL;
}
posi += len;
// LogDebug("JLW_Httpd_Send() XOAL_NS_Send OK len=%d(%d/%d)", sendLen, posi, sendLen);
}
return JLW_WORK_OK;
}
/**
* Function Name : JLW_Httpd_Recv
*
* Function Description :
* Input :
XONS_SOCKET sock
int receiveTimeout
* Output :
strNetBuff *recvBuff : return response data & length
U32 *retContLen : return Content-Length
* Return : int : recv result
*/
int JLW_Httpd_Recv(XONS_SOCKET sock, JLW_WorkBuff *recvBuff, int receiveTimeout, U32 *retContLen)
{
const char contLenText[] = "CONTENT-LENGTH:";
XONS_FDSET readFds, exceptFds;
XONS_TIMEVAL timeout;
int sendLen, len, posi, rcvTotal, i, selectCnt, retVal;
U32 contLen;
U8 buffer[HTTPD_RECV_BUFF_SIZE+1], *retBuffer, *respHeader;
char *temp, *contLenPosi;
memset((char *)recvBuff, '\0', sizeof(JLW_WorkBuff));
contLen = 0xFFFFFFFF;
rcvTotal = 0;
retBuffer = NULL;
temp = NULL;
memset(buffer, '\0', HTTPD_RECV_BUFF_SIZE+1);
while (1)
{
#ifdef __XOAL__SELECT__OK__
if (receiveTimeout > 0)
{
XOAL_NS_FD_ZERO(&readFds);
XOAL_NS_FD_ZERO(&exceptFds);
XOAL_NS_FD_SET(sock, &readFds);
XOAL_NS_FD_SET(sock, &exceptFds);
timeout.tv_sec = receiveTimeout / 1000;
timeout.tv_usec = receiveTimeout % 1000;
#if 0
if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, &exceptFds, &timeout)) <= 0
|| XOAL_NS_FD_ISSET(sock, &exceptFds))
#endif
if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, NULL, &timeout)) <= 0)
{
LogDebug("JLW_Httpd_Recv() XOAL_NS_Select readFds error %d", selectCnt);
break;
}
}
#endif
if ((len = XOAL_NS_Recv(sock, buffer, HTTPD_RECV_BUFF_SIZE, 0)) <= 0)
break;
temp = (char *)retBuffer;
if ((retBuffer = (U8 *)XOAL_Mem_Malloc(rcvTotal + len + 1)) == NULL)
{
LogDebug("JLW_Httpd_Recv() XOAL_Mem_Malloc error");
if (temp)
JLW_XOAL_Mem_Free(temp);
return JLW_MEMORY_ALLOC_FAIL;
}
memset(retBuffer, '\0', rcvTotal + len + 1);
if (temp)
{
memcpy(retBuffer, temp, rcvTotal);
JLW_XOAL_Mem_Free(temp);
}
memcpy(retBuffer+rcvTotal, buffer, len);
rcvTotal += len;
memset(buffer, '\0', len);
if (contLen == 0xFFFFFFFF)
{
if ((temp = strstr((char *)retBuffer, g_StrHeaderEnd)) == NULL)
continue;
len = temp - (char *)retBuffer;
if ((respHeader = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_Httpd_Recv() XOAL_Mem_Malloc error");
JLW_XOAL_Mem_Free(retBuffer);
return JLW_MEMORY_ALLOC_FAIL;
}
memset(respHeader, '\0', len + 1);
for (i = 0; i < len; i++)
respHeader[i] = toupper(retBuffer[i]);
if ((contLenPosi = strstr((char *)respHeader, contLenText)) == NULL)
{
JLW_XOAL_Mem_Free(respHeader);
if (((temp - (char *)retBuffer) + 4) < rcvTotal)
{
LogDebug("JLW_Httpd_Recv() http status 400 error");
JLW_XOAL_Mem_Free(retBuffer);
return (JLW_NET_RESPONSE_ERROR_BASE+400);
}
break;
}
sscanf(contLenPosi + strlen(contLenText), "%lu", &contLen);
// LogDebug("JLW_Httpd_Recv() Content-Length: OK len=%u", contLen);
JLW_XOAL_Mem_Free(respHeader);
if (retContLen)
*retContLen = contLen;
temp += strlen(g_StrHeaderEnd);
len = rcvTotal - (temp - (char *)retBuffer);
LogDebug("JLW_Httpd_Recv() len=%d", len);
if (len >= contLen)
break;
if (contLen > HTTPD_NO_SAVE_CONTENT_LEN)
{
if ((retVal = JLW_HTTPD_RecvFile(sock, receiveTimeout, contLen,
XOAL_F_GetDefaultDrive(), g_recvTempPath, g_recvTempFile, (U8 *)temp, len)))
{
JLW_XOAL_Mem_Free(retBuffer);
return retVal;
} else {
*temp = '\0';
break;
}
}
} else {
if ((temp = strstr((char *)retBuffer, g_StrHeaderEnd)) == NULL)
continue;
LogDebug("JLW_Httpd_Recv() len=%d", strlen(temp + strlen(g_StrHeaderEnd)));
if (rcvTotal - ((temp + strlen(g_StrHeaderEnd)) - (char *)retBuffer) >= contLen)
break;
}
}
LogDebug("JLW_Httpd_Recv() XOAL_NS_Recv OK rcvTotal=%d", rcvTotal);
recvBuff->len = rcvTotal;
recvBuff->buff = retBuffer;
return JLW_WORK_OK;
}
----------------------------------------------------------------
Working functions
----------------------------------------------------------------
/**
* Function Name : JLW_HttpdWork
*
* Function Description : http deamon work
* Input :
* Output :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
* Return :
*/
void JLW_HttpdWork(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo)
{
JLW_WorkBuff recvBuff, urlBuff;
int httpWorkFlag, retVal;
char *posi, *next, *temp;
U32 contLen;
if ((retVal = JLW_Httpd_Recv(sock, &recvBuff, servInfo->recvTime, &contLen)))
{
LogDebug("JLW_HttpdWork() JLW_Httpd_Recv error");
return;
}
JLW_HttpdConv2Char(recvBuff.buff);
// JLW_HTTPD_SendHttpdError(sock, servInfo, 200, "test");
if ((httpWorkFlag = JLW_HttpMethodCheck((char *)recvBuff.buff, &next)) < 0)
{
LogDebug("JLW_HttpdWork() command read error");
JLW_XOAL_Mem_Free(recvBuff.buff);
return;
}
posi = next;
if (JLW_HttpdGetWordAlloc(posi, ' ', TRUE, &urlBuff, &next))
{
LogDebug("JLW_HttpdWork() url read error");
JLW_XOAL_Mem_Free(recvBuff.buff);
return;
}
if ((posi = strchr((char *)urlBuff.buff, '?')))
*posi = '\0';
if (!(next = strrchr((char *)urlBuff.buff, '.')))
{
LogDebug("JLW_HttpdWork() work not found error");
JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
JLW_XOAL_Mem_Free(urlBuff.buff);
JLW_XOAL_Mem_Free(recvBuff.buff);
return;
}
if (!strcmp(next, ".do"))
{ /* CGI WORK */
if (JLW_HTTPD_CGIWork(sock, servInfo, &recvBuff, httpWorkFlag, &urlBuff, posi, contLen))
{
if (posi)
*posi = '&';
JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
}
} else {
char pathName[HTTPD_SMALL_BUFF_SIZE*2+1], fileName[HTTPD_SMALL_BUFF_SIZE+1];
int len;
memset(fileName, '\0', sizeof(fileName));
memset(pathName, '\0', sizeof(pathName));
strcpy(pathName, g_httpBasePath);
if ((temp = strrchr((char *)urlBuff.buff, '/')))
{
if ((next = strrchr((char *)urlBuff.buff, '\\')))
if (temp < next)
temp = next;
strcpy(fileName, temp + 1);
} else if ((temp = strrchr((char *)urlBuff.buff, '\\'))) {
strcpy(fileName, temp + 1);
} else {
strcpy(fileName, (char *)urlBuff.buff);
}
if (temp)
{
if (urlBuff.buff[0] != '/' && urlBuff.buff[0] != '\\')
strcat(pathName, "\\");
memcpy(pathName + strlen(pathName), urlBuff.buff, temp - (char *)urlBuff.buff);
}
if (posi)
*posi = '&';
if (JLW_HTTPD_SendFile(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, fileName))
JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
}
JLW_XOAL_Mem_Free(urlBuff.buff);
JLW_XOAL_Mem_Free(recvBuff.buff);
}
/**
* Function Name : JJLW_HttpMethodCheck
*
* Function Description : http command 를 얻는다.
* Input :
* Output :
char *buffer
char **next
* Return : int
*/
int JLW_HttpMethodCheck(char *buffer, char **next)
{
char command[HTTPD_COMMAND_LEN+1];
int retVal;
if ((retVal = JLW_HttpdGetWordBuff(buffer, ' ', FALSE, command, HTTPD_COMMAND_LEN+1, next)))
return retVal;
if (!strcmp(command, "GET"))
return HTTPD_COMMAND_GET;
if (!strcmp(command, "POST"))
return HTTPD_COMMAND_POST;
return JLW_WORK_FAIL;
}
/**
* Function Name : JLW_HttpdGetWordBuff
*
* Function Description : http command를 구한다.
* Input :
* Output :
char *buffer
char comp
bool checkCrLf
char *word
int maxLen
char **next
* Return : int : find result
*/
int JLW_HttpdGetWordBuff(char *buffer, char comp, bool checkCrLf, char *word, int maxLen, char **next)
{
char *posi, *prev, *quotation, *quotPrev;
int len;
memset(word, '\0', maxLen);
prev = buffer;
while (1)
{
if ((posi = strchr(prev, comp)) == NULL)
{
if (checkCrLf && ((posi = strstr(buffer, g_StrCrLf)) == NULL))
return JLW_WORK_FAIL;
}
quotPrev = prev;
while ((quotation = strchr(quotPrev, '\"')) || (quotation = strchr(quotPrev, '\'')))
{
if (quotation && (posi > quotation))
{
if ((quotPrev = strchr(quotation+1, *quotation)))
{
if (posi < quotPrev)
break;
else {
quotPrev++;
continue;
}
} else
return JLW_WORK_FAIL;
}
break;
}
if (posi < quotPrev)
{
prev = quotPrev+1;
continue;
}
break;
}
len = posi - buffer;
if (len >= maxLen)
return JLW_BUFFER_OVERFLOW;
memcpy(word, buffer, len);
*next = posi + 1;
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HttpdGetWordAlloc
*
* Function Description :
* Input :
* Output :
char *buffer
char comp
bool checkCrLf
JLW_WorkBuff *wordBuff
char **next
* Return : int : find result
*/
int JLW_HttpdGetWordAlloc(char *buffer, char comp, bool checkCrLf, JLW_WorkBuff *wordBuff, char **next)
{
char *posi, *prev, *quotation, *quotPrev;
int len;
memset((char *)wordBuff, '\0', sizeof(JLW_WorkBuff));
prev = buffer;
while (1)
{
if ((posi = strchr(prev, comp)) == NULL)
{
if (checkCrLf && ((posi = strstr(buffer, g_StrCrLf)) == NULL))
return JLW_WORK_FAIL;
}
quotPrev = prev;
while ((quotation = strchr(quotPrev, '\"')) || (quotation = strchr(quotPrev, '\'')))
{
if (quotation && (posi > quotation))
{
if ((quotPrev = strchr(quotation+1, *quotation)))
{
if (posi < quotPrev)
break;
else {
quotPrev++;
continue;
}
} else
return JLW_WORK_FAIL;
}
break;
}
if (posi < quotPrev)
{
prev = quotPrev+1;
continue;
}
break;
}
len = posi - buffer;
if ((wordBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HttpdGetWordAlloc() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
memset(wordBuff->buff, '\0', len+1);
wordBuff->len = len;
memcpy((U8 *)wordBuff->buff, buffer, len);
*next = posi + 1;
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HttpdFindHeaderField
*
* Function Description :
* Input :
* Output :
U8 *request
char *field
* Return : U8 * : 할당받은 data field
*/
U8 *JLW_HttpdFindHeaderField(U8 *request, char *field)
{
const char *endOfHeader = "\r\n\r\n";
const char *endOfLine = "\r\n";
char *header, *posi, *end;
U8 *data;
int len, i;
if (!(posi = strstr((char *)request, endOfHeader)))
return NULL;
len = posi - (char *)request;
if ((header = (char *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HttpdFindHeaderField() XOAL_Mem_Malloc fail");
return NULL;
}
memset(header, '\0', len + 1);
for (i = 0; i < len; i++)
header[i] = toupper(request[i]);
if ((posi = strstr(header, field)))
{
posi += strlen(field);
if ((end = strstr(posi, endOfLine)))
len = end - posi;
else
len = strlen(posi);
if ((data = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HttpdFindHeaderField() XOAL_Mem_Malloc fail");
JLW_XOAL_Mem_Free(header);
return NULL;
}
memset(data, '\0', len + 1);
i = posi - header;
JLW_XOAL_Mem_Free(header);
memcpy(data, request + i, len);
return data;
}
JLW_XOAL_Mem_Free(header);
return NULL;
}
/**
* Function Name : JLW_HttpdFindFieldFromAll
*
* Function Description :
* Input :
U8 *request
U8 *getData
char *field
int retBuffMax : retBuff의 max length
* Output :
U8 *retBuff
* Return : int : result
*/
int JLW_HttpdFindFieldFromAll(U8 *request, U8 *getData, char *field, U8 *retBuff, int retBuffMax)
{
int retVal;
if (request == NULL || !strlen((char *)request) || field == NULL || !strlen((char *)field) || retBuff == NULL || retBuffMax <= 0)
{
LogDebug("JLW_HttpdFindFieldFromAll() function call data error");
return JLW_CALL_DATA_FAIL;
}
if ((retVal = JLW_HttpdFindFieldFromGet(getData, field, retBuff, retBuffMax)) == JLW_FIELD_NOT_FOUND)
retVal = JLW_HttpdFindFieldFromPost(request, field, retBuff, retBuffMax);
return retVal;
}
/**
* Function Name : JLW_HttpdFindFieldFromGet
*
* Function Description :
* Input :
U8 *getData
char *field
int retBuffMax : retBuff의 max length
* Output :
U8 *retBuff
* Return : int : result
*/
int JLW_HttpdFindFieldFromGet(U8 *getData, char *field, U8 *retBuff, int retBuffMax)
{
if (field == NULL || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
{
LogDebug("JLW_HttpdFindFieldFromGet() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (getData == NULL || !strlen((char *)getData+1))
{
LogDebug("JLW_HttpdFindFieldFromGet() field not found");
return JLW_FIELD_NOT_FOUND;
}
/* url에서 ? 위치를 가지고 오는 상황으로 이부분을 '\0' 처리가 되어 있는 상황이다. */
return JLW_HttpdFindFieldFromRequest(getData + 1, field, retBuff, retBuffMax);
}
/**
* Function Name : JLW_HttpdFindFieldFromPost
*
* Function Description :
* Input :
U8 *request
char *field
int retBuffMax : retBuff의 max length
* Output :
U8 *retBuff
* Return : int : result
*/
int JLW_HttpdFindFieldFromPost(U8 *request, char *field, U8 *retBuff, int retBuffMax)
{
U8 *posi;
if (field == NULL || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
{
LogDebug("JLW_HttpdFindFieldFromPost() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (request == NULL || !strlen((char *)request) || (posi = (U8 *)strstr((char *)request, g_StrHeaderEnd)) == NULL)
{
LogDebug("JLW_HttpdFindFieldFromPost() field not found");
return JLW_FIELD_NOT_FOUND;
}
return JLW_HttpdFindFieldFromRequest(posi + strlen(g_StrHeaderEnd), field, retBuff, retBuffMax);
}
/**
* Function Name : JLW_HttpdFindFieldFromRequest
*
* Function Description :
* Input :
U8 *buffer
char *field
int retBuffMax : retBuff의 max length
* Output :
U8 *retBuff
* Return : int : result
*/
int JLW_HttpdFindFieldFromRequest(U8 *buffer, char *field, U8 *retBuff, int retBuffMax)
{
char *posi, *end;
int len;
if (field == NULL || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
{
LogDebug("JLW_HttpdFindFieldFromRequest() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (buffer == NULL || !strlen((char *)buffer))
{
LogDebug("JLW_HttpdFindFieldFromRequest() field not found");
return JLW_FIELD_NOT_FOUND;
}
if ((posi = strstr((char *)buffer, field)))
{
if ((posi == (char *)buffer) || (*(posi-1) == '&'))
{
posi += strlen(field);
if (*posi == '\'' || *posi == '\"')
{
if (((end = strchr(posi+1, *posi)) == NULL) || ((end[1] != '\0') && (end[1] != '&') ))
{
LogDebug("JLW_HttpdFindFieldFromRequest() data error");
return JLW_DATA_ERROR;
}
posi++;
len = end - posi;
if (len > retBuffMax)
{
LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
return JLW_BUFFER_OVERFLOW;
}
memcpy(retBuff, posi, len);
retBuff[len] = '\0';
} else {
if ((end = strchr(posi, '&')))
{
len = end - posi;
if (len > retBuffMax)
{
LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
return JLW_BUFFER_OVERFLOW;
}
memcpy(retBuff, posi, len);
retBuff[len] = '\0';
} else {
if (strlen(posi) > retBuffMax)
{
LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
return JLW_BUFFER_OVERFLOW;
}
strcpy((char *)retBuff, posi);
}
}
return JLW_WORK_OK;
}
}
LogDebug("JLW_HttpdFindFieldFromRequest() field not found");
return JLW_FIELD_NOT_FOUND;
}
/**
* Function Name : JLW_HttpdConv2Char
*
* Function Description :
* Input :
* Output :
U8 *buffer
* Return :
*/
void JLW_HttpdConv2Char(U8 *buffer)
{
U8 *posi, *prev;
char data[3];
int ch;
prev = buffer;
while ((posi = (U8 *)strchr((char *)prev, '%')))
{
if (strlen((char *)posi) <= 3)
return;
if (posi[1] == '%')
continue;
memset(data, '\0', sizeof(data));
data[0] = toupper(posi[1]);
data[1] = toupper(posi[2]);
sscanf(data, "%X", &ch);
*posi = (U8)(ch & 0xFF);
strcpy((char *)posi + 1, (char *)posi + 3);
}
}
----------------------------------------------------------------
CGI functions
----------------------------------------------------------------
/**
* Function Name : JLW_HTTPD_CGIWork
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
int httpWorkFlag
JLW_WorkBuff *urlBuff
char *urlPosi
U32 contLen
* Output :
* Return : int : result
*/
int JLW_HTTPD_CGIWork(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
JLW_WorkBuff *urlBuff, char *urlPosi, U32 contLen)
{
char *posi;
if (sock < 0 || servInfo == NULL || recvBuff == NULL || urlBuff == NULL)
{
LogDebug("JLW_HTTPD_CGIWork() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (urlBuff->buff[0] == '/' || urlBuff->buff[0] == '\\')
posi = (char *)urlBuff->buff+1;
else
posi = (char *)urlBuff->buff;
if (!strcmp(posi, "Dir.do"))
{
return JLW_HTTPD_Dir(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
} else if (!strcmp(posi, "RmDir.do")) {
return JLW_HTTPD_RmDir(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
#if 0
} else if (!strcmp(posi, "MkDir.do")) {
#endif
} else if (!strcmp(posi, "ViewFile.do")) {
return JLW_HTTPD_ViewFile(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
} else if (!strcmp(posi, "DeleteFile.do")) {
return JLW_HTTPD_DeleteFile(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
} else if (!strcmp(posi, "UploadFileHtml.do")) {
return JLW_HTTPD_UploadFileHttp(sock, servInfo);
} else if (!strcmp(posi, "UploadFile.do")) {
if (httpWorkFlag != HTTPD_COMMAND_POST)
return JLW_WORK_FAIL;
return JLW_HTTPD_UploadFile(sock, servInfo, recvBuff, contLen);
}
return JLW_WORK_FAIL;
}
/**
* Function Name : JLW_HTTPD_Dir
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
int httpWorkFlag
JLW_WorkBuff *urlBuff
char *urlPosi
* Output :
* Return : int : result
*/
int JLW_HTTPD_Dir(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
JLW_WorkBuff *urlBuff, char *urlPosi)
{
const char httpBodyHead[] =
"<HTML><HEAD><TITLE>Directory</TITLE></HEAD><BODY>\r\n";
const char strPathName[] = "pathName=";
char pathName[HTTPD_MAX_PATH+1];
int retVal;
memset(pathName, '\0', sizeof(pathName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
(U8 *)pathName, sizeof(pathName)-1);
if (retVal && retVal != JLW_FIELD_NOT_FOUND)
return retVal;
return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, httpBodyHead);
}
/**
* Function Name : JLW_HTTPD_RmDir
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
int httpWorkFlag
JLW_WorkBuff *urlBuff
char *urlPosi
* Output :
* Return : int : result
*/
int JLW_HTTPD_RmDir(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
JLW_WorkBuff *urlBuff, char *urlPosi)
{
const char httpBodyHead[] =
"<HTML><HEAD><TITLE>Rm Dir</TITLE></HEAD><BODY>\r\n"
"rmdir %s %s<br><br>\r\n";
const char strPathName[] = "pathName=";
char pathName[HTTPD_MAX_PATH+1], buffer[HTTPD_BUFF_SIZE+HTTPD_MAX_PATH+1], *posi;
int retVal;
memset(pathName, '\0', sizeof(pathName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
(U8 *)pathName, sizeof(pathName)-1);
if (retVal)
return retVal;
JLW_ConvPathName(pathName);
if (strlen(pathName) == 1 && pathName[0] == '\\')
posi = (char *)g_failText;
else {
#ifndef __NO_VDMS__
if (!XOAL_F_RmDir(XOAL_F_GetDefaultDrive(), pathName))
#else
if (0)
#endif
posi = (char *)g_failText;
else
posi = (char *)g_successText;
}
sprintf(buffer, httpBodyHead, pathName, posi);
if (strlen(pathName) != 1 || pathName[0] != '\\')
if ((posi = strrchr(pathName, '\\')))
*posi = '\0';
return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, buffer);
}
/**
* Function Name : JLW_HTTPD_ViewFile
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
int httpWorkFlag
JLW_WorkBuff *urlBuff
char *urlPosi
* Output :
* Return : int : result
*/
int JLW_HTTPD_ViewFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
JLW_WorkBuff *urlBuff, char *urlPosi)
{
const char strPathName[] = "pathName=";
const char strFileName[] = "fileName=";
char pathName[HTTPD_MAX_PATH+1], fileName[HTTPD_SMALL_BUFF_SIZE+1];
int retVal;
memset(pathName, '\0', sizeof(pathName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
(U8 *)pathName, sizeof(pathName)-1);
if (retVal)
return retVal;
memset(fileName, '\0', sizeof(fileName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strFileName, (U8 *)fileName, sizeof(fileName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strFileName,
(U8 *)fileName, sizeof(fileName)-1);
if (retVal)
return retVal;
JLW_ConvPathName(pathName);
return JLW_HTTPD_SendFile(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, fileName);
}
/**
* Function Name : JLW_HTTPD_DeleteFile
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
int httpWorkFlag
JLW_WorkBuff *urlBuff
char *urlPosi
* Output :
* Return : int : result
*/
int JLW_HTTPD_DeleteFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
JLW_WorkBuff *urlBuff, char *urlPosi)
{
const char httpBodyHead[] =
"<HTML><HEAD><TITLE>Delete file</TITLE></HEAD><BODY>\r\n"
"delete file : path=%s file=%s %s<br><br>\r\n";
const char strPathName[] = "pathName=";
const char strFileName[] = "fileName=";
char pathName[HTTPD_MAX_PATH+1], fileName[HTTPD_SMALL_BUFF_SIZE+1], buffer[HTTPD_BUFF_SIZE+HTTPD_MAX_PATH+1], *posi;
int retVal;
memset(pathName, '\0', sizeof(pathName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
(U8 *)pathName, sizeof(pathName)-1);
if (retVal)
return retVal;
memset(fileName, '\0', sizeof(fileName));
if (httpWorkFlag == HTTPD_COMMAND_GET)
retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strFileName, (U8 *)fileName, sizeof(fileName)-1);
else
retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strFileName,
(U8 *)fileName, sizeof(fileName)-1);
if (retVal)
return retVal;
JLW_ConvPathName(pathName);
#ifndef __NO_VDMS__
if (!XOAL_F_Remove(XOAL_F_GetDefaultDrive(), pathName, fileName))
#else
if (0)
#endif
posi = (char *)g_failText;
else
posi = (char *)g_successText;
sprintf(buffer, httpBodyHead, pathName, fileName, posi);
return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, buffer);
}
/**
* Function Name : JLW_HTTPD_DirResponse
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
int device
char *pathName
char *httpBodyHeader
* Output :
* Return : int : result
*/
int JLW_HTTPD_DirResponse(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int device, char *pathName,
const char *httpBodyHead)
{
#if 0
const char httpBodyHead[] =
"<HTML><HEAD><TITLE>Directory</TITLE></HEAD><BODY>\r\n";
#endif
const char httpBodyTableStart[] =
"%s >><br><TABLE BORDER=1>\r\n";
const char httpBodyTail[] =
"</TABLE></BODY></HTML>";
const char httpBodyTableParent[] =
"<TR><TD colspan=3><A HREF=\"Dir.do?pathName='%s'\">[..]</A></TD></TR>\r\n";
const char httpBodyTableDir[] =
"<TR><TD><A HREF=\"Dir.do?pathName='%s%s%s'\">[%s]</A></TD><TD>%lu</TD>"
"<TD><A HREF=\"RmDir.do?pathName='%s%s%s'\"><IMG border=0 src=\"image/btn_delete.gif\"></A></TD></TR>\r\n";
const char httpBodyTableFile[] =
"<TR><TD><A HREF=\"ViewFile.do?pathName='%s'&fileName='%s'\">%s</A></TD><TD>%lu</TD>"
"<TD><A HREF=\"DeleteFile.do?pathName='%s'&fileName='%s'\"><IMG border=0 src=\"image/btn_delete.gif\"></A></TD></TR>\r\n";
const char strSearch[] = "*";
#ifndef __NO_VDMS__
XOF_FILEINFO *fileInfo;
XOF_HFIND *findHandle;
#else
XOF_FILEINFO fileInfo;
XOF_HFIND findHandle;
#endif
char fullPath[HTTPD_MAX_PATH+1], fileSize[40], pathEnd[2], *posi;
unsigned long bodylen, pathLen;
JLW_WorkBuff headBuff, bodyBuff;
int retVal;
if (sock < 0 || servInfo == NULL)
{
LogDebug("JLW_HTTPD_DirResponse() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (pathName == NULL)
pathName = "";
JLW_ConvPathName(pathName);
if (pathName[0] != '\\')
sprintf(fullPath, "\\%s", pathName);
else
strcpy(fullPath, pathName);
pathLen = strlen(fullPath);
if (pathLen > 1 && fullPath[pathLen-1] == '\\')
{
fullPath[pathLen-1] = '\0';
pathLen--;
}
bodylen = strlen(httpBodyHead) + strlen(httpBodyTableStart) - 1 * 2 + pathLen + strlen(httpBodyTail);
if (pathLen > 1)
{
bodylen += strlen(httpBodyTableParent) - 1 * 2;
posi = strrchr(fullPath, '\\');
if (posi == fullPath)
bodylen += 1;
else {
bodylen += (posi - fullPath);
}
strcpy(pathEnd, "\\");
} else {
memset(pathEnd, '\0', sizeof(pathEnd));
}
/* directory */
findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_DIR, &fileInfo);
#ifndef __NO_VDMS__
if (findHandle != NULL)
#else
if (findHandle != INVALID_HANDLE_VALUE)
#endif
{
do {
#ifndef __NO_VDMS__
if (fileInfo)
#endif
{
#ifdef __NO_VDMS__
if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
continue;
if (!strcmp(fileInfo.cFileName, ".") || !strcmp(fileInfo.cFileName, ".."))
continue;
#endif
bodylen += (strlen(httpBodyTableDir) - 7 * 2 - 1 * 3 + pathLen * 2 + strlen(pathEnd) * 2
#ifndef __NO_VDMS__
+ strlen(fileInfo->szFileName) * 3);
sprintf(fileSize, "%lu", fileInfo->uiFileSize);
#else
+ strlen(fileInfo.cFileName) * 3);
sprintf(fileSize, "%lu", (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow);
#endif
bodylen += strlen(fileSize);
}
} while (XOAL_F_FindNext(findHandle, &fileInfo));
XOAL_F_FindClose(findHandle);
}
/* file */
findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_NORMAL, &fileInfo);
#ifndef __NO_VDMS__
if (findHandle != NULL)
#else
if (findHandle != INVALID_HANDLE_VALUE)
#endif
{
do {
#ifndef __NO_VDMS__
if (fileInfo)
#endif
{
#ifdef __NO_VDMS__
if ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
continue;
#endif
bodylen += (strlen(httpBodyTableFile) - 5 * 2 - 1 * 3 + pathLen * 2
#ifndef __NO_VDMS__
+ strlen(fileInfo->szFileName) * 3);
sprintf(fileSize, "%lu", fileInfo->uiFileSize);
#else
+ strlen(fileInfo.cFileName) * 3);
sprintf(fileSize, "%lu", (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow);
#endif
bodylen += strlen(fileSize);
}
} while (XOAL_F_FindNext(findHandle, &fileInfo));
XOAL_F_FindClose(findHandle);
}
/* header make & send */
if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodylen, &headBuff)))
return retVal;
retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(headBuff.buff);
if (retVal)
return retVal;
if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(HTTPD_MAX_PATH * 2 + HTTPD_BUFF_SIZE + 1)) == NULL)
{
LogDebug("JLW_HTTPD_DirResponse() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
sprintf((char *)bodyBuff.buff, httpBodyHead);
bodyBuff.len = strlen((char *)bodyBuff.buff);
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
sprintf((char *)bodyBuff.buff, httpBodyTableStart, fullPath);
bodyBuff.len = strlen((char *)bodyBuff.buff);
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
if (pathLen > 1)
{
posi = strrchr(fullPath, '\\');
if (posi == fullPath)
sprintf((char *)bodyBuff.buff, httpBodyTableParent, "\\");
else {
*posi = '\0';
sprintf((char *)bodyBuff.buff, httpBodyTableParent, fullPath);
*posi = '\\';
}
bodyBuff.len = strlen((char *)bodyBuff.buff);
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
}
/* directory */
findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_DIR, &fileInfo);
#ifndef __NO_VDMS__
if (findHandle != NULL)
#else
if (findHandle != INVALID_HANDLE_VALUE)
#endif
{
do {
#ifndef __NO_VDMS__
if (fileInfo)
#endif
{
#ifdef __NO_VDMS__
if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|| (fileInfo.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
continue;
if (!strcmp(fileInfo.cFileName, ".") || !strcmp(fileInfo.cFileName, ".."))
continue;
#endif
sprintf((char *)bodyBuff.buff, httpBodyTableDir,
#ifndef __NO_VDMS__
fullPath, pathEnd, fileInfo->szFileName, fileInfo->szFileName,
fileInfo->uiFileSize,
fullPath, pathEnd, fileInfo->szFileName);
#else
fullPath, pathEnd, fileInfo.cFileName, fileInfo.cFileName,
(fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow,
fullPath, pathEnd, fileInfo.cFileName);
#endif
bodyBuff.len = strlen((char *)bodyBuff.buff);
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
XOAL_F_FindClose(findHandle);
return retVal;
}
}
} while (XOAL_F_FindNext(findHandle, &fileInfo));
XOAL_F_FindClose(findHandle);
}
/* file */
findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_NORMAL, &fileInfo);
#ifndef __NO_VDMS__
if (findHandle != NULL)
#else
if (findHandle != INVALID_HANDLE_VALUE)
#endif
{
do {
#ifndef __NO_VDMS__
if (fileInfo)
#endif
{
#ifdef __NO_VDMS__
if ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|| (fileInfo.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
continue;
#endif
sprintf((char *)bodyBuff.buff, httpBodyTableFile,
#ifndef __NO_VDMS__
fullPath, fileInfo->szFileName, fileInfo->szFileName,
fileInfo->uiFileSize,
fullPath, fileInfo->szFileName);
#else
fullPath, fileInfo.cFileName, fileInfo.cFileName,
(fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow,
fullPath, fileInfo.cFileName);
#endif
bodyBuff.len = strlen((char *)bodyBuff.buff);
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
XOAL_F_FindClose(findHandle);
return retVal;
}
}
} while (XOAL_F_FindNext(findHandle, &fileInfo));
XOAL_F_FindClose(findHandle);
}
sprintf((char *)bodyBuff.buff, httpBodyTail);
bodyBuff.len = strlen((char *)bodyBuff.buff);
retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
/**
* Function Name : JLW_HTTPD_UploadFileHttp
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
* Output :
* Return : int : result
*/
int JLW_HTTPD_UploadFileHttp(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo)
{
const char httpBody[] =
"<HTML><HEAD><TITLE>File upload For WEB</TITLE></HEAD>\r\n"
"<BODY><Form action=\"UploadFile.do\" Method=\"POST\" enctype=\"multipart/form-data\">\r\n"
"Path : <Input type=\"TEXT\" name=\"pathName\"><br>\r\n"
"File : <Input type=\"FILE\" name=\"fileName\"><br>\r\n"
"<Input type=\"SUBMIT\" value=\"Send\"></Form></BODY></HTML>\r\n";
JLW_WorkBuff headBuff, bodyBuff;
int retVal;
if (sock < 0 || servInfo == NULL)
{
LogDebug("JLW_HTTPD_UploadFileHttp() function call data error");
return JLW_CALL_DATA_FAIL;
}
bodyBuff.buff = (U8 *)httpBody;
bodyBuff.len = strlen(httpBody);
/* header make & send */
if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodyBuff.len, &headBuff)))
return retVal;
retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(headBuff.buff);
if (retVal)
return retVal;
/* body send */
return JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);
}
/**
* Function Name : JLW_HTTPD_UploadFile
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
JLW_WorkBuff *recvBuff
U32 contLen
* Output :
* Return : int : result
*/
int JLW_HTTPD_UploadFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, U32 contLen)
{
const char httpBody[] =
"<HTML><HEAD><TITLE>File upload For WEB</TITLE></HEAD>\r\n"
"<BODY>Path : %s<BR>File : %s<BR>Upload Result : %s<BR>\r\n"
"<Form action=\"UploadFile.do\" Method=\"POST\" enctype=\"multipart/form-data\">\r\n"
"Path : <Input type=\"TEXT\" name=\"pathName\"><br>\r\n"
"File : <Input type=\"FILE\" name=\"fileName\"><br>\r\n"
"<Input type=\"SUBMIT\" value=\"Send\"></Form></BODY></HTML>\r\n";
char fileName[HTTPD_SMALL_BUFF_SIZE+1], pathName[HTTPD_MAX_PATH+1], *boundary, *posi;
JLW_WorkBuff pathBuff, headBuff, bodyBuff;
int len, retVal;
if (sock < 0 || servInfo == NULL || recvBuff == NULL || !contLen)
{
LogDebug("JLW_HTTPD_UploadFile() function call data error");
return JLW_CALL_DATA_FAIL;
}
if (contLen <= HTTPD_NO_SAVE_CONTENT_LEN)
{ /* content length가 저장 크기보다 적어 http body가 file로 생성되지 않은경우 file로 만든다 */
if ((posi = strstr((char *)recvBuff->buff, g_StrHeaderEnd)) == NULL)
{
LogDebug("JLW_HTTPD_UploadFile() receive data error");
return JLW_WORK_FAIL;
}
posi += strlen(g_StrHeaderEnd);
JLW_HTTPD_RecvFile(sock, servInfo->recvTime, contLen, XOAL_F_GetDefaultDrive(),
g_recvTempPath, g_recvTempFile, (U8 *)posi, contLen);
*posi = '\0';
}
/* header에서 boundary 를 찾는다 */
if ((boundary = (char *)JLW_HttpdFindHeaderField(recvBuff->buff, "BOUNDARY=")) == NULL)
{
LogDebug("JLW_HTTPD_UploadFile() boundary not found");
return JLW_BOUNDARY_NOT_FOUND;
}
if ((posi = strchr(boundary, ';')))
*posi = '\0';
/* http body에서 pathName field를 구하고 directory를 생성한다. */
if ((retVal = JLW_HTTPD_GetFieldFromFile("pathName", boundary, XOAL_F_GetDefaultDrive(),
g_recvTempPath, g_recvTempFile, &pathBuff)))
{
JLW_XOAL_Mem_Free(boundary);
return retVal;
}
// JLW_Makedir(g_httpBasePath, (char *)pathBuff.buff, pathName);
#ifndef __NO_VDMS__
JLW_Makedir("", (char *)pathBuff.buff, pathName);
#else
JLW_Makedir(g_httpBasePath, (char *)pathBuff.buff, pathName); // web directory로만 upload한다.
#endif
/* http body에서 fileName field를 구하고, file로 생성한다. */
retVal = JLW_HTTPD_MakeFile("fileName", boundary, XOAL_F_GetDefaultDrive(),
g_recvTempPath, g_recvTempFile, XOAL_F_GetDefaultDrive(), pathName, fileName, sizeof(fileName)-1);
JLW_XOAL_Mem_Free(boundary);
if (retVal)
posi = (char *)g_failText;
else
posi = (char *)g_successText;
bodyBuff.len = strlen(httpBody) + strlen((char *)pathBuff.buff) + strlen(fileName) + strlen(posi) - 3 * 2;
if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(bodyBuff.len + 1)) == NULL)
{
LogDebug("JLW_HTTPD_UploadFile() XOAL_Mem_Malloc fail");
JLW_XOAL_Mem_Free(pathBuff.buff);
return JLW_MEMORY_ALLOC_FAIL;
}
sprintf((char *)bodyBuff.buff, httpBody, pathBuff.buff, fileName, posi);
JLW_XOAL_Mem_Free(pathBuff.buff);
if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodyBuff.len, &headBuff)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
/* header make & send */
retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(headBuff.buff);
if (retVal)
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
----------------------------------------------------------------
Message functions
----------------------------------------------------------------
/** 공통사용 http text 선언
*/
const char g_StrHeaderEnd[] = "\r\n\r\n";
const char g_StrCrLf[] = "\r\n";
const char g_successText[] = "success";
const char g_failText[] = "fail";
/**
* Function Name : JLW_HTTPD_MakeHttpdHeader
*
* Function Description :
* Input :
char *status
int bodyLength
* Output :
JLW_WorkBuff *retBuff : return buffer data & length
* Return : int : result
*/
int JLW_HTTPD_MakeHttpdHeader(const char *status, U32 bodyLength, JLW_WorkBuff *retBuff)
{
const char headerFormat[] = "HTTP/1.1 %s\r\n"
"Connection: close\r\n"
"Content-Type: text/html\r\n"
"Content-Length: %u\r\n"
"Cache-Control: no-cache\r\n"
"\r\n";
char temp[50];
U32 len;
memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
if (status == NULL || !strlen(status) || bodyLength < 0 || retBuff == NULL)
{
LogDebug("JLW_HTTPD_MakeHttpdHeader() function call data error");
return JLW_CALL_DATA_FAIL;
}
len = strlen(headerFormat) + strlen(status) - 2 * 2;
sprintf(temp, "%u", bodyLength);
len += strlen(temp);
if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HTTPD_MakeHttpdHeader() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
retBuff->len = len;
memset(retBuff->buff, '\0', len + 1);
sprintf((char *)retBuff->buff, headerFormat, status, bodyLength);
#if 0
{
U8 temp[101];
int i;
LogDebug("JLW_HTTPD_MakeHttpdHeader() len=%d", len);
for (i = 0; i < len; i+= 100)
{
strncpy(temp, retBuff->buff+i, 100);
LogDebug("%s", temp);
}
}
#endif
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HTTPD_MakeHttpdImageHeader
*
* Function Description :
* Input :
char *status
int bodyLength
char *contentType
* Output :
JLW_WorkBuff *retBuff : return buffer data & length
* Return : int : result
*/
int JLW_HTTPD_MakeHttpdOtherHeader(const char *status, U32 bodyLength, JLW_WorkBuff *retBuff, char *contentType)
{
const char headerFormat[] = "HTTP/1.1 %s\r\n"
"Connection: close\r\n"
"Content-Type: %s\r\n"
"Content-Length: %u\r\n"
"Cache-Control: no-cache\r\n"
"\r\n";
char temp[50];
U32 len;
memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
if (status == NULL || !strlen(status) || bodyLength < 0 || retBuff == NULL)
{
LogDebug("JLW_HTTPD_MakeHttpdImageHeader() function call data error");
return JLW_CALL_DATA_FAIL;
}
len = strlen(headerFormat) - 3 * 2 + strlen(status) + strlen(contentType);
sprintf(temp, "%u", bodyLength);
len += strlen(temp);
if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HTTPD_MakeHttpdImageHeader() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
retBuff->len = len;
memset(retBuff->buff, '\0', len + 1);
sprintf((char *)retBuff->buff, headerFormat, status, contentType, bodyLength);
#if 0
{
U8 temp[101];
int i;
LogDebug("JLW_HTTPD_MakeHttpdImageHeader() len=%d", len);
for (i = 0; i < len; i+= 100)
{
strncpy(temp, retBuff->buff+i, 100);
LogDebug("%s", temp);
}
}
#endif
return JLW_WORK_OK;
}
----------------------------------------------------------------
File handle functions
----------------------------------------------------------------
/**
* Function Name : JLW_HTTPD_SendFile
*
* Function Description :
* Input :
XONS_SOCKET sock
JLW_HttpdServerInfo *servInfo
int device
U8 *pathName
char *fileName
* Output :
* Return : int : result
*/
int JLW_HTTPD_SendFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int device, char *pathName, char *fileName)
{
JLW_WorkBuff headBuff, bodyBuff;
char *posi, *contentType;
bool isText = TRUE;
XOF_FILE *readFp;
U32 fileLen;
int retVal, readLen;
if (sock < 0 || servInfo == NULL || device < 0 || pathName == NULL || fileName == NULL || !strlen(fileName))
{
LogDebug("JLW_HTTPD_SendFile() function call data error");
return JLW_CALL_DATA_FAIL;
}
if ((posi = strrchr(fileName, '.')) != NULL)
{
if ((contentType = JLW_GetMimeType(posi + 1)) != NULL)
if (!strstr(contentType, "text/"))
isText = FALSE;
}
JLW_ConvPathName(pathName);
#ifndef __NO_VDMS__
if ((readFp = XOAL_F_Open(device, pathName, fileName, DCA_READ | DCA_BINARY)) == NULL)
#else
if ((readFp = XOAL_F_Open(device, pathName, fileName, "rb")) == NULL)
#endif
{
LogDebug("JLW_HTTPD_SendFile() file open error %d:%s/%s", device, pathName, fileName);
return JLW_FILE_OPEN_FAIL;
}
fileLen = XOAL_F_Size(readFp);
if (isText)
{
if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, fileLen, &headBuff)))
{
XOAL_F_Close(readFp);
return retVal;
}
} else {
if ((retVal = JLW_HTTPD_MakeHttpdOtherHeader(g_strHttpStatus200, fileLen, &headBuff, contentType)))
{
XOAL_F_Close(readFp);
return retVal;
}
}
retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
JLW_XOAL_Mem_Free(headBuff.buff);
if (retVal)
{
XOAL_F_Close(readFp);
return retVal;
}
if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(HTTPD_SEND_FILE_BUFF + 1)) == NULL)
{
LogDebug("JLW_HTTPD_SendFile() XOAL_Mem_Malloc fail");
XOAL_F_Close(readFp);
return JLW_MEMORY_ALLOC_FAIL;
}
while (!XOAL_F_EOF(readFp))
{
memset(bodyBuff.buff, '\0', HTTPD_SEND_FILE_BUFF+1);
if ((readLen = XOAL_F_Read(readFp, bodyBuff.buff, HTTPD_SEND_FILE_BUFF)) < 0)
{
LogDebug("JLW_HTTPD_SendFile() XOAL_F_Read error");
break;
}
bodyBuff.len = readLen;
if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
{
LogDebug("JLW_HTTPD_SendFile() file JLW_Httpd_Send error");
JLW_XOAL_Mem_Free(bodyBuff.buff);
XOAL_F_Close(readFp);
return retVal;
}
}
JLW_XOAL_Mem_Free(bodyBuff.buff);
XOAL_F_Close(readFp);
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HTTPD_RecvFile
*
* Function Description :
* Input :
XONS_SOCKET sock
int receiveTimeout
U32 fileLen
int device
char *pathName
char *fileName
U8 *before
int beforeLen
* Output :
* Return : int : result
*/
int JLW_HTTPD_RecvFile(XONS_SOCKET sock, int receiveTimeout, U32 fileLen, int device, char *pathName, char *fileName,
U8 *before, int beforeLen)
{
U8 *buffer;
XOF_FILE *writeFp;
U32 recvTotal;
int retVal, recvLen, writeTotal, selectCnt, len;
XONS_FDSET readFds, exceptFds;
XONS_TIMEVAL timeout;
if (sock < 0 || device < 0 || pathName == NULL || fileName == NULL || !strlen(fileName))
{
LogDebug("JLW_HTTPD_RecvFile() function call data error");
return JLW_CALL_DATA_FAIL;
}
JLW_Mkdir(device, pathName,FALSE);
#ifndef __NO_VDMS__
if ((writeFp = XOAL_F_Open(device, pathName, fileName, DCA_WRITE | DCA_CREATE | DCA_BINARY)) == NULL)
#else
if ((writeFp = XOAL_F_Open(device, pathName, fileName, "w+b")) == NULL)
#endif
{
LogDebug("JLW_HTTPD_RecvFile() file open error %d:%s/%s", device, pathName, fileName);
return JLW_FILE_OPEN_FAIL;
}
if (before != NULL && beforeLen)
{
writeTotal = 0;
while (beforeLen > writeTotal)
{
if ((len = XOAL_F_Write(writeFp, before + writeTotal, beforeLen - writeTotal)) == -1)
{
LogDebug("JLW_HTTPD_RecvFile() XOAL_F_Write fail");
XOAL_F_Close(writeFp);
return JLW_FILE_WRITE_FAIL;
}
writeTotal += len;
}
fileLen -= beforeLen;
}
if ((buffer = (U8 *)XOAL_Mem_Malloc(HTTPD_RECV_FILE_BUFF + 1)) == NULL)
{
LogDebug("JLW_HTTPD_RecvFile() XOAL_Mem_Malloc fail");
XOAL_F_Close(writeFp);
return JLW_MEMORY_ALLOC_FAIL;
}
for (recvTotal = 0; recvTotal < fileLen; recvTotal += recvLen)
{
#ifdef __XOAL__SELECT__OK__
if (receiveTimeout > 0)
{
XOAL_NS_FD_ZERO(&readFds);
XOAL_NS_FD_ZERO(&exceptFds);
XOAL_NS_FD_SET(sock, &readFds);
XOAL_NS_FD_SET(sock, &exceptFds);
timeout.tv_sec = receiveTimeout / 1000;
timeout.tv_usec = receiveTimeout % 1000;
#if 0
if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, &exceptFds, &timeout)) <= 0
|| XOAL_NS_FD_ISSET(sock, &exceptFds))
#endif
if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, NULL, &timeout)) <= 0)
{
LogDebug("JLW_HTTPD_RecvFile() XOAL_NS_Select readFds error %d", selectCnt);
JLW_XOAL_Mem_Free(buffer);
XOAL_F_Close(writeFp);
return JLW_NET_RECV_FAIL;
}
}
#endif
if ((recvLen = XOAL_NS_Recv(sock, buffer, HTTPD_RECV_FILE_BUFF, 0)) <= 0)
{
LogDebug("JLW_HTTPD_RecvFile() XOAL_NS_Recv fail");
JLW_XOAL_Mem_Free(buffer);
XOAL_F_Close(writeFp);
return JLW_NET_RECV_FAIL;
}
writeTotal = 0;
while (recvLen > writeTotal)
{
if ((len = XOAL_F_Write(writeFp, buffer + writeTotal, recvLen - writeTotal)) == -1)
{
LogDebug("JLW_HTTPD_RecvFile() XOAL_F_Write fail");
JLW_XOAL_Mem_Free(buffer);
XOAL_F_Close(writeFp);
return JLW_FILE_WRITE_FAIL;
}
writeTotal += len;
}
}
JLW_XOAL_Mem_Free(buffer);
XOAL_F_Close(writeFp);
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HTTPD_MakeFile
*
* Function Description :
* Input :
char *field
char *boundary
int deviceR, char *pathNameR, char *fileNameR
int deviceW, char *pathNameW, int fileNameWLen
* Output :
char *fileNameW : return fileName to write
* Return : int : result
*/
int JLW_HTTPD_MakeFile(char *field, char *boundary, int deviceR, char *pathNameR, char *fileNameR,
int deviceW, char *pathNameW, char *fileNameW, int fileNameWLen)
{
const char strBoundary[] = "\r\n--";
const char g_StrCrLf[] = "\r\n";
const char strRequestEnd[] = "--";
const char strName[] = "name=";
const char strFileName[] = "filename=";
char temp[HTTPD_BUFF_SIZE+1], *posi;
XOF_FILE *readFp, *writeFp;
U8 buffer[2];
int loop, check, workStep, flag, retVal;
if (field == NULL || !strlen(field) || boundary == NULL || !strlen(boundary)
|| deviceR < 0 || pathNameR == NULL || fileNameR == NULL || !strlen(fileNameR)
|| deviceW < 0 || pathNameW == NULL || fileNameW == NULL || fileNameWLen <= 0)
{
LogDebug("JLW_HTTPD_MakeFile() function call data error");
return JLW_CALL_DATA_FAIL;
}
#ifndef __NO_VDMS__
if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, DCA_READ | DCA_BINARY)) == NULL)
#else
if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, "rb")) == NULL)
#endif
{
LogDebug("JLW_HTTPD_MakeFile() file open error %d:%s/%s", deviceR, pathNameR, fileNameR);
return JLW_FILE_OPEN_FAIL;
}
memset(fileNameW, '\0', fileNameWLen+1);
memset(temp, '\0', sizeof(temp));
memset(buffer, '\0', sizeof(buffer));
check = 2; /* file로 저장된 request는 boundary부터 저장된다 */
workStep = 0; /* 0인경우 boundary를 찾음
1인경우 field를 찾음
2인경우 filename을 찾음
3인경우 read start 위치를 찾음 */
while(!XOAL_F_EOF(readFp))
{
if (XOAL_F_Read(readFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Read error");
XOAL_F_Close(readFp);
return JLW_FIELD_NOT_FOUND;
}
if (!workStep)
{
if (!check) /* boundary 시작위치를 찾는다 */
{
if (buffer[0] == strBoundary[check])
check++;
continue;
} else if (check < strlen(strBoundary)) { /* boundary 시작위치를 찾는다 */
if (buffer[0] == strBoundary[check])
{
check++;
continue;
}
} else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
if (buffer[0] == boundary[check - strlen(strBoundary)])
{
check++;
continue;
}
} else {
if (buffer[0] == g_StrCrLf[check - strlen(strBoundary) - strlen(boundary)])
{
check++;
if (check >= (strlen(strBoundary) + strlen(boundary) + strlen(g_StrCrLf)))
{ /* boundary를 찾음 */
workStep = 1;
check = 0;
}
continue;
}
}
check = 0;
if (buffer[0] == strBoundary[check])
check++;
} else if (workStep == 1) {
if (check < strlen(strName)) /* name 시작위치를 찾는다 */
{
if (buffer[0] == strName[check])
check++;
else
check = 0;
} else {
if (check == strlen(strName))
{
if (buffer[0] == '\"' || buffer[0] == '\'')
{
flag = 1;
check++;
continue;
} else
flag = 0;
}
if (check == (strlen(strName) + strlen(field) + flag))
{
check = 0;
if ((flag && (buffer[0] == '\"' || buffer[0] == '\''))
|| (!flag && buffer[0] == ';'))
{
workStep = 2; /* field를 찾았음 */
} else {
workStep = 0;
}
} else if (buffer[0] == field[check - strlen(strName) - flag]) {
check++;
} else {
check = 0;
workStep = 0;
}
}
} else if (workStep == 2) {
if (check < strlen(strFileName)) /* filename= 시작위치를 찾는다 */
{
if (buffer[0] == strFileName[check])
check++;
else
check = 0;
} else {
if (check == strlen(strFileName))
{
if (buffer[0] == '\"' || buffer[0] == '\'')
{
check++;
continue;
}
}
if (buffer[0] == '\"' || buffer[0] == '\'' || buffer[0] == '\r' || buffer[0] == ';')
{
workStep = 3;
if (buffer[0] == '\r') /* g_StrHeaderEnd 늘 찾기위한 시작 */
check = 1;
else
check = 0;
continue;
}
if (strlen(temp) >= (sizeof(temp) - 1))
{
LogDebug("JLW_HTTPD_MakeFile() temp buffer overflow error");
XOAL_F_Close(readFp);
return JLW_BUFFER_OVERFLOW;
}
strcat(temp, (char *)buffer);
}
} else {
if (buffer[0] == g_StrHeaderEnd[check])
check++;
else
check = 0;
if (check >= strlen(g_StrHeaderEnd)) /* read 시작위치를 찾는다 */
{
workStep = 4;
break;
}
}
}
if (workStep < 4)
{
LogDebug("JLW_HTTPD_MakeFile() filename not found");
XOAL_F_Close(readFp);
return JLW_FIELD_NOT_FOUND;
}
JLW_ConvPathName(temp);
if ((posi = strrchr(temp, '\\')))
{
if (strlen(posi + 1) >= (fileNameWLen + 1))
{
LogDebug("JLW_HTTPD_MakeFile() fileNameW buffer overflow error");
XOAL_F_Close(readFp);
return JLW_BUFFER_OVERFLOW;
}
strcpy(fileNameW, posi + 1);
} else {
if (strlen(temp) >= (fileNameWLen+1))
{
LogDebug("JLW_HTTPD_MakeFile() fileNameW buffer overflow error");
XOAL_F_Close(readFp);
return JLW_BUFFER_OVERFLOW;
}
strcpy(fileNameW, temp);
}
JLW_Mkdir(deviceW, pathNameW, FALSE);
#ifndef __NO_VDMS__
if ((writeFp = XOAL_F_Open(deviceW, pathNameW, fileNameW, DCA_WRITE | DCA_CREATE | DCA_BINARY)) == NULL)
#else
if ((writeFp = XOAL_F_Open(deviceW, pathNameW, fileNameW, "w+b")) == NULL)
#endif
{
LogDebug("JLW_HTTPD_MakeFile() file open error %d:%s/%s", deviceW, pathNameW, fileNameW);
XOAL_F_Close(readFp);
return JLW_FILE_OPEN_FAIL;
}
check = 0;
while(!XOAL_F_EOF(readFp))
{
if (XOAL_F_Read(readFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Read error");
retVal = JLW_BOUNDARY_NOT_FOUND;
break;
}
if (!check) /* boundary 시작위치를 찾는다 */
{
if (buffer[0] == strBoundary[check])
{
check++;
} else {
if (XOAL_F_Write(writeFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
}
continue;
} else if (check < strlen(strBoundary)) { /* boundary 시작위치를 찾는다 */
if (buffer[0] == strBoundary[check])
{
check++;
continue;
} else {
if (XOAL_F_Write(writeFp, strBoundary, check) != check)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
}
} else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
if (buffer[0] == boundary[check - strlen(strBoundary)])
{
check++;
continue;
} else {
if (XOAL_F_Write(writeFp, strBoundary, strlen(strBoundary)) != strlen(strBoundary))
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
check -= strlen(strBoundary);
if (XOAL_F_Write(writeFp, boundary, check) != check)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
}
} else {
if ((check - strlen(strBoundary) - strlen(boundary)) == 0)
{
if (buffer[0] == g_StrCrLf[0])
{
check++;
flag = 0; /* crlf 로 종료 */
continue;
} else if (buffer[0] == strRequestEnd[0]) {
check++;
flag = 1; /* -- 로 종료 */
continue;
}
} else {
if ((!flag && buffer[0] == g_StrCrLf[1]) || (flag && buffer[0] == strRequestEnd[1]))
{
retVal = JLW_WORK_OK; /* boundary를 찾음 */
break;
}
}
if (XOAL_F_Write(writeFp, strBoundary, strlen(strBoundary)) != strlen(strBoundary))
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
check -= strlen(strBoundary);
if (XOAL_F_Write(writeFp, boundary, strlen(boundary)) != strlen(boundary))
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
check -= strlen(boundary);
if (check)
{
if (!flag)
{
if (XOAL_F_Write(writeFp, g_StrCrLf, check) != check)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
} else {
if (XOAL_F_Write(writeFp, strRequestEnd, check) != check)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
}
}
}
check = 0;
if (buffer[0] == strBoundary[check])
check++;
else {
if (XOAL_F_Write(writeFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
retVal = JLW_FILE_WRITE_FAIL;
break;
}
}
}
XOAL_F_Close(readFp);
XOAL_F_Close(writeFp);
return retVal;
}
/**
* Function Name : JLW_HTTPD_CopyRequestValue
*
* Function Description :
* Input :
char *buffer
int len
* Output :
JLW_WorkBuff *retBuff : return buffer data & length
* Return : int : result
*/
static int JLW_HTTPD_CopyRequestValue(U8 *buffer, int len, JLW_WorkBuff *retBuff)
{
if (retBuff->buff == NULL || (len + strlen((char *)retBuff->buff)) >= retBuff->len)
{
U8 *temp;
temp = retBuff->buff;
retBuff->len += HTTPD_SMALL_BUFF_SIZE;
if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(retBuff->len + 1)) == NULL)
{
LogDebug("JLW_HTTPD_CopyRequestValue() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
memset(retBuff->buff, '\0', retBuff->len + 1);
if (temp) {
strcpy((char *)retBuff->buff, (char *)temp);
JLW_XOAL_Mem_Free(temp);
}
}
memcpy((char *)retBuff->buff + strlen((char *)retBuff->buff), buffer, len);
return JLW_WORK_OK;
}
/**
* Function Name : JLW_HTTPD_GetFieldFromFile
*
* Function Description :
* Input :
char *field
char *boundary
int deviceR, char *pathNameR, char *fileNameR
* Output :
JLW_WorkBuff *retBuff : return buffer data & length
* Return : int : result
*/
int JLW_HTTPD_GetFieldFromFile(char *field, char *boundary, int deviceR, char *pathNameR, char *fileNameR, JLW_WorkBuff *retBuff)
{
const char strBoundary[] = "\r\n--";
const char strRequestEnd[] = "--";
const char strName[] = "name=";
XOF_FILE *readFp;
U8 buffer[2], *temp;
int check, workStep, flag, retVal;
memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
if (field == NULL || !strlen(field) || boundary == NULL || !strlen(boundary)
|| deviceR < 0 || pathNameR == NULL || fileNameR == NULL || !strlen(fileNameR) || retBuff == NULL)
{
LogDebug("JLW_HTTPD_GetFieldFromFile() function call data error");
return JLW_CALL_DATA_FAIL;
}
#ifndef __NO_VDMS__
if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, DCA_READ | DCA_BINARY)) == NULL)
#else
if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, "rb")) == NULL)
#endif
{
LogDebug("JLW_HTTPD_GetFieldFromFile() file open error %d:%s/%s", deviceR, pathNameR, fileNameR);
return JLW_FILE_OPEN_FAIL;
}
memset(buffer, '\0', sizeof(buffer));
check = 2; /* file로 저장된 request는 boundary부터 저장된다 */
workStep = 0; /* 0인경우 boundary를 찾음
1인경우 field를 찾음
3인경우 read start 위치를 찾음 */
while(!XOAL_F_EOF(readFp))
{
if (XOAL_F_Read(readFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_GetFieldFromFile() XOAL_F_Read error");
XOAL_F_Close(readFp);
return JLW_FIELD_NOT_FOUND;
}
if (!workStep)
{
if (!check) /* boundary 시작위치를 찾는다 */
{
if (buffer[0] == strBoundary[check])
check++;
continue;
} else if (check < strlen(strBoundary)) { /* boundary 시작위치를 찾는다 */
if (buffer[0] == strBoundary[check])
{
check++;
continue;
}
} else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
if (buffer[0] == boundary[check - strlen(strBoundary)])
{
check++;
continue;
}
} else {
if (buffer[0] == g_StrCrLf[check - strlen(strBoundary) - strlen(boundary)])
{
check++;
if (check >= (strlen(strBoundary) + strlen(boundary) + strlen(g_StrCrLf)))
{ /* boundary를 찾음 */
workStep = 1;
check = 0;
}
continue;
}
}
check = 0;
if (buffer[0] == strBoundary[check])
check++;
} else if (workStep == 1) {
if (check < strlen(strName)) /* name 시작위치를 찾는다 */
{
if (buffer[0] == strName[check])
check++;
else
check = 0;
} else {
if (check == strlen(strName))
{
if (buffer[0] == '\"' || buffer[0] == '\'')
{
flag = 1;
check++;
continue;
} else
flag = 0;
}
if (check == (strlen(strName) + strlen(field) + flag))
{
check = 0;
if ((flag && (buffer[0] == '\"' || buffer[0] == '\''))
|| (!flag && (buffer[0] == '\r' || buffer[0] == ';')))
{
workStep = 2; /* field를 찾았음 */
if (buffer[0] == '\r') /* g_StrHeaderEnd 늘 찾기위한 시작 */
check = 1;
else
check = 0;
} else {
workStep = 0;
}
} else if (buffer[0] == field[check - strlen(strName) - flag]) {
check++;
} else {
check = 0;
workStep = 0;
}
}
} else {
if (buffer[0] == g_StrHeaderEnd[check])
check++;
else
check = 0;
if (check >= strlen(g_StrHeaderEnd)) /* read 시작위치를 찾는다 */
{
workStep = 3;
break;
}
}
}
if (workStep < 3)
{
LogDebug("JLW_HTTPD_GetFieldFromFile() filename not found");
XOAL_F_Close(readFp);
return JLW_FIELD_NOT_FOUND;
}
check = 0;
while(!XOAL_F_EOF(readFp))
{
if (XOAL_F_Read(readFp, buffer, 1) != 1)
{
LogDebug("JLW_HTTPD_GetFieldFromFile() XOAL_F_Read error");
retVal = JLW_BOUNDARY_NOT_FOUND;
break;
}
if (!check) /* boundary 시작위치를 찾는다 */
{
if (buffer[0] == strBoundary[check])
check++;
else {
if ((retVal = JLW_HTTPD_CopyRequestValue(buffer, 1, retBuff)))
break;
}
continue;
} else if (check < strlen(strBoundary)) { /* boundary 시작위치를 찾는다 */
if (buffer[0] == strBoundary[check])
{
check++;
continue;
} else {
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, check, retBuff)))
break;
}
} else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
if (buffer[0] == boundary[check - strlen(strBoundary)])
{
check++;
continue;
} else {
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, strlen(strBoundary), retBuff)))
break;
check -= strlen(strBoundary);
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)boundary, check, retBuff)))
break;
}
} else {
if ((check - strlen(strBoundary) - strlen(boundary)) == 0)
{
if (buffer[0] == g_StrCrLf[0])
{
check++;
flag = 0; /* crlf 로 종료 */
continue;
} else if (buffer[0] == strRequestEnd[0]) {
check++;
flag = 1; /* -- 로 종료 */
continue;
}
} else {
if ((!flag && buffer[0] == g_StrCrLf[1]) || (flag && buffer[0] == strRequestEnd[1]))
{
retVal = JLW_WORK_OK; /* boundary를 찾음 */
break;
}
}
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, strlen(strBoundary), retBuff)))
break;
check -= strlen(strBoundary);
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)boundary, strlen(boundary), retBuff)))
break;
check -= strlen(boundary);
if (check)
{
if (!flag)
{
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)g_StrCrLf, check, retBuff)))
break;
} else {
if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strRequestEnd, check, retBuff)))
break;
}
}
}
check = 0;
if (buffer[0] == strBoundary[check])
check++;
else {
if ((retVal = JLW_HTTPD_CopyRequestValue(buffer, 1, retBuff)))
break;
}
}
XOAL_F_Close(readFp);
if (retVal)
{
JLW_XOAL_Mem_Free(retBuff->buff);
memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
}
return retVal;
}
static const JLW_MimeType s_mimeType[] = {
#if 0
{ "abs", "audio/x-mpeg" },
{ "ai", "application/postscript" },
{ "aif", "audio/x-aiff" },
{ "aifc", "audio/x-aiff" },
{ "aiff", "audio/x-aiff" },
{ "aim", "application/x-aim" },
#endif
{ "art", "image/x-jg" },
#if 0
{ "asf", "video/x-ms-asf" },
{ "asx", "video/x-ms-asf" },
{ "au", "audio/basic" },
{ "avi", "video/x-msvideo" },
{ "avx", "video/x-rad-screenplay" },
{ "bcpio", "application/x-bcpio" },
{ "bin", "application/octet-stream" },
#endif
{ "bmp", "image/bmp" },
{ "body", "text/html" },
#if 0
{ "cdf", "application/x-cdf" },
{ "cer", "application/x-x509-ca-cert" },
{ "class", "application/java" },
{ "cpio", "application/x-cpio" },
{ "csh", "application/x-csh" },
#endif
{ "css", "text/css" },
{ "dib", "image/bmp" },
#if 0
{ "doc", "application/msword" },
{ "dtd", "application/xml-dtd" },
{ "dv", "video/x-dv" },
{ "dvi", "application/x-dvi" },
{ "eps", "application/postscript" },
#endif
{ "etx", "text/x-setext" },
{ "exe", "application/octet-stream" },
{ "gif", "image/gif" },
#if 0
{ "gtar", "application/x-gtar" },
{ "gz", "application/x-gzip" },
{ "hdf", "application/x-hdf" },
{ "hqx", "application/mac-binhex40" },
#endif
{ "htc", "text/x-component" },
{ "htm", "text/html" },
{ "html", "text/html" },
#if 0
{ "hqx", "application/mac-binhex40" },
#endif
{ "ief", "image/ief" },
{ "jad", "text/vnd.sun.j2me.app-descriptor" },
#if 0
{ "jar", "application/java-archive" },
#endif
{ "java", "text/plain" },
#if 0
{ "jnlp", "application/x-java-jnlp-file" },
#endif
{ "jpe", "image/jpeg" },
{ "jpeg", "image/jpeg" },
{ "jpg", "image/jpeg" },
{ "js", "text/javascript" },
{ "jsf", "text/plain" },
{ "jspf", "text/plain" },
#if 0
{ "kar", "audio/x-midi" },
{ "latex", "application/x-latex" },
{ "m3u", "audio/x-mpegurl" },
#endif
{ "mac", "image/x-macpaint" },
#if 0
{ "man", "application/x-troff-man" },
{ "mathml", "application/mathml+xml" },
{ "me", "application/x-troff-me" },
{ "mid", "audio/x-midi" },
{ "midi", "audio/x-midi" },
{ "mif", "application/x-mif" },
{ "mov", "video/quicktime" },
{ "movie", "video/x-sgi-movie" },
{ "mp1", "audio/x-mpeg" },
{ "mp2", "audio/x-mpeg" },
{ "mp3", "audio/x-mpeg" },
{ "mp4", "video/mp4" },
{ "mpa", "audio/x-mpeg" },
{ "mpe", "video/mpeg" },
{ "mpeg", "video/mpeg" },
{ "mpega", "audio/x-mpeg" },
{ "mpg", "video/mpeg" },
{ "mpv2", "video/mpeg2" },
{ "ms", "application/x-wais-source" },
{ "nc", "application/x-netcdf" },
{ "oda", "application/oda" },
{ "ogg", "application/ogg" },
#endif
{ "pbm", "image/x-portable-bitmap" },
{ "pct", "image/pict" },
{ "pdf", "application/pdf" },
{ "pgm", "image/x-portable-graymap" },
{ "pic", "image/pict" },
{ "pict", "image/pict" },
#if 0
{ "pls", "audio/x-scpls" },
#endif
{ "png", "image/png" },
{ "pnm", "image/x-portable-anymap" },
{ "pnt", "image/x-macpaint" },
{ "ppm", "image/x-portable-pixmap" },
#if 0
{ "ppt", "application/powerpoint" },
{ "ps", "application/postscript" },
#endif
{ "psd", "image/x-photoshop" },
#if 0
{ "qt", "video/quicktime" },
#endif
{ "qti", "image/x-quicktime" },
{ "qtif", "image/x-quicktime" },
{ "ras", "image/x-cmu-raster" },
#if 0
{ "rdf", "application/rdf+xml" },
#endif
{ "rgb", "image/x-rgb" },
#if 0
{ "rm", "application/vnd.rn-realmedia" },
{ "roff", "application/x-troff" },
{ "rtf", "application/rtf" },
#endif
{ "rtx", "text/richtext" },
#if 0
{ "sh", "application/x-sh" },
{ "shar", "application/x-shar" },
{ "smf", "audio/x-midi" },
{ "sit", "application/x-stuffit" },
{ "snd", "audio/basic" },
{ "src", "application/x-wais-source" },
{ "sv4cpio", "application/x-sv4cpio" },
{ "sv4crc", "application/x-sv4crc" },
{ "swf", "application/x-shockwave-flash" },
{ "t", "application/x-troff" },
{ "tar", "application/x-tar" },
{ "tcl", "application/x-tcl" },
{ "tex", "application/x-tex" },
{ "texi", "application/x-texinfo" },
{ "texinfo", "application/x-texinfo" },
#endif
{ "tif", "image/tiff" },
{ "tiff", "image/tiff" },
#if 0
{ "tr", "application/x-troff" },
#endif
{ "tsv", "text/tab-separated-values" },
{ "txt", "text/plain" },
#if 0
{ "ulw", "audio/basic" },
{ "ustar", "application/x-ustar" },
{ "vxml", "application/voicexml+xml" },
#endif
{ "xbm", "image/x-xbitmap" },
{ "xht", "application/xhtml+xml" },
{ "xhtml", "application/xhtml+xml" },
{ "xml", "application/xml" },
{ "xpm", "image/x-xpixmap" },
{ "xsl", "application/xml" },
{ "xslt", "application/xslt+xml" },
{ "xul", "application/vnd.mozilla.xul+xml" },
{ "xwd", "image/x-xwindowdump" },
#if 0
{ "wav", "audio/x-wav" },
#endif
{ "svg", "image/svg+xml" },
{ "svgz", "image/svg+xml" },
#if 0
{ "vsd", "application/x-visio" },
#endif
{ "wbmp", "image/vnd.wap.wbmp" },
{ "wml", "text/vnd.wap.wml" },
#if 0
{ "wmlc", "application/vnd.wap.wmlc" },
#endif
{ "wmls", "text/vnd.wap.wmlscript" },
#if 0
{ "wmlscriptc", "application/vnd.wap.wmlscriptc" },
{ "wmv", "video/x-ms-wmv" },
{ "wrl", "x-world/x-vrml" },
{ "wspolicy", "application/wspolicy+xml" },
{ "Z", "application/x-compress" },
{ "z", "application/x-compress" },
{ "zip", "application/zip" },
#endif
{ "xls", "application/vnd.ms-excel" },
{ "doc", "application/vnd.ms-word" },
{ "ppt", "application/vnd.ms-powerpoint" },
{ NULL, NULL }
};
/**
* Function Name : JLW_GetMimeType
*
* Function Description : Mime type return
* Input :
* Output :
char *ext
* Return : char * : return mime type
*/
char *JLW_GetMimeType(char *ext)
{
int i;
for (i = 0; s_mimeType[i].ext[0] != '\0'; i++)
{
if (!strcmp(s_mimeType[i].ext, ext))
return (char *)s_mimeType[i].type;
}
return NULL;
}
/**
* Function Name : JLW_MKDir
*
* Function Description :
* Input :
* Output :
S32 nDevice
char *pathName
bool fileInFlag
* Return : int : result
*/
int JLW_Mkdir(S32 nDevice, char *pathName, bool fileInFlag)
{
char *filePosi = NULL, *posi, *next;
int len;
if (fileInFlag)
{
if ((filePosi = strrchr(posi, '\\')))
{
*filePosi = '\0';
} else {
return JLW_WORK_OK;
}
}
posi = pathName + strlen(pathName) - 1;
if (*posi == '\\')
*posi == '\0';
else
posi = pathName;
while ((next = strchr(posi, '\\')))
{
*next = '\0';
XOAL_F_MkDir(nDevice, pathName);
*next = '\\';
posi = next + 1;
}
XOAL_F_MkDir(nDevice, pathName);
return JLW_WORK_OK;
}
/**
* Function Name : JLW_Rmdir
*
* Function Description :
* Input :
* Output :
S32 nDevice
char *pathName
bool fileInFlag
* Return : int : result
*/
int JLW_Rmdir(S32 nDevice, char *pathName, bool fileInFlag)
{
char *filePosi = NULL, *posi;
if (fileInFlag)
{
if ((filePosi = strrchr(posi, '\\')))
{
*filePosi = '\0';
} else {
return JLW_WORK_OK;
}
}
posi = pathName + strlen(pathName) - 1;
if (*posi == '\\')
*posi == '\0';
else
posi = NULL;
XOAL_F_RmDir(nDevice, pathName);
if (posi)
*posi = '\\';
if (filePosi)
*filePosi = '\\';
return JLW_WORK_OK;
}
/**
* Function Name : JLW_Makedir
*
* Function Description :
* Input :
char *basePathName
char *makePathName
* Output :
char *retPathName
* Return :
*/
void JLW_Makedir(char *basePathName, char *makePathName, char *retPathName)
{
char *posi, *next;
int len;
retPathName[0] = '\0';
if (basePathName == NULL)
basePathName = "";
if (makePathName == NULL)
makePathName = "";
len = strlen(basePathName) + strlen(makePathName);
if (!len)
return;
if (strlen(basePathName))
{
if (*makePathName == '/' || *makePathName == '\\')
next = makePathName+1;
else
next = makePathName;
posi = basePathName + strlen(basePathName) - 1;
if (*posi == '/' || *posi == '\\')
sprintf(retPathName, "%s%s", basePathName, next);
else
sprintf(retPathName, "%s\\%s", basePathName, next);
} else {
strcpy(retPathName, makePathName);
}
JLW_ConvPathName(retPathName);
}
/**
* Function Name : JLW_ConvPathName
*
* Function Description :
* Input :
* Output :
char *pathName
* Return :
*/
void JLW_ConvPathName(char *pathName)
{
char *posi;
if (pathName == NULL)
return;
posi = pathName;
while ((posi = strchr(posi, '/')))
{
*posi = '\\';
posi++;
}
}
----------------------------------------------------------------
Error message send functions
----------------------------------------------------------------
const char g_strHttpStatus200[] = "200 OK";
static const char s_strHttpStatus301[] = "301 Moved Permanently";
static const char s_strHttpStatus302[] = "302 Moved Temporarily";
static const char s_strHttpStatus304[] = "304 Not Modified";
static const char s_strHttpStatus400[] = "400 Bad Request";
static const char s_strHttpStatus401[] = "401 Unauthorized";
static const char s_strHttpStatus403[] = "403 Forbidden";
static const char s_strHttpStatus404[] = "404 Not Found";
static const char s_strHttpStatus411[] = "411 Length Required";
static const char s_strHttpStatus412[] = "412 Precondition Failed";
static const char s_strHttpStatus414[] = "414 Request URI Too Long";
static const char s_strHttpStatus416[] = "416 Invalid Range";
static const char s_strHttpStatus500[] = "500 Server Error";
static const char s_strHttpStatus501[] = "501 Not Implemented";
static const char s_strHttpStatus502[] = "502 Bad Gateway";
static const char s_strHttpStatus503[] = "503 Service Unavailable";
static const char s_strHttpStatus505[] = "505 HTTP Version Not Supported";
static const char s_bodyFormat301[] =
"<HTML><HEAD><TITLE>301 Moved Permanently</TITLE></HEAD>\r\n"
"<BODY><H1>301 Moved</H1>The document has moved\r\n"
"<A HREF=\"%s\">here</A>.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat302[] =
"<HTML><HEAD><TITLE>302 Moved Temporarily</TITLE></HEAD>\r\n"
"<BODY><H1>302 Moved</H1>The document has moved\r\n"
"<A HREF=\"%s\">here</A>.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat304[] = "\r\n";
static const char s_bodyFormat400[] =
"<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\r\n"
"<BODY><H1>400 Bad Request</H1>Your client has issued a malformed or illegal request.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat401[] =
"<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\r\n"
"<BODY><H1>401 Unauthorized</H1>Your client does not have permission to get URL %s from this server.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat403[] =
"<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\r\n"
"<BODY><H1>403 Forbidden</H1>Your client does not have permission to get URL %s from this server.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat404[] =
// "<html><head><title>JLW-HttpdServer - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body>"
// "<h1>HTTP Status 404 - %s</h1><HR size=\"1\" noshade=\"noshade\"><p><b>type</b> Status report</p><p><b>message</b> <u>%s</u></p><p><b>description</b> <u>The requested resource (%s) is not available.</u></p><HR size=\"1\" noshade=\"noshade\"><h3>JLW-HttpdServer</h3></body></html>\r\n";
"<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\r\n"
"<BODY><H1>404 Not Found</H1>The requested URL %s was not found on this server.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat411[] =
"<HTML><HEAD><TITLE>411 Length Required</TITLE></HEAD>\r\n"
"<BODY><H1>411 Length Required</H1>The requested URL %s requires that a valid Content-Length header be sent with it.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat412[] =
"<HTML><HEAD><TITLE>412 Precondition Failed</TITLE></HEAD>\r\n"
"<BODY><H1>412 Precondition Failed</H1></BODY></HTML>\r\n";
static const char s_bodyFormat414[] =
"<HTML><HEAD><TITLE>414 Request URI Too Long</TITLE></HEAD>\r\n"
"<BODY><H1>414 Request URI Too Long</H1>Your client has issued a malformed or illegal request.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat416[] =
"<HTML><HEAD><TITLE>416 Invalid Range</TITLE></HEAD>\r\n"
"<BODY><H1>416 Invalid Range</H1></BODY></HTML>\r\n";
static const char s_bodyFormat500[] =
"<HTML><HEAD><TITLE>500 Server Error</TITLE></HEAD>\r\n"
"<BODY><H1>500 Server Error</H1>The server encountered an internal error and could not complete your request.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat501[] =
"<HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD>\r\n"
"<BODY><H1>501 Not Implemented</H1>POST to non-script is not supported\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat502[] =
"<HTML><HEAD><TITLE>502 Bad Gateway</TITLE></HEAD>\r\n"
"<BODY><H1>502 Bad Gateway</H1>The CGI was not CGI/1.1 compliant.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat503[] =
"<HTML><HEAD><TITLE>503 Service Unavailable</TITLE></HEAD>\r\n"
"<BODY><H1>503 Service Unavailable</H1>There are too many connections in use right now.\r\n"
"Please try again later.\r\n"
"</BODY></HTML>\r\n";
static const char s_bodyFormat505[] =
"<HTML><HEAD><TITLE>505 HTTP Version Not Supported</TITLE></HEAD>\r\n"
"<BODY><H1>505 HTTP Version Not Supported</H1>POST to non-script is not supported"
"</BODY></HTML>\r\n";
#if 0
static const char s_bodyFormat200[] =
"<HTML><HEAD><TITLE>JLW Server Test</TITLE></HEAD>\r\n"
"<BODY><H1>HTTP 200 OK test</H1>Hello world"
"</BODY></HTML>\r\n";
#endif
static const JLW_ErrorInfo s_getUrlInfo[] = {
// { FALSE, 200, (char *)g_strHttpStatus200, (char *)s_bodyFormat200 },
{ TRUE, 301, (char *)s_strHttpStatus301, (char *)s_bodyFormat301 },
{ TRUE, 302, (char *)s_strHttpStatus302, (char *)s_bodyFormat302 },
{ FALSE, 304, (char *)s_strHttpStatus304, (char *)s_bodyFormat304 },
{ FALSE, 400, (char *)s_strHttpStatus400, (char *)s_bodyFormat400 },
{ TRUE, 401, (char *)s_strHttpStatus401, (char *)s_bodyFormat401 },
{ TRUE, 403, (char *)s_strHttpStatus403, (char *)s_bodyFormat403 },
{ TRUE, 404, (char *)s_strHttpStatus404, (char *)s_bodyFormat404 },
{ TRUE, 411, (char *)s_strHttpStatus411, (char *)s_bodyFormat411 },
{ FALSE, 412, (char *)s_strHttpStatus412, (char *)s_bodyFormat412 },
{ FALSE, 414, (char *)s_strHttpStatus414, (char *)s_bodyFormat414 },
{ FALSE, 416, (char *)s_strHttpStatus416, (char *)s_bodyFormat416 },
{ FALSE, 500, (char *)s_strHttpStatus500, (char *)s_bodyFormat500 },
{ FALSE, 501, (char *)s_strHttpStatus501, (char *)s_bodyFormat501 },
{ FALSE, 502, (char *)s_strHttpStatus502, (char *)s_bodyFormat502 },
{ FALSE, 503, (char *)s_strHttpStatus503, (char *)s_bodyFormat503 },
{ FALSE, 505, (char *)s_strHttpStatus505, (char *)s_bodyFormat505 },
{ FALSE, 0, NULL, NULL }
};
/**
* Function Name : JLW_HTTPD_SendHttpdError
*
* Function Description :
* Input :
XONS_SOCKET sock
int httpStatus
U8 *url
* Output :
* Return : int : result
*/
int JLW_HTTPD_SendHttpdError(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int httpStatus, char *url)
{
JLW_WorkBuff headBuff, bodyBuff;
int retVal, i;
if (sock < 0 || servInfo == NULL || httpStatus < 0)
{
LogDebug("JLW_HTTPD_SendHttpdError() function call data error");
return JLW_CALL_DATA_FAIL;
}
for (i = 0; ; i++)
{
if (!s_getUrlInfo[i].httpStatus)
return JLW_WORK_FAIL;
if (s_getUrlInfo[i].httpStatus == httpStatus)
break;
}
if (s_getUrlInfo[i].freeCheck)
{
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_getUrlInfo[i].bodyFormat, url, &bodyBuff)))
return retVal;
} else {
bodyBuff.buff = (U8 *)s_getUrlInfo[i].bodyFormat;
bodyBuff.len = strlen(s_getUrlInfo[i].bodyFormat);
}
if ((retVal = JLW_HTTPD_MakeHttpdHeader(s_getUrlInfo[i].strHttpStatus, bodyBuff.len, &headBuff)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
retVal = JLW_HttpdSendBasic(sock, &headBuff, &bodyBuff, servInfo->sendTime);
if (s_getUrlInfo[i].freeCheck)
JLW_XOAL_Mem_Free(bodyBuff.buff);
JLW_XOAL_Mem_Free(headBuff.buff);
if (!JLW_Httpd_Recv(sock, &headBuff, 100, NULL))
JLW_XOAL_Mem_Free(headBuff.buff);
return retVal;
#if 0
JLW_WorkBuff headBuff, bodyBuff;
int retVal;
const char *strHttpStatus;
bool freeCheck = FALSE;
if (sock < 0 || httpStatus < 0)
{
LogDebug("JLW_HTTPD_SendHttpdError() function call data error");
return JLW_CALL_DATA_FAIL;
}
switch (httpStatus)
{
case 301 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat301, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus301;
break;
case 302 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat302, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus302;
break;
case 304 :
memset((char *)&bodyBuff, '\0', sizeof(JLW_WorkBuff));
strHttpStatus = s_strHttpStatus304;
break;
case 400 :
bodyBuff.buff = (U8 *)s_bodyFormat400;
bodyBuff.len = strlen(s_bodyFormat400);
strHttpStatus = s_strHttpStatus400;
break;
case 401 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat401, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus401;
break;
case 403 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat403, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus403;
break;
case 404 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat404, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus404;
break;
case 411 :
freeCheck = TRUE;
if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat411, url, &bodyBuff)))
return retVal;
strHttpStatus = s_strHttpStatus411;
break;
case 412 :
bodyBuff.buff = (U8 *)s_bodyFormat412;
bodyBuff.len = strlen(s_bodyFormat412);
strHttpStatus = s_strHttpStatus412;
break;
case 414 :
bodyBuff.buff = (U8 *)s_bodyFormat414;
bodyBuff.len = strlen(s_bodyFormat414);
strHttpStatus = s_strHttpStatus414;
break;
case 416 :
bodyBuff.buff = (U8 *)s_bodyFormat416;
bodyBuff.len = strlen(s_bodyFormat416);
strHttpStatus = s_strHttpStatus416;
break;
case 500 :
bodyBuff.buff = (U8 *)s_bodyFormat500;
bodyBuff.len = strlen(s_bodyFormat500);
strHttpStatus = s_strHttpStatus500;
break;
case 501 :
bodyBuff.buff = (U8 *)s_bodyFormat501;
bodyBuff.len = strlen(s_bodyFormat501);
strHttpStatus = s_strHttpStatus501;
break;
case 502 :
bodyBuff.buff = (U8 *)s_bodyFormat502;
bodyBuff.len = strlen(s_bodyFormat502);
strHttpStatus = s_strHttpStatus502;
break;
case 503 :
bodyBuff.buff = (U8 *)s_bodyFormat503;
bodyBuff.len = strlen(s_bodyFormat503);
strHttpStatus = s_strHttpStatus503;
break;
case 505 :
bodyBuff.buff = (U8 *)s_bodyFormat505;
bodyBuff.len = strlen(s_bodyFormat505);
strHttpStatus = s_strHttpStatus505;
break;
}
if ((retVal = JLW_HTTPD_MakeHttpdHeader(strHttpStatus, bodyBuff.len, &headBuff)))
{
JLW_XOAL_Mem_Free(bodyBuff.buff);
return retVal;
}
retVal = JLW_HttpdSendBasic(sock, &headBuff, &bodyBuff, servInfo->sendTime);
if (freeCheck)
JLW_XOAL_Mem_Free(bodyBuff.buff);
JLW_XOAL_Mem_Free(headBuff.buff);
return retVal;
#endif
}
/**
* Function Name : JLW_HTTPD_MakeHttpdErrorBody
*
* Function Description :
* Input :
char *bodyFormat
U8 *url
* Output :
JLW_WorkBuff *retBuff : return buffer data & length
* Return : int : result
*/
int JLW_HTTPD_MakeHttpdErrorBody(const char *bodyFormat, char *url, JLW_WorkBuff *retBuff)
{
U32 len;
memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
if (bodyFormat == NULL || !strlen(bodyFormat) || url == NULL || !strlen(url))
{
LogDebug("JLW_HTTPD_MakeHttpdErrorBody() function call data error");
return JLW_CALL_DATA_FAIL;
}
len = strlen(bodyFormat) + strlen(url) - 1 * 2;
if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
{
LogDebug("JLW_HTTPD_MakeHttpdErrorBody() XOAL_Mem_Malloc fail");
return JLW_MEMORY_ALLOC_FAIL;
}
retBuff->len = len;
memset(retBuff->buff, '\0', len + 1);
sprintf((char *)retBuff->buff, bodyFormat, url);
#if 0
{
U8 temp[101];
int i;
LogDebug("JLW_HTTPD_MakeHttpdErrorBody() len=%d", len);
for (i = 0; i < len; i+= 100)
{
strncpy(temp, retBuff->buff+i, 100);
LogDebug("%s", temp);
}
}
#endif
return JLW_WORK_OK;
}