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

📄 http.c

📁 小型的web服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  // free any existing data buffer  free(phsSocket->pucData);  phsSocket->pucData=NULL; // invalidate to prevent double free    // set state to SENDING (actual sending will occur on next select)  phsSocket->hssState=HTTPSOCKETSTATE_SENDING;  // raw (not file) data send mode  phsSocket->bRawDataSend=TRUE;  // reset expiration timer  {    phsSocket->lExpirationTime=gettime()+HTTPEXPIRATIONTIME;  }  // messages is HTML  phsSocket->hftFileType=HTTPFILETYPE_HTML;  // build redirect message  {    DEBUG("Http redirection to file %s on socket %d\n",                 pchFilename, phsSocket->iSocket);    phsSocket->iBufferLength=strlen(HTTPBODY_REDIRECT)+HTTPSUBSTEXPANSION;    phsSocket->pucData=malloc(phsSocket->iBufferLength);    ASSERT(phsSocket->pucData!=NULL);        if (phsSocket->pucData!=NULL) {      int iDummy;      sprintf(phsSocket->pucData,HTTPBODY_REDIRECT,pchFilename);            phsSocket->iDataLength=_mwSubstVariables(phsSocket->pucData,                                                 strlen(phsSocket->pucData),                                                 phsSocket->iBufferLength,                                                 &iDummy);    } else {      // close connection      _mwCloseSocket(phsSocket);    }  }} // end of _mwRedirect////////////////////////////////////////////////////////////////////////////// _mwSubstVariables// Perform substitution of variables in a buffer// returns new length////////////////////////////////////////////////////////////////////////////int _mwSubstVariables(char* pchData, int iLength, int iMaxLength,                         int* piBytesUsed){  int iSubstLength=iLength;  char* pchTemp=pchData;  ASSERT(iMaxLength>iLength);  if (g_pfnSubst==NULL) {    *piBytesUsed=iLength;    return iLength;  }  DEBUG("_SubstVariables input len %d\n",iLength);  // null term the data  if (pchData[iLength-1]!='\0') {    pchData[iLength]='\0';    iSubstLength++;  }    // parse for variables  while((pchTemp=strstr(pchTemp,"$$"))!=NULL) {    char* pchEnd;    pchTemp+=2; // skip past $$    pchEnd=strstr(pchTemp,"$$");    if (pchEnd!=NULL) {      SubstParam sp;      int iReturn;      ASSERT(pchEnd<(pchData+iMaxLength));            *pchEnd='\0';      sp.pchParamName=pchTemp;      // call user substitution function      iReturn=(*g_pfnSubst)(&sp);            if (iReturn) {        int iValueLength;        int iNameLength;        DEBUG("Http subst [%s] = [%s]\n",                     pchTemp,sp.chParamValue);		g_stats.varSubstCount++;        iValueLength=strlen(sp.chParamValue);        ASSERT(iValueLength<MAXSUBSTLENGTH);                iNameLength=4+pchEnd-pchTemp;  // including the $$ each end                if ((iValueLength-iNameLength+iSubstLength)<iMaxLength) {          //move the data following the param          memmove(pchTemp-2+iValueLength, // at end of subst variable                  pchEnd+2, // end of variable name (after the $$)                  iSubstLength+pchData-pchEnd-2);                    // patch in variable          memcpy(pchTemp-2,sp.chParamValue,iValueLength);                    // update length          iSubstLength+=(iValueLength-iNameLength);                    // backup pchTemp to start of subst string          pchTemp-=2;        } else {          DEBUG("Exceeded buffer length\n");          // exceed buffer length - abort with what we have          // backup pchTemp to before the variable          pchTemp-=2;          //*pchEnd='$'; // put back the $ we removed earlier          break;        }      } else {        DEBUG("Variable lookup for %s failed\n",pchTemp);        *pchEnd='$'; // put back the $ we removed earlier        pchTemp=pchEnd+2; // skip past variable      }    } else {      DEBUG("No matching $$ found (partial=%s)\n",                   pchTemp-2);      // we did not find a matching $$. Back up and end substitution      pchTemp-=2;      break;    }    ASSERT(pchTemp<(pchData+iMaxLength));  }  // remove terminating null from subst length  iSubstLength--;  if (pchTemp==NULL) {    // adjust pchTemp to point to terminating null    pchTemp=pchData+iSubstLength;  }  // check for single $ - could be start of a $$ tag  if (pchTemp>pchData && (strcmp(pchTemp-1,"$")==0)) {    DEBUG("Last char maybe a single $\n");    // backup by 1 character    pchTemp--;  }  // calculate bytes used  *piBytesUsed=iLength-strlen(pchTemp);  DEBUG("_mwSubst in=%d, out=%d, used=%d\n",               iLength,(int)(pchTemp-pchData),*piBytesUsed);  return (pchTemp-pchData);} // end of _mwSubstVariables////////////////////////////////////////////////////////////////////////////// _mwStrStrNoCase// Case insensitive version of ststr////////////////////////////////////////////////////////////////////////////char* _mwStrStrNoCase(char* pchHaystack, char* pchNeedle){  char* pchReturn=NULL;  while(*pchHaystack!='\0' && pchReturn==NULL) {    if (toupper(*pchHaystack)==toupper(pchNeedle[0])) {      char* pchTempHay=pchHaystack;      char* pchTempNeedle=pchNeedle;      // start of match      while(*pchTempHay!='\0') {        if(toupper(*pchTempHay)!=toupper(*pchTempNeedle)) {          // failed to match          break;        }        pchTempNeedle++;        pchTempHay++;        if (*pchTempNeedle=='\0') {          // completed match          pchReturn=pchHaystack;          break;        }      }    }    pchHaystack++;  }  return pchReturn;} // end of _mwStrStrNoCase////////////////////////////////////////////////////////////////////////////// _mwStrDword////////////////////////////////////////////////////////////////////////////char* _mwStrDword(char* pchHaystack, DWORD dwSub, DWORD dwCharMask){	char* pchReturn=NULL;	dwCharMask = dwCharMask?(dwCharMask & 0xdfdfdfdf):0xdfdfdfdf;	dwSub &= dwCharMask;	while(*pchHaystack) {		if (((*(DWORD*)pchHaystack) & dwCharMask)==dwSub)			return pchHaystack;	    pchHaystack++;	}	return NULL;}////////////////////////////////////////////////////////////////////////////// _mwDecodeCharacter// Convert and individual character////////////////////////////////////////////////////////////////////////////__inline char _mwDecodeCharacter(char* pchEncodedChar){  char chHex[3];  ASSERT(*pchEncodedChar=='%');    chHex[0]=*(pchEncodedChar+1);  chHex[1]=*(pchEncodedChar+2);  chHex[2]='\0';    // convert from base 16  return (char)strtol(chHex,NULL,16);} // end of _mwDecodeCharacter////////////////////////////////////////////////////////////////////////////// _mwDecodeString// This function converts URLd characters back to ascii. For example// %3A is '.'////////////////////////////////////////////////////////////////////////////void _mwDecodeString(char* pchString){  int bEnd=FALSE;  char* pchInput=pchString;  char* pchOutput=pchString;  do {    switch (*pchInput) {    case '%':      if (*(pchInput+1)=='\0' || *(pchInput+2)=='\0') {        // something not right - terminate the string and abort        *pchOutput='\0';        bEnd=TRUE;      } else {        *pchOutput=_mwDecodeCharacter(pchInput);        pchInput+=3;      }      break;    case '+':      *pchOutput=' ';      pchInput++;      break;    case '\0':      bEnd=TRUE;      // drop through    default:      // copy character      *pchOutput=*pchInput;      pchInput++;    }    pchOutput++;  } while (!bEnd);} // end of _mwDecodeStringint _mwCheckAccess(HttpSocket* phsSocket){	return 1;}int _mwGetContentType(char *pchExtname){	int iContentType=HTTPFILETYPE_OCTET;	// check type of file requested	if (*(pchExtname+1)=='\0') {		DEBUG("Unknown content type\n");		return HTTPFILETYPE_OCTET;	} else if (*(pchExtname+2)=='\0') {		//identify 2-char file extensions		switch (GETDWORD(pchExtname) & 0xffffdfdf) {	//logic-and with 0xffffdfdf gets the uppercase of 2 chars		case FILEEXT_JS:			iContentType=HTTPFILETYPE_JS;			break;		}	} else if (*(pchExtname+3)=='\0' || *(pchExtname+3)=='?') {		//identify 3-char file extensions		switch (GETDWORD(pchExtname) & 0xffdfdfdf) {	//logic-and with 0xffdfdfdf gets the uppercase of 3 chars		case FILEEXT_HTM:			iContentType=HTTPFILETYPE_HTML;			break;		case FILEEXT_TEXT:			iContentType=HTTPFILETYPE_TEXT;			break;		case FILEEXT_GIF:			iContentType=HTTPFILETYPE_GIF;			break;		case FILEEXT_JPG:			iContentType=HTTPFILETYPE_JPEG;			break;		case FILEEXT_PNG:			iContentType=HTTPFILETYPE_PNG;			break;		case FILEEXT_CSS:			iContentType=HTTPFILETYPE_CSS;			break;		case FILEEXT_SWF:			iContentType=HTTPFILETYPE_SWF;			break;		}	} else if (*(pchExtname+4)=='\0' || *(pchExtname+4)=='?') {		switch (GETDWORD(pchExtname) & 0xdfdfdfdf) {	//logic-and with 0xdfdfdfdf gets the uppercase of 4 chars		case FILEEXT_HTML:			iContentType=HTTPFILETYPE_HTML;			break;		}	}	DEBUG("Content type: %s\n",pchFileTypeTable[iContentType]);	return iContentType;}////////////////////////////////////////////////////////////////////////////// _mwGetLocalFilename// This function maps http request to local filename and returns content type////////////////////////////////////////////////////////////////////////////int _mwGetLocalFilename(char *requestFile, char *buffer, int bufsize){	#ifndef WIN32	#define SLASH '/'	#else	#define SLASH '\\'	#endif	char *pchDot=NULL,*p=buffer,*q=requestFile;	int iContentType=HTTPFILETYPE_OCTET;	if (g_webRoot) {		strcpy(buffer,g_webRoot);		p+=strlen(g_webRoot);		if (*(p-1)!=SLASH) {			*p=SLASH;			*(++p)=0;		}	}	while (*q && *q!='?' && q-requestFile<bufsize) {#ifdef WIN32		//change slash to backslash		if (*q=='/') {			*(p++)='\\';			q++;			continue;		}#endif		*p=*(q++);		if (*p=='.') {			pchDot=p;			if (*q=='.') q++;	//avoid '..' appearing in filename for security issue		}		p++;	}	*p=0;	if (q==requestFile || *(q-1)=='/') {		//if requesting for directory, add default page name		strcpy(p,"index.htm");		iContentType=HTTPFILETYPE_HTML;	} else if (pchDot) {		iContentType=_mwGetContentType(pchDot+1);	}	DEBUG("Local file name: %s\n",buffer);	return iContentType;}int _mwGrabToken(char *pchToken, char *pchBuffer, int iMaxTokenSize){	char *p=pchToken;	int iCharCopied=0;	while (*p && *p!=' ' && *p!='\r' && iCharCopied<=iMaxTokenSize) {		*(pchBuffer++)=*(p++);		iCharCopied++;	}	pchBuffer='\0';	return iCharCopied;}#define HEADER_DATA_FREE HEADER_DATA_MAX_SIZE-1-(phsSocket->pucFreeSpace-phsSocket->aucHeaderData)int _mwCheckHeader(HttpSocket* phsSocket){	char *p=phsSocket->pucData;	char *q;	int iLen;	char buf[16];	if (GETDWORD(p)==HTTP_GET) {		phsSocket->hrtType=HTTPREQTYPE_GET;		p+=5;	} else if (GETDWORD(p)==HTTP_POST)  {		phsSocket->hrtType=HTTPREQTYPE_POST;		p+=6;	} else {		phsSocket->hrtType=HTTPREQTYPE_UNKNOWN;		return 0;	}	// look for start of request	for (q=p;*q!=' ';q++) {		if (*q=='\0') return 0;	}	iLen=q-p;	//allocate space for storage of request string	if (iLen>HEADER_DATA_MAX_SIZE-1) {		DEBUG("Request path too long\n");		return 0;	}	phsSocket->pucRequest=phsSocket->aucHeaderData;	//adjust new free header data space pointer	phsSocket->pucFreeSpace=phsSocket->aucHeaderData+iLen+1;	//set zero terminator	*(phsSocket->pucFreeSpace-1)=0;	//store request path	memcpy(phsSocket->pucRequest,p,iLen);	//analyze rest of the header	p=q+9;	//skip "HTTP/1.x"	for(;;) {		//look for a valid domain name		while (*p && *p!='\r') p++;		//travel to '\r'		if (!*p || GETDWORD(p)==HTTP_HEADEREND) {			return 1;					//end of header		}		p+=2;							//skip "\r\n"		if (*p=='C' && !memcmp(p,"Connection: ",12)) {			p+=12;			if (!strncmp(p,"keep-alive",10)) {				phsSocket->sFlags|=FLAG_KEEPALIVE;				p+=10;			}		} else if (*p=='K' && !memcmp(p,"Keep-Alive: ",12)) {			p+=_mwGrabToken(p+12,buf,sizeof(buf)-1);			phsSocket->sKeepAlive=atoi(buf);		} else if (*p=='R' && !memcmp(p,"Referer: ",9)) {			p+=9;			iLen=_mwGrabToken(p,phsSocket->pucFreeSpace,HEADER_DATA_FREE);			phsSocket->pucReferer=phsSocket->pucFreeSpace;			phsSocket->pucFreeSpace+=iLen+1;			p+=iLen;		} else if (*p=='H' && !memcmp(p,"Host: ",6)) {			p+=6;			iLen=_mwGrabToken(p,phsSocket->pucFreeSpace,HEADER_DATA_FREE);			phsSocket->pucHost=phsSocket->pucFreeSpace;			phsSocket->pucFreeSpace+=iLen+1;			p+=iLen;		}	}}//////////////////////////// END OF FILE ///////////////////////////////////

⌨️ 快捷键说明

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