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
void* accept_request(void* arg)
{
    pthread_detach(pthread_self());
    
    int sock = (int)arg;
    char buf[_SIZE_];
    char method[_SIZE_];
    char url[_SIZE_];
    char path[_SIZE_];

    memset(buf, '\0', sizeof(buf));
    memset(method, '\0', sizeof(method));
    memset(url, '\0', sizeof(url));
    memset(path, '\0', sizeof(path));
    
    int cgi = 0;
    int ret = -1;
    char* query_string = NULL;

#ifdef _DEBUG_
    do{
        ret = get_line(sock, buf, sizeof(buf));
        printf("%s", buf);
        fflush(stdout);
    } while((ret > 0) && (strcmp(buf, "\n") != 0));
#endif

    ret = get_line(sock, buf, sizeof(buf));
    if(ret < 0)
    {
        echo_errno(sock);
        return (void *)1;
    }

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

    while( (i < sizeof(method)-1) && (j < sizeof(buf)) && (!isspace(buf[j])))
    {
        method[i] = buf[j];
        i++, j++;
    }

    method[i] = '\0';
    while( isspace(buf[j]) )
    {
        j++;
    }

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

    if(strcasecmp(method, "POST") == 0)
    {
        cgi = 1;
    }

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

    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++;
        }
    }

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

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

        if(cgi)
        {
            exec_cgi(sock, path, method, query_string);
        }
        else
        {
            clear_header(sock);
            echo_html(sock, path, st.st_size);
        }
    }

    close(sock);
    return (void*)0;
}