Ejemplo n.º 1
0
static void * accept_request(void *arg)
{
	int sock = (int)arg;
	char buf[_SIZE_];

	char method[_SIZE_/10];
	char url[_SIZE_];
	char path[_SIZE_];

	memset(buf, '\0', sizeof(buf));
	memset(buf, '\0', sizeof(method));
	memset(buf, '\0', sizeof(url));
	memset(buf, '\0', sizeof(path));

	int cgi = 0;
	int ret = -1;
	char *query_string = NULL; // 数据参数
	int len = sizeof(buf) / sizeof(buf[0]);
#ifdef _DEBUG_
	do 
	{
		// http 请求 报文 按行存储
		ret = get_line(sock, buf, len);
		printf("%s", buf);
		fflush(stdout);
	} while (ret > 0 && strcmp(buf, "\n") != 0);
#endif 

	ret = get_line(sock, buf, len); // 获取请求行
printf("line:   %s\n", buf);	
	if (ret < 0)
	{
		echo_errno(sock);
		return (void*)1;
	}

	// GET / HTTP/1.0
	int i = 0; // method index
	int j = 0; // buf index

	// 请求行 包括   【方法(GET/POST)】【url】【HTTP/1.0(1.1)】
	// 获取方法 GET/POST
	while ((i < sizeof(method) - 1) && (j < sizeof(buf)) && (!isspace(buf[j])))
	{
		method[i] = buf[j];
		++i;
		++j;
	}
	method[i] = '\0';
	// strcasecmp 忽略大小写的比较
	if (strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0)
	{
		echo_errno(sock);
		return (void*)2;
	}
	
	// 跳过空格
	while (j < sizeof(buf) && isspace(buf[j]))
	{
		j++;
	}

	i = 0;


	// 获取url url是除了域名 端口号之后的 /。。。
	while ((i < sizeof(url) - 1) && (j < sizeof(buf)) && (!isspace(buf[j])))
	{
		url[i++] = buf[j++];
	}

	url[i] = '\0';
	//GET  所传递的参数 在URL中, 从server的QUERY_STRING 中获取
	//POST 所传递的参数 在 数据包中 从server环境变量中CONTENT_LENGTH 环境变量中获取参数 数据的长度
	
	if (strcasecmp(method, "POST") == 0)
	{
		cgi = 1;
	}
	
	 if (strcasecmp(method, "GET") == 0)
	 {
		 query_string = url;
		 // 路径和数据参数 以?分隔 如 http:// baidu.com /s ?  k = v
		 while (*query_string != '\0' && *query_string != '?')
		 {
			 ++query_string;
		 }

		 if(*query_string == '?') // GET 带参数 需要进一步处理参数
		 {
			 cgi = 1;
			 *query_string++ = '\0';
		 }
	 }

	 // 没指定具体网页 加默认网页 和 根文件夹(安全考虑)
	 sprintf(path, "httpdoc%s", url);
	 if (path[strlen(path) - 1] == '/')
	 {
		strcat(path, "index.html");
	 }


	 // method , query_string, cgi, path
	 struct stat st;
	 if (stat(path, &st) < 0) // 测文件在不在
	 {
		 echo_errno(sock);
		 return (void*)3;
	 }
	 else
	 {
		 if (S_ISDIR(st.st_mode))// 测是不是 文件夹
		 {
			 strcat(path, "/index.html");
		 }
		 else if( (st.st_mode & S_IXUSR) ||\
				(st.st_mode & S_IXGRP) ||\
				(st.st_mode & S_IXOTH))
				//   查看cgi执行权限
		 {
				cgi = 1;
		 }
		 else
		 {}

		 if (cgi)
		 {
			  exec_cgi(sock, method, path,  query_string);
		 }
		 else
		 {
			clear_header(sock); // 
			echo_www(sock, path, st.st_size);
		 }
	 }
}
Ejemplo n.º 2
0
int handler_msg(int sock)       //浏览器请求处理函数
{
	char buf[SIZE];
	int count=get_line(sock,buf);
	int ret=0;
	char method[32];
	char url[SIZE];
	char *query_string=NULL;
	int i=0;
	int j=0;
	int cgi=0;

	//获取请求方法和请求路径
	while(j<count)
	{
		if(isspace(buf[j]))
		{
			break;
		}
		method[i]=buf[j];	
		i++;
		j++;
	}
	method[i]='\0';
	while(isspace(buf[j])&&j<SIZE)      //过滤空格
	{
		j++;
	}

	if(strcasecmp(method,"POST")&&strcasecmp(method,"GET"))
	{
		printf_log("method failed",FATAL);
		echo_error(sock,405);
		ret=5;
		goto end;
	}

	if(strcasecmp(method,"POST")==0)
	{
		cgi=1;
	}	
	
	i=0;
	while(j<count)
	{
		if(isspace(buf[j]))
		{
			break;
		}
		if(buf[j]=='?')
		{
			query_string=&url[i];
			query_string++;
			url[i]='\0';
		}
		else
			url[i]=buf[j];
		j++;
		i++;
	}
	url[i]='\0';

	if(strcasecmp(method,"GET")==0&&query_string!=NULL)
	{
		cgi=1;
	}

	//找到请求的资源路径
	char path[SIZE];
	sprintf(path,"wwwroot%s",url);       
	
	if(path[strlen(path)-1]=='/')              //判断浏览器请求的是不是目录
	{
		strcat(path,"index.html");	     //如果请求的是目录,则就把该目录下的首页返回回去
	}

	struct stat st;           
	if(stat(path,&st)<0)            //获取客户端请求的资源的相关属性
	{
		printf_log("stat path faile\n",FATAL);
		echo_error(sock,404);
		ret=6;
		goto end;
	}
	else
	{
		if(S_ISDIR(st.st_mode))
		{
			strcat(path,"/index.html");
		}

		if(st.st_mode & (S_IXUSR | S_IXOTH | S_IXGRP))
		{
			cgi=1;
		}
	}

	if(cgi)       //请求的是可执行程序或者带参数用cgi程序处理
	{
		ret=excu_cgi(sock,method,path,query_string);           //处理CGI模式的请求
	}
	else
	{
		clear_header(sock);
		ret=echo_www(sock,path,st.st_size);  //如果是GET方法,而且没有参数,请求的也不是可执行程序,则直接返回资源	
	}
	
end:
	close(sock);
	return ret;
}
Ejemplo n.º 3
0
Archivo: httpd.c Proyecto: zw1510/HTTP
static void * accept_request(void* arg)
{
	int sock = (int)arg;
	printf("%d\n",sock);
	char buf[SIZE];
	int ret = 0;
#ifdef _DEBUG_
	do
	{
			ret = get_line(sock,buf,size);
			printf("%s",buf);
			fflush(stdout);
	}while(ret > 0 && strcmp(buf,'\n'));
#endif
	char method[SIZE / 10];
	char url[SIZE];

	char* query_string = NULL;
	int cgi = 0;
	char path[SIZE];
	memset(method,'\0',sizeof(method));
	memset(url,'\0',sizeof(url));

	ret = get_line(sock,buf,sizeof(buf));
	if(ret < 0)
	{
			echo_errno(sock,1);
			return (void*)1;
	}
	printf("%s\n",buf);
	//1 get method
	//GET //xx//yy HTTP/1.1
	int i = 0;
	int j =0;
	while(i< sizeof(method) - 1 && !isspace(buf[j])  && j < sizeof(buf) )
	{
			method[i]=buf[j];
			++i;
			++j;
	}

	method[i] = '\0';

	//2 check method
	if(strcasecmp(method,"GET")!=0 && strcasecmp(method,"POST") != 0)
	{
			echo_errno(sock,1);
			return (void*)2;
	}

	//3 get url first step space
	while(isspace(buf[j]))
	{
			++j;
	}

	i=0;
	while(!isspace(buf[j])&& (i < sizeof(url)-1) && j < sizeof(buf))
	{
		url[i] = buf [j];
		++i;
		++j;

	}

	if(strcasecmp(method,"POST") == 0)
	{
			cgi = 1;
	}
	printf("method: %s,url_path :%s\n ",method,url);

	if(strcasecmp(method,"GET") == 0)
	{
			query_string = url;
			
	}

	char *start = url;
	while( *start != '\0')
	{
			if( *start == '?')
			{
					cgi = 1;
					*start = '\0';
					query_string = start+1;
					break;
			}

			++start;

	}
	sprintf(path,"htdoc%s",url);
	if(path[strlen(path)-1] == '/')
	{
			strcat(path,"index.html");
	}

	//
	printf("path:%s\n",path);
	printf("cgi:%d\n",cgi);
	//method,query_string,cgi,path
	struct stat st;
	if(stat(path,&st) < 0)//default -> htdoc/index.html
	{
			printf("stat error\n");
			echo_errno(sock,1);
			return (void*)-3;
			
	}
	else
	{
			if(S_ISDIR(st.st_mode))
			{
					strcpy(path,"htdoc/index.html");
			}
			if(( st.st_mode & S_IXGRP)||\
					( st.st_mode & S_IXGRP)||\
					st.st_mode & S_IXOTH)
			{
					cgi = 1;
			}
			else
			{}

			//path cgi
			if(cgi)
			{
					printf("cgi mode\n");
					execut_cgi(sock,path,method,query_string);
			}
			else// 请求首页内容
			{
					clear_head(sock);
					echo_www(sock,path,st.st_size);
			}
	}

	close(sock);   //no face link
	return (void*) 0;
}
Ejemplo n.º 4
0
static void* accept_request(void *arg)		//static
{
	int sock = (int)arg;
	char buf[SIZE];
	int len = sizeof(buf)/sizeof(*buf);
	char method[SIZE/10];
	char url[SIZE];
	char path[SIZE];
	int ret = -1;
	int i = 0;
	int j = 0;

	char *query_string = NULL;    //aim at val(can shu)
	int cgi = 0;
#ifdef _DEBUG_
//	do
//	{
//		ret = get_line(sock, buf, len);
//		printf("%s", buf);
//		fflush(stdout);
//	}while(ret > 0 && (strcmp(buf, "\n") != 0) );
#endif

	memset(buf, '\0', sizeof(buf));
	memset(method, '\0', sizeof(method));
	memset(url, '\0', sizeof(url));
	memset(path, '\0', sizeof(buf));

	//Request Line
	ret = get_line(sock, buf, len);
	if(ret <= 0)
	{
		echo_errno(sock);
		return (void*)1;
	}
	i = 0;	//method index
	j = 0;	//buf index
	while((i < (sizeof(method)/sizeof(*method) - 1)) && (j < sizeof(buf)/sizeof(*buf) - 1) && (!isspace(buf[j]) ) )
	{
		method[i] = buf[j];
		++i;
		++j;
	}
	method[i] = '\0';
	if((strcasecmp(method, "GET") != 0) && (strcasecmp(method, "POST")) )
	{
		//echo_errno(sock);
		return (void*)2;
	}

	//URL
	while(isspace(buf[j]))	//Remove Space
	{
		++j;
	}
	i = 0;
	while( ( i < sizeof(url)/sizeof(*url)-1 ) && (j < sizeof(buf)/sizeof(*buf)) && (!isspace(buf[j])) )
	{
		url[i] = buf[j];
		++i;
		++j;
	}
	url[i] = '\0';

	if( strcasecmp(method, "POST") == 0 )
	{
		cgi = 1;
		sprintf(path, "%s", url+1);
	}

	if( strcasecmp(method, "GET") == 0 )
	{
		query_string = url;
		while( *query_string != '\0' && *query_string != '?' )
		{
			query_string++;
		}
		if(*query_string == '?')
		{
			cgi = 1;
			*query_string = '\0';
			++query_string;
		}
	}

	if( strcasecmp(method, "GET") == 0 )
	{
		sprintf(path, "htdoc%s", url);
		if( path[strlen(path)-1] == '/' )
		{
			strcat(path, "index.html");
		}
	}


	struct stat st;
	if( stat(path, &st) < 0 )
	{
		//echo_errno();	//404	
		return (void*)3;
	}
	else	//case : DIR
	{
		if( S_ISDIR(st.st_mode) )
		{
			strcat(path, "index.html");
		}
		else if( (st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) )      //bin(binary file)
		{
			cgi = 1;
		}
		else
		{}   //noting to do
	}
	
	printf("!@!#%@^   %s   !@%@^%\n", buf);
	if(cgi) // u+x file
	{
		printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!cgi\n");
		exe_cgi(sock, method, path, query_string);  //cgi mode
	}
	else  //.jpg   .html ...
	{
		printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!www\n");
		clear_header(sock);  //! important!
		echo_www(sock, path, st.st_size);
	}

	close(sock);
	return 0;

	
}