📄 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// post callbacksPFNPOSTCALLBACK g_pfnPost=DefaultWebPostCallback;PFNFILEUPLOADCALLBACK g_pfnFileUpload=DefaultWebFileUploadCallback;#ifdef HTTPAUTHextern DWORD g_dwAuthenticatedNode;extern DWORD g_dwAuthenticationExpirationTime;extern OCTET g_bAuthenticationOn;extern HttpStats g_stats;#endif////////////////////////////////////////////////////////////////////////////// mwFileUploadRegister// Register a MULTIPART FILE UPLOAD callback////////////////////////////////////////////////////////////////////////////PFNFILEUPLOADCALLBACK mwFileUploadRegister(PFNFILEUPLOADCALLBACK pfnUploadCb) { PFNFILEUPLOADCALLBACK pfnUploadPrevCb=g_pfnFileUpload; // save new CB if (pfnUploadCb==NULL) return NULL; g_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_pfnPost; // save new CB if (pfnPostCb==NULL) return NULL; g_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_pfnPost!=NULL); iReturn=(*g_pfnPost)(pp); #ifdef HTTPAUTH switch(iReturn) { case WEBPOST_AUTHENTICATIONON: DEBUG("Http authentication on\n"); g_bAuthenticationOn=TRUE; break; case WEBPOST_AUTHENTICATIONOFF: DEBUG("Http authentication off\n"); g_bAuthenticationOn=FALSE; break; case WEBPOST_AUTHENTICATED: { struct sockaddr_in sinAddress; socklen_t sLength=sizeof(struct sockaddr_in); getpeername(phsSocket->iSocket, (struct sockaddr*)&sinAddress,&sLength); g_dwAuthenticatedNode=ntohl(sinAddress.sin_addr.s_addr); DEBUG("Http authenticated node %s\n", inet_ntoa(sinAddress.sin_addr)); // Set authentication period g_dwAuthenticationExpirationTime = gettime() + HTTPAUTHTIMEOUT; } break; case WEBPOST_NOTAUTHENTICATED: { struct sockaddr_in sinAddress; socklen_t sLength=sizeof(struct sockaddr_in); getpeername(phsSocket->iSocket, (struct sockaddr*)&sinAddress,&sLength); DEBUG("Http authentication fail! (%s NOT authenticated)\n", inet_ntoa(sinAddress.sin_addr)); g_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 = phsSocket->pxMultipartInfo; if (phsSocket == NULL || pxMP == NULL) { _mwCloseSocket(phsSocket); return; } // Grab more POST data from the socket sLength = recv(phsSocket->iSocket, phsSocket->pucData + 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->lExpirationTime=gettime()+HTTPEXPIRATIONTIME; } pxMP->iWriteLocation += (sLength > 0 ? sLength : 0); //ASSERT(pxMP->iWriteLocation <= HTTPMAXRECVBUFFER); // Search new data for boundary indicator pchBoundarySearch = _mwFindMultipartBoundary(phsSocket->pucData, 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_pfnFileUpload)(pxMP->pchFilename, pxMP->oFileuploadStatus, phsSocket->pucData, (DWORD)pchBoundarySearch - (DWORD)phsSocket->pucData); pxMP->pchFilename = NULL; DEBUG("Multipart file POST on socket %d complete\n", phsSocket->iSocket); } else { char *pchStart = _mwStrStrNoCase(phsSocket->pucData, HTTP_MULTIPARTCONTENT); char *pchEnd = _mwStrDword(phsSocket->pucData, HTTP_HEADEREND, 0); char *pchFilename = _mwStrStrNoCase(phsSocket->pucData, HTTP_FILENAME); if (pchStart == NULL || pchEnd == NULL) { DEBUG("Waiting for multipart header description on socket %d\n", phsSocket->iSocket); 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->iSocket); 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 (_mwCheckAuthentication(phsSocket) || (*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->pucData; memmove(phsSocket->pucData, pchEnd, pxMP->iWriteLocation); memset(phsSocket->pucData + pxMP->iWriteLocation, 0, HTTPMAXRECVBUFFER - pxMP->iWriteLocation); break; } else { // move to start of next boundary indicator pchBoundarySearch = pchEnd; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -