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

📄 http.c

📁 一个C语言的聊天室源代码
💻 C
字号:
/*
	Version: 0.2.0(alpha)
	Author: Computer_xu
	Email: Computer_xu@sina.com
	HomePage: http://www.socketchat.com
	LastModify: 2001-07-04 (yyyy-mm-dd)
*/

#include "http.h"

/* #define DEBUGMODE */

/* 转换字符串中的%??为字符 */
void a2c(char *str)
{
        char *p;
        char c;

        p=str;
        while( *p!='\0' )
        {
                (*str)=(*p);
                if( *p=='%' )
                {
                        p++;
                        if( 'A' <= *p && *p <= 'F' )        c=((*p)&0x0f)+9;
                        else                                c=(*p)&0x0f;
                        c<<=4;
                        p++;
                        if( 'A' <= *p && *p <= 'F' )        c|=((*p)&0x0f)+9;
                        else                                c|=(*p)&0x0f;
                        (*str)=c;
                }
                if( *p=='+') *str=' ';
                p++; str++;
        }
        (*str)=(*p);
}
/* 获取表单数据 */
FormData *GetFormData(char *content_data)
{
        SPLIT *sp1,*sp2,*sp3,*sp4;
        FormData *fp1,*fp2;
        int i;
        FormData *rp=NULL;

#ifdef DEBUGMODE
	printf("Enter GetFormData...\n");
#endif
        sp1=sp2=split(content_data,"&");
        while(sp1!=NULL && sp1->msg!=NULL )
        {
                fp1=Malloc(sizeof(FormData));
                fp1->name=NULL;
                fp1->value=NULL;

                sp4=sp3=split(sp1->msg,"=");
                for(i=0;i<2;i++)
                {
                        if( sp3!=NULL && sp3->msg!=NULL )
                        {
				a2c(sp3->msg);
#ifdef DEBUGMODE
                                printf("%s\n",sp3->msg);
#endif
                                if(i)
                                {
                                        fp1->value=Malloc(Strlen(sp3->msg)+1);
                                        strcpy(fp1->value,sp3->msg);
                                }
                                else
                                {
                                        fp1->name=Malloc(Strlen(sp3->msg)+1);
                                        strcpy(fp1->name,sp3->msg);
                                }
                        }
                        else        break;
                        sp3=sp3->next;
                }
                free_split(sp4);

                fp1->next=NULL;
                if( rp==NULL )        rp=fp1;
                else                  fp2->next=fp1;
                fp2=fp1;
                sp1=sp1->next;
        }
        free_split(sp2);
#ifdef DEBUGMODE
	printf("Return From GetFormData.\n");
#endif
        return(rp);
}
/* 获取表单中某一变量的值 */
char * GetFormVarValue(FormData *rp,char *var)
{
        FormData *p;
        char *value;

        p=rp;
        if(p==NULL) return(NULL);
        while(p!=NULL)
        {
                if( StrCmp(p->name,var)==0 )
                        return(p->value);
                p=p->next;
        }
	return(NULL);
}
FormData * FreeFD(FormData *rp)
{
	if( rp==NULL )	return(NULL);
	if( rp->name!=NULL )
	{
		Free(rp->name);
		rp->name=NULL;
	}
	if( rp->value!=NULL )
	{
		Free(rp->value);
		rp->value=NULL;
	}
	rp->next=FreeFD(rp->next);
	Free(rp);
	return(NULL);
}
/* 获取Query数据 */
QueryData *GetQueryData(char *string)
{
        SPLIT *sp1,*sp2,*sp3,*sp4;
        QueryData *fp1,*fp2;
        int i;
        QueryData *rp=NULL;

        if( Strlen(string) == 0 ) return;
        sp1=sp2=split(string,"&");
        while(sp1!=NULL && sp1->msg!=NULL )
        {
                fp1=Malloc(sizeof(QueryData));
                fp1->name=NULL;
                fp1->value=NULL;

                sp4=sp3=split(sp1->msg,"=");
                for(i=0;i<2;i++)
                {
                        if( sp3!=NULL && sp3->msg!=NULL )
                        {
				a2c(sp3->msg);
                                /*printf("%s\n",sp3->msg);*/
                                if(i)
                                {
                                        fp1->value=Malloc(Strlen(sp3->msg)+1);
                                        strcpy(fp1->value,sp3->msg);
                                }
                                else
                                {
                                        fp1->name=Malloc(Strlen(sp3->msg)+1);
                                        strcpy(fp1->name,sp3->msg);
                                }
                        }
                        else        break;
                        sp3=sp3->next;
                }
                free_split(sp4);

                fp1->next=NULL;
                if( rp==NULL )        rp=fp1;
                else                  fp2->next=fp1;
                fp2=fp1;
                sp1=sp1->next;
        }
        free_split(sp2);
        return(rp);
}
/* 获取Query中某一变量的值 */
char * GetQueryVarValue(QueryData *rp,char *var)
{
        QueryData *p;
        char *value;

        p=rp;
        if(p==NULL) return(NULL);
        while(p!=NULL)
        {
                if( StrCmp(p->name,var)==0 )
                        return(p->value);
                p=p->next;
        }
        return(NULL);
}
QueryData * FreeQD(QueryData *rp)
{
	if( rp==NULL )	return(NULL);
	if( rp->name!=NULL )
	{
		Free(rp->name);
		rp->name=NULL;
	}
	if( rp->value!=NULL )
	{
		Free(rp->value);
		rp->value=NULL;
	}
	rp->next=FreeQD(rp->next);
	Free(rp);
	return(NULL);
}
/* 从套接口读取数据,超时监测,遇到特殊字符串结束
	目前endstr不被支持,必须填写NULL */
char *Recv(int connfd, int t, char *endstr)
{
	char buf[1025];
	int status;
	fd_set rset;
	struct timeval timeout;
	char *msg;
	unsigned int msg_len=1025, n;

	
	msg = (char *)Malloc(msg_len);
	msg[0] = '\0';

	status=fcntl(connfd,F_GETFL,0);
	fcntl(connfd,F_SETFL,status|O_NONBLOCK);

	FD_ZERO(&rset);
	timeout.tv_sec=t;
	timeout.tv_usec=0;
			
	while(1)
	{
		FD_SET(connfd,&rset);
		if( select(connfd+1,&rset,NULL,NULL,&timeout) < 0 )
		{
			perror("select");
			if( errno==EINTR )	continue;
			else			break;
		}
		if( FD_ISSET(connfd,&rset) )
		{
			unsigned int slen;

			n=recv(connfd,buf,1024,0);	buf[n]='\0';
			slen=Strlen(msg);
			strncpy(&msg[slen],buf,n);
			msg[slen+n]='\0';
			if( n==0 )	break;
			if( endstr != NULL )
			{
			}
			else
			{
				if( strstr(msg, "\r\n\r\n")!=NULL || strstr(msg, "\n\n")!=NULL )
					break;
			}
			msg_len+=1024;
			msg = (char *)Realloc(msg, msg_len);
		}
		else	break; /* timeout */
	}
	fcntl(connfd,F_SETFL,status);
	return(msg);
}

/* 处理从浏览器发来的请求信息 */
/* 在每个请求说明信息中的结尾都有连续的两个换行,在遇到结尾的换行时置engflag为1 */
/* 从socket连接connfd,读去数据,将剩下的数据通过rbuf送到下一个操作 */
RequestInfo *GetRequestInfo(int connfd,char *rbuf)
{
	unsigned int n,m;
	char *Buffer;
	SPLIT *sp1,*sp2,*sp3,*sp4;
	RequestInfo *ret, *p1, *p2;
	int endflag=0;
	char *cp;

#ifdef DEBUGMODE
	printf("Enter GetRequestInfo...\n");
#endif
	ret=NULL;

	Buffer=Recv(connfd,300,NULL);

#ifdef DEBUGMODE
	printf("(%s)\n",Buffer);
#endif
        sp2=sp1=split(Buffer,"\n");

	/* 处理第一行:请求方式 请求目标 HTTP协议版本 */
        if(sp1!=NULL)
        {
		m=0;
		del_ch(sp1->msg,'\r');
		sp4=sp3=split(sp1->msg," ");
		if(sp3!=NULL)
		{
			m++;
			if(sp3->msg!=NULL)
			{
				p1=(RequestInfo *)Malloc(sizeof(RequestInfo));
				p1->next=NULL;
				p1->name=(char *)Malloc(8);
				strcpy(p1->name,"Methods");  /* 请求方式 */
				p1->value=(char *)Malloc(Strlen(sp3->msg)+1);
				strcpy(p1->value,sp3->msg);
				ret=p2=p1;
				sp3=sp3->next;
				m++;
				if( sp3!=NULL && sp3->msg!=NULL)
				{
					p1=(RequestInfo *)Malloc(sizeof(RequestInfo));
					p1->next=NULL;
					p1->name=(char *)Malloc(7);
					strcpy(p1->name,"Action");  /* 请求目标 */
					p1->value=(char *)Malloc(Strlen(sp3->msg)+1);
					strcpy(p1->value,sp3->msg);
					p2->next=p1;
					p2=p1;
					sp3=sp3->next;
					m++;
					if( sp3!=NULL && sp3->msg!=NULL)
					{
						p1=(RequestInfo *)Malloc(sizeof(RequestInfo));
						p1->next=NULL;
						p1->name=(char *)Malloc(8);
						strcpy(p1->name,"HttpVer");  /* http protocol version */
						p1->value=(char *)Malloc(Strlen(sp3->msg)+1);
						strcpy(p1->value,sp3->msg);
						p2->next=p1;
						p2=p1;
						sp3=sp3->next;
						m++;
					}
				}
			}
		}
		free_split(sp4);
	}
	/* 第一行出现错误 */
	if( m<4 )
	{

		free_split(sp2);
		FreeRI(ret);
		Free(Buffer);
#ifdef DEBUGMODE
		printf("Return From GetRequestInfo(1).\n");
#endif
		return(NULL);
	}
#ifdef DEBUGMODE
	if( sp1->msg==NULL )	printf("==NULL##\n\n");
	else			printf("==%s##\n\n",sp1->msg);
#endif
	sp1=sp1->next;
#ifdef DEBUGMODE
	printf("GetRequestInfo(2)...\n");
#endif	
	/* 处理后续的行,包括Accept,Host,Content-Length等信息 */
	while(sp1!=NULL)
	{
		del_ch(sp1->msg,'\r');
#ifdef DEBUGMODE
		if( sp1->msg==NULL )	printf("==NULL##\n\n");
		else			printf("==%s##\n\n",sp1->msg);
#endif
		if( Strlen(sp1->msg) == 0 )
		{
			endflag=1;
#ifdef DEBUGMODE
			printf("Walk sp1 Over!\n");
#endif
			break;
		}
		sp4=sp3=split(sp1->msg,": ");
		while( sp3!=NULL )
		{
			if( sp3->msg!=NULL )
			{
				p1=(RequestInfo *)Malloc(sizeof(RequestInfo));
				p1->next=NULL;
				p1->name=(char *)Malloc(Strlen(sp3->msg)+1);
				strcpy(p1->name,sp3->msg);
				sp3=sp3->next;
				if( sp3!=NULL )
				{
					if( sp3->msg!=NULL )
					{
						p1->value=(char *)Malloc(Strlen(sp3->msg)+1);
						strcpy(p1->value,sp3->msg);
					}
					else	p1->value=NULL;
				}
				else	p1->value=NULL;
				p2->next=p1;
				p2=p1;
			}
			if( sp3!=NULL )	sp3=sp3->next;
		}
		free_split(sp4);
		sp1=sp1->next;
	}
	free_split(sp2);
#ifdef DEBUGMODE
	printf("GetRequestInfo(3)...\n");
#endif
	cp=strstr(Buffer,"\n\n");
	if(cp!=NULL)
	{
		cp+=2;
		if( *cp=='\0' )	rbuf[0]='\0';
		else		strcpy(rbuf,cp);
	}
	else
	{
		cp=strstr(Buffer,"\r\n\r\n");
		if( cp!=NULL)
		{
			cp+=4;
			if( *cp=='\0' )	rbuf[0]='\0';
			else		strcpy(rbuf,cp);
		}
		else	rbuf[0]='\0';
	}
	Free(Buffer);
	/* 删除最后的换行符号 */
#ifdef DEBUGMODE
	printf("Return From GetRequestInfo.\n");
#endif
	return(ret);
}

char * GetRIVarValue(RequestInfo *rp,char *var)
{
        RequestInfo *p;
        char *value;
#ifdef DEBUGMODE
	printf("Enter GetRIVarValue...\n");
#endif
        p=rp;
        if(p==NULL)	return(NULL);
        while(p!=NULL)
        {
                if( StrCmp(p->name,var)==0 )
		{
#ifdef DEBUGMODE
			printf("Return From GetRIVarValue.\n");
#endif
                        return(p->value);
		}
                p=p->next;
        }
#ifdef DEBUGMODE
	printf("Return From GetRIVarValue.\n");
#endif
        return(NULL);
}

RequestInfo * FreeRI(RequestInfo *p)
{
	if( p==NULL )	return(NULL);
	if( p->name!=NULL )
	{
		Free(p->name);
		p->name=NULL;
	}
	if( p->value!=NULL )
	{
		Free(p->value);
		p->value=NULL;
	}
	p->next=FreeRI(p->next);
	Free(p);
	return(NULL);	
}
/* 一次调用,处理所有来自浏览器的请求信息 */
RequestData * GetRequestData(int connfd)
{
	RequestData *p;
	char buf[1025];
	int n;
	int status;
	fd_set rset;
	struct timeval timeout;

#ifdef DEBUGMODE
	printf("Enter GetRequestData...\n");
#endif
	p=(RequestData *)Malloc(sizeof(RequestData));
	p->Request=GetRequestInfo(connfd,buf);
	if( p->Request==NULL )
	{
		Free(p);
		return(NULL);
	}
#ifdef DEBUGMODE
	printf("	Check POST Data...\n");
#endif
	if( StrCmp(GetRIVarValue(p->Request,"Methods"),"POST")==0 )
	{
		unsigned long int length;
		char *form;
		unsigned int ContentOK=1;

		length=atol(GetRIVarValue(p->Request,"Content-Length"));
		form=(char *)Malloc(length+2+1); /* 在请求的最后有一个换行,字节长度不在Content-Length中 */
		strncpy(form,buf,length);	form[length]='\0';

		if( Strlen(form) < length )
		{
			status=fcntl(connfd,F_GETFL,0);
			fcntl(connfd,F_SETFL,status|O_NONBLOCK);

			FD_ZERO(&rset);
			timeout.tv_sec=300;
			timeout.tv_usec=0;
			
			ContentOK=0;

			while(1)
			{
				FD_SET(connfd,&rset);
				if( select(connfd+1,&rset,NULL,NULL,&timeout) < 0 )
				{
					perror("select");
					if( errno==EINTR )	continue;
					else			break;
				}
				if( FD_ISSET(connfd,&rset) )
				{
					unsigned int slen;

					n=recv(connfd,buf,1024,0);	buf[n]='\0';
					slen=Strlen(form);
					strncpy(&form[slen],buf,length-slen);
					slen+=( length-slen>n )?n:(length-slen);
					form[slen]='\0';
					if( n==0 )	break;
					if( slen==length )
					{
						ContentOK=1;
						break;
					}
				}
				else	break; /* timeout */
			}
			fcntl(connfd,F_SETFL,status);
		}
		if( ContentOK )
		{
			del_ch(form,'\r');del_ch(form,'\n');
			p->Form=GetFormData(form);
		}
		else	p->Form=NULL;
		Free(form);
	}
	else	p->Form=NULL;
#ifdef DEBUGMODE
	printf("	Check QUERY Data...\n");
#endif
	if( StrCmp(GetRIVarValue(p->Request,"Methods"),"GET")==0 )
	{
		char *query;

		query=GetRIVarValue(p->Request,"Action");
		query=strstr(query,"?");
		if( query!=NULL )
		{
			query++;
			p->Query=GetQueryData(query);
		}
		else	p->Query=NULL;
	}
	else	p->Query=NULL;
#ifdef DEBUGMODE
	printf("Return From GetRequestData.\n");
#endif
	return(p);
}

RequestData * FreeRD(RequestData *p)
{
	if( p!=NULL )
	{
		if( p->Form!=NULL )
			FreeFD(p->Form);
		if( p->Query!=NULL )
			FreeQD(p->Query);
		if( p->Request!=NULL )
			FreeRI(p->Request);
	}
	Free(p);
	return(NULL);
}

⌨️ 快捷键说明

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