📄 http.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 + -