⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httppost.c

📁 A small implementation of web server
💻 C
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
// 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 + -