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

📄 http.c

📁 小型的web服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	default:		break;    } 	return;  }    // ready to read  if (bRead && phsSocket->hssState==HTTPSOCKETSTATE_RECEIVING) {    int sLength;    #ifdef HTTPPOST    if (phsSocket->pxMultipartInfo != NULL) {      _mwProcessMultipartPost(phsSocket);      return;    }#endif	if (phsSocket->iBufferLength==phsSocket->iDataLength) {		phsSocket->iBufferLength=phsSocket->iBufferLength<<1;		if (phsSocket->iBufferLength > HTTPMAXRECVBUFFER) {			DEBUG("Error! Http max buffer size reached\n");			// close connection			_mwCloseSocket(phsSocket);			return;		}		DEBUG("Resizing http receive buffer to %d bytes\n",phsSocket->iBufferLength);		phsSocket->pucData=realloc(phsSocket->pucData,phsSocket->iBufferLength);		if (!phsSocket->pucData) {			DEBUG("Out of memory\n");			_mwCloseSocket(phsSocket);			return;		}	}    // read next chunk of data    sLength=recv(phsSocket->iSocket,                    phsSocket->pucData+phsSocket->iDataLength,                   phsSocket->iBufferLength-phsSocket->iDataLength, 0);    if (sLength > 0) {		char pchFilename[128];		int ret=0,i,iPrefixLen;       		// add in new data received		phsSocket->iDataLength+=sLength;				// check if end of request		if (*(DWORD*)(phsSocket->pucData+phsSocket->iDataLength-sizeof(HTTP_HEADEREND))!=				HTTP_HEADEREND) {			DEBUG("Not end\n");			return;			}		// add zero terminator		*(phsSocket->pucData+sLength)=0;		if (!_mwCheckHeader(phsSocket)) {			DEBUG("Error! Unknown request type\n");			// close connection			_mwCloseSocket(phsSocket);  		}		switch (phsSocket->hrtType) {		case HTTPREQTYPE_GET:			// get filename			DEBUG("Http GET for file %s on socket %d\n",phsSocket->pucRequest, phsSocket->iSocket);			if (!_mwCheckAccess(phsSocket)) {				DEBUG("Access denied for %s\n",phsSocket->pucRequest);				_mwCloseSocket(phsSocket);				return;			}			if (g_urlProcCount>0) {				for (i=0;i<g_urlProcCount;i++) {					iPrefixLen=strlen((g_urlProcParams+i)->pchUrlPrefix);					if (!strncmp(phsSocket->pucRequest,(g_urlProcParams+i)->pchUrlPrefix,iPrefixLen)) {						//URL prefix matches						ret=(g_urlProcParams+i)->pfnUrlProcCallback(phsSocket,phsSocket->pucRequest+iPrefixLen);						if (ret) {							DEBUG("URL Preprocessed\n");							break;						}					}				}			}			if (ret==0) {				// check type of file requested				phsSocket->hftFileType=_mwGetLocalFilename(phsSocket->pucRequest,pchFilename,128);				// mark if substitution needed				phsSocket->bSubstitutionNeeded=(g_pfnSubst && 					(phsSocket->hftFileType==HTTPFILETYPE_HTML ||phsSocket->hftFileType==HTTPFILETYPE_JS));				// send requested page				_mwStartSendFile(phsSocket, pchFilename);			} else {				g_stats.urlProcessCount++;				switch(phsSocket->hcsSource){				case HTTPSRC_FILE:					// check type of file requested					phsSocket->hftFileType=_mwGetLocalFilename(phsSocket->pucData,pchFilename,128);					// send specified file					_mwStartSendFile(phsSocket, pchFilename);					break;				case HTTPSRC_MEM:					_mwStartSendMemoryData(phsSocket);					break;				default:					_mwCloseSocket(phsSocket);					return;				}			}			g_stats.reqGetCount++;			break;#ifdef HTTPPOST		case HTTPREQTYPE_POST:			// http POST ....			_mwProcessPost(phsSocket);			g_stats.reqPostCount++;			break;#endif		default:            DEBUG("Error! Http unknown request %s\n",phsSocket->pucRequest);            // close connection            _mwCloseSocket(phsSocket);		}	} else if (sLength<0) {		_mwCloseSocket(phsSocket);		return;	}  }} // end of _mwProcessSocket////////////////////////////////////////////////////////////////////////////// _mwCloseSocket// Close an open connection////////////////////////////////////////////////////////////////////////////void _mwCloseSocket(HttpSocket* phsSocket){  if (phsSocket->hssState != HTTPSOCKETSTATE_NOTINUSE){    if (phsSocket->iSocket != 0) {      DEBUG("Http socket %d closed\n\n",phsSocket->iSocket);#ifdef WIN32	  closesocket(phsSocket->iSocket);#else	  close(phsSocket->iSocket);#endif      phsSocket->iSocket = -1;    }    if (phsSocket->pucData != NULL) {      free(phsSocket->pucData);  	  phsSocket->pucData=NULL;    }    if (phsSocket->iFile > 0) {      close(phsSocket->iFile);    }    if (phsSocket->pxMultipartInfo != NULL) {      int i;      for (i=0;i<phsSocket->pxMultipartInfo->pp.iNumParams;i++) {        free(phsSocket->pxMultipartInfo->pp.stParams[i].pchParamName);        free(phsSocket->pxMultipartInfo->pp.stParams[i].pchParamValue);      }      free(phsSocket->pxMultipartInfo);    }    memset(phsSocket, 0, sizeof(*phsSocket));    phsSocket->hssState=HTTPSOCKETSTATE_NOTINUSE;  } else {    DEBUG("Warning : closing a http socket (phsSkt=%lx) that is already closed ! \n",(DWORD)phsSocket);  }} // end of _mwCloseSocketvoid _mwSendMemoryChunk(HttpSocket* phsSocket){	int iBytesWritten;	if (phsSocket->bHeaderSent) {		if (phsSocket->iDataLength>0) {			iBytesWritten=send(phsSocket->iSocket, phsSocket->pucData, phsSocket->iDataLength, 0);		}		_mwCloseSocket(phsSocket);	} else {		_mwSendHttpHeader(phsSocket,phsSocket->iDataLength);	}}////////////////////////////////////////////////////////////////////////////// _mwStartSendMemoryData// Send memory content////////////////////////////////////////////////////////////////////////////int _mwStartSendMemoryData(HttpSocket* phsSocket){	phsSocket->hssState=HTTPSOCKETSTATE_SENDING;	// and reset expiration timer	phsSocket->lExpirationTime=gettime()+HTTPEXPIRATIONTIME;	return 1;}////////////////////////////////////////////////////////////////////////////// _mwStartSendFile// Setup for sending of a file////////////////////////////////////////////////////////////////////////////void _mwStartSendFile(HttpSocket* phsSocket, char* pchFilename){#ifdef HTTPAUTH  // check if authenticated  if (FALSE == _mwCheckAuthentication(phsSocket)) {    // Not authenticated    if (phsSocket->hftFileType==HTTPFILETYPE_HTML) {      // send password page only      pchFilename=g_chPasswordPage;    }  }#endif	// open filename	phsSocket->iFile=open(pchFilename, 		phsSocket->bSubstitutionNeeded?O_RDONLY:O_RDONLY|0x8000);    // set state to SENDING (actual sending will occur on next select)  phsSocket->hssState=HTTPSOCKETSTATE_SENDING;  // and reset expiration timer  phsSocket->lExpirationTime=gettime()+HTTPEXPIRATIONTIME;} // end of _mwStartSendFileint _mwSendHttpHeader(HttpSocket* phsSocket, int iContentLength){	unsigned char ucHeader[HTTPHEADERSIZE];	ssize_t sBytesWritten;	int iHdrSize;	// build http header	iHdrSize=sprintf(ucHeader,HTTPHEADER_OK,iContentLength,pchFileTypeTable[phsSocket->hftFileType]);	if (phsSocket->iDataLength && HTTPHEADERSIZE-iHdrSize>iContentLength) {		// embed content in header		memcpy(ucHeader+iHdrSize,phsSocket->pucData,phsSocket->iDataLength);		iHdrSize+=phsSocket->iDataLength;	}	// send http header    sBytesWritten=send(phsSocket->iSocket, ucHeader, iHdrSize, 0);	if (sBytesWritten!=iHdrSize) {		// failed to send header (socket may have been closed by peer)		DEBUG("Http failed to send header on %d, %d of %d sent\n",			phsSocket->iSocket,(int)sBytesWritten,			(int)strlen(ucHeader));		_mwCloseSocket(phsSocket);        return 0;	}	phsSocket->bHeaderSent=TRUE;	DEBUG("Http header sent on socket %d\n",                     phsSocket->iSocket);	if (phsSocket->iDataLength==0) {		DEBUG("Content sent with header\n");		_mwCloseSocket(phsSocket);	}	return 1;}////////////////////////////////////////////////////////////////////////////// _mwSendFileChunk// Send a chunk of a file////////////////////////////////////////////////////////////////////////////void _mwSendFileChunk(HttpSocket* phsSocket){  // check if file open  if (phsSocket->iFile>0) {                                    if (!phsSocket->bHeaderSent) {      off_t ofFileSize;                                                	  // get file length      ofFileSize=lseek(phsSocket->iFile,0,SEEK_END);      if (ofFileSize<0) {		DEBUG("Error! Http could not access file\n");		// close connection		_mwCloseSocket(phsSocket);		return;      }	  lseek(phsSocket->iFile,0,SEEK_SET);      DEBUG("Http file size is %d\n",(int)ofFileSize);      // artificially increase file size for substituted files      phsSocket->iExpansionLeft=        (phsSocket->bSubstitutionNeeded)?HTTPSUBSTEXPANSION:0;      ofFileSize+=phsSocket->iExpansionLeft;      // load first chunk of file      phsSocket->iDataLength=_mwLoadFileChunk(phsSocket,                                                 phsSocket->iBufferLength);		// build and send header		_mwSendHttpHeader(phsSocket,ofFileSize);		g_stats.fileSentCount++;		g_stats.fileSentBytes+=ofFileSize;    } else {      int iBytesWritten;      if(phsSocket->pucData != NULL){        // send a chunk of data        iBytesWritten=send(phsSocket->iSocket, phsSocket->pucData,                           phsSocket->iDataLength, 0);        if (iBytesWritten>0) {          DEBUG("Http sent %d bytes of file on socket %d\n",                       iBytesWritten,phsSocket->iSocket);          phsSocket->iDataLength-=iBytesWritten;          if (phsSocket->iDataLength<=0) {            int iBytesRead;            // used all buffered data - load next chunk of file            iBytesRead=_mwLoadFileChunk(phsSocket,                                           min(phsSocket->iBufferLength,                                              HTTPMAXFILECHUNK));            if (iBytesRead>0) {              phsSocket->iDataLength=iBytesRead;            } else {              // end of file              if (phsSocket->bSubstitutionNeeded) {                // finished substituted file. Need to pad with expansion                // bytes                memset(phsSocket->pucData,0x0d,phsSocket->iBufferLength);                if (phsSocket->iExpansionLeft>0) {                  phsSocket->iDataLength=min(phsSocket->iExpansionLeft,                                             phsSocket->iBufferLength);                  phsSocket->iExpansionLeft-=phsSocket->iDataLength;                  DEBUG("Sending %d expansion filler bytes\n",                               phsSocket->iDataLength);                } else {                  _mwCloseSocket(phsSocket);                }              } else {                // finished regular file                _mwCloseSocket(phsSocket);              }            }          } else {            // move remaining data to start of buffer            memmove(phsSocket->pucData, phsSocket->pucData+iBytesWritten,                    phsSocket->iDataLength);          }		} else if (iBytesWritten<=0) {          // close connection          DEBUG("Connection closed by client for socket %d\n",phsSocket->iSocket);          _mwCloseSocket(phsSocket);          return;        }      }    }  } else {    // send file not found header	phsSocket->iDataLength=sprintf(phsSocket->pucData,HTTPHEADER_MISSING,VER_MAJOR,VER_MINOR);	send(phsSocket->iSocket, phsSocket->pucData, phsSocket->iDataLength, 0);    DEBUG("Error! Http file not found\n");    // close connection    _mwCloseSocket(phsSocket);  }} // end of _mwSendFileChunk////////////////////////////////////////////////////////////////////////////// _mwLoadFileChunk// load and substitute a file chunk////////////////////////////////////////////////////////////////////////////int _mwLoadFileChunk(HttpSocket* phsSocket, int iChunkBufferSize){  int iReturnBytes=0;  ssize_t sBytesRead;                                                                  if (phsSocket->bSubstitutionNeeded) {    int iBytesUsed;        // substituted file - read smaller chunk    sBytesRead=read(phsSocket->iFile,phsSocket->pucData,                    iChunkBufferSize-HTTPSUBSTEXPANSION);    ASSERT((int)sBytesRead<=iChunkBufferSize-HTTPSUBSTEXPANSION);        if (sBytesRead>0) {      iReturnBytes=_mwSubstVariables(phsSocket->pucData,                                       sBytesRead,                                       iChunkBufferSize,                                       &iBytesUsed);      ASSERT(iBytesUsed<=(int)sBytesRead);            // update expansion left      phsSocket->iExpansionLeft-=(iReturnBytes-iBytesUsed);            // update file pointer      lseek(phsSocket->iFile,iBytesUsed-sBytesRead,SEEK_CUR);    }  } else {    // normal file    sBytesRead=read(phsSocket->iFile,phsSocket->pucData,                    iChunkBufferSize);    ASSERT((int)sBytesRead<=iChunkBufferSize);    iReturnBytes=sBytesRead;  }  return iReturnBytes;}////////////////////////////////////////////////////////////////////////////// _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;}////////////////////////////////////////////////////////////////////////////// _mwSendRawDataChunk// Send a chunk of a raw data block////////////////////////////////////////////////////////////////////////////void _mwSendRawDataChunk(HttpSocket* phsSocket){  ssize_t sBytesWritten;  ASSERT(phsSocket->bRawDataSend);  ASSERT(phsSocket->pucData!=NULL);  if (!phsSocket->bHeaderSent) {		// build and send header		_mwSendHttpHeader(phsSocket,phsSocket->iDataLength);  } else {    // send a chunk of data    ASSERT(phsSocket->iSocket != 0 );    ASSERT(phsSocket->pucData != NULL);	if (phsSocket->iDataLength==0) {		_mwCloseSocket(phsSocket);		return;	}    sBytesWritten=send(phsSocket->iSocket, phsSocket->pucData,                       phsSocket->iDataLength, 0);    if (sBytesWritten<0) {      // failure - close connection      _mwCloseSocket(phsSocket);      return;    } else {      DEBUG("Http sent %d bytes of raw data on socket %d\n",                   (int)sBytesWritten,phsSocket->iSocket);      phsSocket->iDataLength-=sBytesWritten;      if (phsSocket->iDataLength<=0) {        // used all buffered data - close connection        _mwCloseSocket(phsSocket);      } else {        // move remaining data to start of buffer        memmove(phsSocket->pucData, phsSocket->pucData+sBytesWritten,                phsSocket->iDataLength);      }    }  }} // end of _mwSendRawDataChunk////////////////////////////////////////////////////////////////////////////// _mwRedirect// Setup for redirect to another file////////////////////////////////////////////////////////////////////////////void _mwRedirect(HttpSocket* phsSocket, char* pchFilename){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -