📄 http.c
字号:
// 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 + -