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

📄 http.c

📁 MINIWEB 0.75, 可以用于嵌入式系统设计。
💻 C
📖 第 1 页 / 共 3 页
字号:
			int i;			//requesting for directory, first try opening default pages			*(p++)=SLASH;			for (i=0; defaultPages[i]; i++) {				strcpy(p,defaultPages[i]);				phsSocket->fd=open(hfp.cFilePath,OPEN_FLAG);				if (phsSocket->fd>=0) break;			}		}		if (phsSocket->fd<0) {			if (!(hp->flags & FLAG_DIR_LISTING)) {				_mwSend404Page(phsSocket);				return -1;			}			SETFLAG(phsSocket,FLAG_DATA_RAW);			if (!hfp.fTailSlash) {				p=phsSocket->request.pucPath;				while(*p) p++;				//seek to the end of the string				SETWORD(p,DEFWORD('/',0));	//add a tailing slash				while(--p>(char*)phsSocket->request.pucPath) {					if (*p=='/') {						p++;						break;					}				}				_mwRedirect(phsSocket,p);			} else {				*(p-1)=0;				_mwListDirectory(phsSocket,hfp.cFilePath);			}			return _mwStartSendRawData(hp, phsSocket);		}		fstat(phsSocket->fd,&st);		phsSocket->response.fileType=HTTPFILETYPE_HTML;	} else {		// open file		phsSocket->fd=open(hfp.cFilePath,OPEN_FLAG);		if (phsSocket->fd<0) {			_mwSend404Page(phsSocket);			return -1;		}		if (hfp.pchExt) {			phsSocket->response.fileType=_mwGetContentType(hfp.pchExt);		}		DEBUG("Local file name: %s\n",hfp.cFilePath);	}	// mark if substitution needed	if (hp->pfnSubst && (phsSocket->response.fileType==HTTPFILETYPE_HTML ||phsSocket->response.fileType==HTTPFILETYPE_JS)) {		SETFLAG(phsSocket,FLAG_SUBST);	}	if (phsSocket->response.iContentLength==0) phsSocket->response.iContentLength=st.st_size-phsSocket->request.iStartByte;	SYSLOG(LOG_INFO,"File/requested size: %d/%d\n",st.st_size,phsSocket->response.iContentLength);	// build http header	phsSocket->iDataLength=_mwBuildHttpHeader(		hp,		phsSocket,		st.st_mtime,		phsSocket->pucData);	phsSocket->response.iSentBytes=-phsSocket->iDataLength;	hp->stats.fileSentCount++;	return 0;} // end of _mwStartSendFile////////////////////////////////////////////////////////////////////////////// _mwSendFileChunk// Send a chunk of a file////////////////////////////////////////////////////////////////////////////int _mwSendFileChunk(HttpParam *hp, HttpSocket* phsSocket){	int iBytesWritten;	int iBytesRead;	// send a chunk of data	iBytesWritten=send(phsSocket->socket, phsSocket->pucData,phsSocket->iDataLength, 0);	if (iBytesWritten<=0) {		// close connection		DEBUG("[%d] error sending data\n", phsSocket->socket);		SETFLAG(phsSocket,FLAG_CONN_CLOSE);		return -1;	}	phsSocket->response.iSentBytes+=iBytesWritten;	phsSocket->pucData+=iBytesWritten;	phsSocket->iDataLength-=iBytesWritten;	SYSLOG(LOG_INFO,"[%d] sent %d bytes of %d\n",phsSocket->socket,phsSocket->response.iSentBytes,phsSocket->response.iContentLength);	// if only partial data sent just return wait the remaining data to be sent next time	if (phsSocket->iDataLength>0)	return 0;	// used all buffered data - load next chunk of file	phsSocket->pucData=phsSocket->buffer;	iBytesRead=read(phsSocket->fd,phsSocket->buffer,HTTP_BUFFER_SIZE);	if (iBytesRead<=0) {		// finished with a file		int iRemainBytes=phsSocket->response.iContentLength-phsSocket->response.iSentBytes;		DEBUG("[%d] EOF reached\n",phsSocket->socket);		if (iRemainBytes>0) {			if (iRemainBytes>HTTP_BUFFER_SIZE) iRemainBytes=HTTP_BUFFER_SIZE;			DEBUG("Sending %d padding bytes\n",iRemainBytes);			memset(phsSocket->buffer,0,iRemainBytes);			phsSocket->iDataLength=iRemainBytes;			return 0;		} else {			DEBUG("Closing file (fd=%d)\n",phsSocket->fd);			hp->stats.fileSentBytes+=phsSocket->response.iSentBytes;			close(phsSocket->fd);			return 1;		}	}	if (ISFLAGSET(phsSocket,FLAG_SUBST)) {		int iBytesUsed;		// substituted file - read smaller chunk		phsSocket->iDataLength=_mwSubstVariables(hp, phsSocket->buffer,iBytesRead,&iBytesUsed);		if (iBytesUsed<iBytesRead) {			lseek(phsSocket->fd,iBytesUsed-iBytesRead,SEEK_CUR);		}	} else {		phsSocket->iDataLength=iBytesRead;	}	return 0;} // end of _mwSendFileChunk////////////////////////////////////////////////////////////////////////////// _mwStartSendRawData// Start sending raw data blocks////////////////////////////////////////////////////////////////////////////int _mwStartSendRawData(HttpParam *hp, HttpSocket* phsSocket){	unsigned char header[HTTP200_HDR_EST_SIZE];	int offset=0,hdrsize,bytes;	hdrsize=_mwBuildHttpHeader(hp, phsSocket,time(NULL),header);	// send http header	do {		bytes=send(phsSocket->socket, header+offset,hdrsize-offset,0);		if (bytes<=0) break;		offset+=bytes;	} while (offset<hdrsize);	if (bytes<=0) {		// failed to send header (socket may have been closed by peer)		SYSLOG(LOG_INFO,"Failed to send header\n");		return -1;	}	return 0;}////////////////////////////////////////////////////////////////////////////// _mwSendRawDataChunk// Send a chunk of a raw data block////////////////////////////////////////////////////////////////////////////int _mwSendRawDataChunk(HttpParam *hp, HttpSocket* phsSocket){	int  iBytesWritten;    // send a chunk of data	if (phsSocket->iDataLength==0) {		if (ISFLAGSET(phsSocket,FLAG_DATA_STREAM) && phsSocket->ptr) {			//FIXME: further implementation of FLAG_DATA_STREAM case		}		hp->stats.fileSentBytes+=phsSocket->response.iSentBytes;		return 1;	}	iBytesWritten=(int)send(phsSocket->socket, phsSocket->pucData,phsSocket->iDataLength, 0);    if (iBytesWritten<=0) {		// failure - close connection		SYSLOG(LOG_INFO,"Connection closed\n");		SETFLAG(phsSocket,FLAG_CONN_CLOSE);		return -1;    } else {		SYSLOG(LOG_INFO,"[%d] sent %d bytes of raw data\n",phsSocket->socket,iBytesWritten);		phsSocket->response.iSentBytes+=iBytesWritten;		phsSocket->pucData+=iBytesWritten;		phsSocket->iDataLength-=iBytesWritten;	}	if (phsSocket->iDataLength<=0 && 			ISFLAGSET(phsSocket,FLAG_DATA_STREAM) &&			phsSocket->response.iSentBytes<phsSocket->response.iContentLength) {		//load next chuck of raw data		UrlHandlerParam uhp;		memset(&uhp,0,sizeof(UrlHandlerParam));		uhp.hp=hp;		uhp.iContentBytes=phsSocket->response.iContentLength;		uhp.iSentBytes=phsSocket->response.iSentBytes;		uhp.pucBuffer=phsSocket->buffer;		uhp.iDataBytes=HTTP_BUFFER_SIZE;		if ((*(PFNURLCALLBACK)(phsSocket->ptr))(&uhp)) {			phsSocket->pucData=uhp.pucBuffer;			phsSocket->iDataLength=uhp.iDataBytes;		}	}	return 0;} // end of _mwSendRawDataChunk////////////////////////////////////////////////////////////////////////////// _mwRedirect// Setup for redirect to another file////////////////////////////////////////////////////////////////////////////void _mwRedirect(HttpSocket* phsSocket, char* pchPath){	// raw (not file) data send mode	SETFLAG(phsSocket,FLAG_DATA_RAW);	// messages is HTML	phsSocket->response.fileType=HTTPFILETYPE_HTML;	// build redirect message	SYSLOG(LOG_INFO,"[%d] Http redirection to %s\n",phsSocket->socket,pchPath);	phsSocket->iDataLength=sprintf(phsSocket->pucData,HTTPBODY_REDIRECT,pchPath);	phsSocket->response.iContentLength=phsSocket->iDataLength;} // end of _mwRedirect////////////////////////////////////////////////////////////////////////////// _mwSubstVariables// Perform substitution of variables in a buffer// returns new length////////////////////////////////////////////////////////////////////////////int _mwSubstVariables(HttpParam* hp, char* pchData, int iLength, int* piBytesUsed){	int lastpos,pos=0,used=0;	SubstParam sp;	int iValueBytes;    DEBUG("_SubstVariables input len %d\n",iLength);	iLength--;	for(;;) {		lastpos=pos;		for (; pos<iLength && *(WORD*)(pchData+pos)!='$$'; pos++);		used+=(pos-lastpos);		if (pos==iLength) {			*piBytesUsed=used+1;			return iLength+1;		}		lastpos=pos;		for (pos=pos+2; pos<iLength && *(WORD*)(pchData+pos)!='$$'; pos++);		if (pos==iLength) {			*piBytesUsed=used;			return lastpos;		}		pos+=2;		used+=pos-lastpos;		pchData[pos-2]=0;		sp.pchParamName=pchData+lastpos+2;		sp.iMaxValueBytes=pos-lastpos;		sp.pchParamValue=pchData+lastpos;		iValueBytes=hp->pfnSubst(&sp);		if (iValueBytes>=0) {			if (iValueBytes>sp.iMaxValueBytes) iValueBytes=sp.iMaxValueBytes;			memmove(pchData+lastpos+iValueBytes,pchData+pos,iLength-pos);			iLength=iLength+iValueBytes-(pos-lastpos);			pos=lastpos+iValueBytes;		} else {			DEBUG("No matched variable for %s\n",sp.pchParamName);			pchData[pos-2]='$';		}	}} // 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;}#if 0////////////////////////////////////////////////////////////////////////////// _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 _mwDecodeString#endifint _mwGetContentType(char *pchExtname){	int i;	int iContentType=HTTPFILETYPE_OCTET;	// check type of file requested	if (*(pchExtname+1)=='\0') {		DEBUG("Unknown content type\n");		return HTTPFILETYPE_OCTET;	} else if (*(pchExtname+3)=='\0' || *(pchExtname+3)=='?') {		//identify 3-char file extensions		for (i=0;fileExtTable[i];i++) {			//logic-and with 0xffdfdfdf gets the uppercase of 3 chars			if ((GETDWORD(pchExtname)&0xffdfdfdf)==fileExtTable[i]) {				iContentType=i;				break;			}		}	} else if (*(pchExtname+4)=='\0' || *(pchExtname+4)=='?') {		//logic-and with 0xdfdfdfdf gets the uppercase of 4 chars		switch (GETDWORD(pchExtname)&0xdfdfdfdf) {		case FILEEXT_HTML:			iContentType=HTTPFILETYPE_HTML;			break;		case FILEEXT_MPEG:			iContentType=HTTPFILETYPE_MPEG;			break;		}	}	return iContentType;}int _mwGrabToken(char *pchToken, char chDelimiter, char *pchBuffer, int iMaxTokenSize){	char *p=pchToken;	int iCharCopied=0;	while (*p && *p!=chDelimiter && iCharCopied<iMaxTokenSize) {		*(pchBuffer++)=*(p++);		iCharCopied++;	}	pchBuffer='\0';	return (*p==chDelimiter)?iCharCopied:0;}int _mwParseHttpHeader(HttpSocket* phsSocket){	int iLen;	char buf[12];	char *p=phsSocket->buffer;		//pointer to header data	HttpRequest *req=&phsSocket->request;	//analyze rest of the header	for(;;) {		//look for a valid field name		while (*p && *p!='\r') p++;		//travel to '\r'		if (!*p || GETDWORD(p)==HTTP_HEADEREND) break;		p+=2;							//skip "\r\n"		switch (*(p++)) {		case 'C':			if (!memcmp(p,"onnection: ",11)) {				p+=11;				if (!memcmp(p,"close",5)) {					SETFLAG(phsSocket,FLAG_CONN_CLOSE);					p+=5;				}			} else if (!memcmp(p,"ontent-Length: ",15)) {				p+=15;				p+=_mwGrabToken(p,'\r',buf,sizeof(buf));				phsSocket->response.iContentLength=atoi(buf);			}			break;		case 'R':			if (!memcmp(p,"eferer: ",8)) {				p+=8;				phsSocket->request.ofReferer=(int)p-(int)phsSocket->buffer;			} else if (!memcmp(p,"ange: bytes=",12)) {				p+=12;				iLen=_mwGrabToken(p,'-',buf,sizeof(buf));				if (iLen==0) continue;				p+=iLen;				phsSocket->request.iStartByte=atoi(buf);				iLen=_mwGrabToken(p,'/',buf,sizeof(buf));				if (iLen==0) continue;				p+=iLen;                phsSocket->response.iContentLength=atoi(buf)-phsSocket->request.iStartByte+1;			}			break;		case 'H':			if (!memcmp(p,"ost: ",5)) {				p+=5;				phsSocket->request.ofHost=(int)p-(int)phsSocket->buffer;			}			break;		}	}	return 0;					//end of header}//////////////////////////// END OF FILE ///////////////////////////////////

⌨️ 快捷键说明

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