📄 httppost.c
字号:
/////////////////////////////////////////////////////////////////////////////
//
// http.c
//
// MiniWeb HTTP POST implementation for
//
/////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "httppil.h"
#include "httpapi.h"
#include "httpint.h"
#ifdef HTTPPOST
extern HttpParam g_httpParam;
////////////////////////////////////////////////////////////////////////////
// _mwFindMultipartBoundary
// Searches a memory buffer for a multi-part boundary string
////////////////////////////////////////////////////////////////////////////
OCTET* _mwFindMultipartBoundary(OCTET *poHaystack, int iHaystackSize, OCTET *poNeedle)
{
int i;
int iNeedleLength = strlen(poNeedle);
ASSERT(iNeedleLength > 0);
for (i=0; i <= (iHaystackSize-iNeedleLength-2); i++){
if (*(poHaystack+i)==0x0d && *(poHaystack+i+1)==0x0a &&
memcmp(poHaystack+i+2, poNeedle, iNeedleLength) == 0) {
return (poHaystack+i);
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////
// mwFileUploadRegister
// Register a MULTIPART FILE UPLOAD callback
////////////////////////////////////////////////////////////////////////////
PFNFILEUPLOADCALLBACK mwFileUploadRegister(PFNFILEUPLOADCALLBACK pfnUploadCb)
{
PFNFILEUPLOADCALLBACK pfnUploadPrevCb=g_httpParam.pfnFileUpload;
// save new CB
if (pfnUploadCb==NULL) return NULL;
g_httpParam.pfnFileUpload=pfnUploadCb;
// return previous CB (so app can chain onto it)
return pfnUploadPrevCb;
}
////////////////////////////////////////////////////////////////////////////
// mwPostRegister
// Register a POST callback
////////////////////////////////////////////////////////////////////////////
PFNPOSTCALLBACK mwPostRegister(PFNPOSTCALLBACK pfnPostCb)
{
PFNPOSTCALLBACK pfnPostPrevCb=g_httpParam.pfnPost;
// save new CB
if (pfnPostCb==NULL) return NULL;
g_httpParam.pfnPost=pfnPostCb;
// return previous CB (so app can chain onto it)
return pfnPostPrevCb;
}
////////////////////////////////////////////////////////////////////////////
// _mwNotifyPostVars
// Process posted variables and do callback with parameter list
////////////////////////////////////////////////////////////////////////////
void _mwNotifyPostVars(HttpSocket* phsSocket, PostParam *pp)
{
// if found any vars
if (pp->iNumParams>0) {
int iReturn;
// call app callback to process post vars
//ASSERT(g_httpParam.pfnPost!=NULL);
iReturn=(*g_httpParam.pfnPost)(pp);
#ifdef HTTPAUTH
switch(iReturn) {
case WEBPOST_AUTHENTICATIONON:
DEBUG("Http authentication on\n");
SETFLAG(phsSocket,FLAG_AUTHENTICATION)
break;
case WEBPOST_AUTHENTICATIONOFF:
DEBUG("Http authentication off\n");
CLRFLAG(phsSocket,FLAG_AUTHENTICATION)
break;
case WEBPOST_AUTHENTICATED:
{
struct sockaddr_in sinAddress;
socklen_t sLength=sizeof(struct sockaddr_in);
getpeername(phsSocket->socket,
(struct sockaddr*)&sinAddress,&sLength);
g_httpParam.dwAuthenticatedNode=ntohl(sinAddress.sin_addr.s_addr);
DEBUG("Http authenticated node %s\n",
inet_ntoa(sinAddress.sin_addr));
// Set authentication period
g_httpParam.tmAuthExpireTime = time(NULL) + HTTPAUTHTIMEOUT;
}
break;
case WEBPOST_NOTAUTHENTICATED:
{
struct sockaddr_in sinAddress;
socklen_t sLength=sizeof(struct sockaddr_in);
getpeername(phsSocket->socket,
(struct sockaddr*)&sinAddress,&sLength);
DEBUG("Http authentication fail! (%s NOT authenticated)\n",
inet_ntoa(sinAddress.sin_addr));
g_httpParam.dwAuthenticatedNode=0;
}
break;
}
#endif
}
// was a redirect filename returned
if (strlen(pp->chFilename)>0) {
// redirect to specified file
_mwRedirect(phsSocket, pp->chFilename);
} else {
// redirect to index page
_mwRedirect(phsSocket, "/");
}
}
////////////////////////////////////////////////////////////////////////////
// _mwProcessMultipartPost
// Process a multipart POST request
////////////////////////////////////////////////////////////////////////////
void _mwProcessMultipartPost(HttpSocket* phsSocket)
{
int sLength;
char *pchBoundarySearch = NULL;
HttpMultipart *pxMP = (HttpMultipart*)phsSocket->ptr;
if (phsSocket == NULL || pxMP == NULL) {
_mwCloseSocket(phsSocket);
return;
}
// Grab more POST data from the socket
sLength = recv(phsSocket->socket,
phsSocket->buffer + pxMP->iWriteLocation,
HTTPMAXRECVBUFFER - pxMP->iWriteLocation,
0);
if (sLength < 0) {
DEBUG("Socket closed by peer\n");
_mwCloseSocket(phsSocket);
return;
}
else if (sLength > 0) {
// reset expiration timer
phsSocket->tmExpirationTime=time(NULL)+HTTP_EXPIRATION_TIME;
}
pxMP->iWriteLocation += (sLength > 0 ? sLength : 0);
//ASSERT(pxMP->iWriteLocation <= HTTPMAXRECVBUFFER);
// Search new data for boundary indicator
pchBoundarySearch = _mwFindMultipartBoundary(phsSocket->buffer,
HTTPMAXRECVBUFFER,
pxMP->pchBoundaryValue);
while (pchBoundarySearch != NULL) {
if (pxMP->pchFilename != NULL) {
// It's the last chunk of the posted file
// Warning: MAY BE BIGGER THAN HTTPUPLOAD_CHUNKSIZE
pxMP->oFileuploadStatus |= HTTPUPLOAD_LASTCHUNK;
(*g_httpParam.pfnFileUpload)(pxMP->pchFilename,
pxMP->oFileuploadStatus,
phsSocket->buffer,
(DWORD)pchBoundarySearch - (DWORD)phsSocket->buffer);
pxMP->pchFilename = NULL;
DEBUG("Multipart file POST on socket %d complete\n",
phsSocket->socket);
}
else {
char *pchStart = _mwStrStrNoCase(phsSocket->buffer, HTTP_MULTIPARTCONTENT);
char *pchEnd = _mwStrDword(phsSocket->buffer, HTTP_HEADEREND, 0);
char *pchFilename = _mwStrStrNoCase(phsSocket->buffer, HTTP_FILENAME);
if (pchStart == NULL || pchEnd == NULL) {
DEBUG("Waiting for multipart header description on socket %d\n",
phsSocket->socket);
break;
}
if (pchFilename == NULL ||
pchFilename > pchEnd) { // check filename belongs to this variable
// It's a normal (non-file) var
// check we have the entire section (up to start of next boundary)
pchFilename = NULL;
if (strstr(pchEnd+4, "\r\n") == NULL) {
DEBUG("Waiting for multipart variable value on socket %d\n",
phsSocket->socket);
break;
}
}
pchStart+=strlen(HTTP_MULTIPARTCONTENT)+1; // move past first quote
pchEnd=strchr(pchStart,0x22); // find end quote
// Is peer authenticated to post this var?
if (
#ifdef HTTPAUTH
_mwCheckAuthentication(phsSocket) ||
#endif
(*pchStart=='.')) {
pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamName =
calloc(pchEnd-pchStart+1, sizeof(char));
memcpy(pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamName, pchStart,
pchEnd-pchStart);
if (pchFilename!=NULL) {
// use filename as var value
pchStart=pchFilename+strlen(HTTP_FILENAME)+1; // move past first quote
pchEnd=strchr(pchStart,0x22); // find end quote
} else {
// use data as var value
pchStart=_mwStrDword(pchEnd, HTTP_HEADEREND, 0) + 4;
pchEnd=strstr(pchStart,"\r\n");
}
pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamValue =
calloc(pchEnd-pchStart+1, sizeof(char));
memcpy(pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamValue, pchStart,
pchEnd-pchStart);
DEBUG("Http multipart POST var %d [%s]=[%s]\n",
pxMP->pp.iNumParams,
pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamName,
pxMP->pp.stParams[pxMP->pp.iNumParams].pchParamValue);
pxMP->pp.iNumParams++;
if (pchFilename!=NULL) {
pxMP->pchFilename = pxMP->pp.stParams[pxMP->pp.iNumParams-1].pchParamValue;
// shift to start of file data
pxMP->oFileuploadStatus = HTTPUPLOAD_FIRSTCHUNK;
pchEnd=_mwStrDword(pchFilename, HTTP_HEADEREND, 0) + 4; //move past "\r\n\r\n"
pxMP->iWriteLocation -= (DWORD)pchEnd - (DWORD)phsSocket->buffer;
memmove(phsSocket->buffer, pchEnd, pxMP->iWriteLocation);
memset(phsSocket->buffer + pxMP->iWriteLocation, 0,
HTTPMAXRECVBUFFER - pxMP->iWriteLocation);
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -