// File: /workspace/github_cpp_makefile_star2_O2/fltflt[P]Tinyhttpd_with_threadpool_epoll/httpd.cpp
// Function: accept_request(void*)
void *accept_request(void* from_client)
{
	int client = *(int *)from_client;
	char buf[1024];
	int numchars;
	char method[255];
	char url[255];
	char path[512];
	size_t i, j;
	struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
	char *query_string = NULL;
//获取一行HTTP报文数据
	numchars = get_line(client, buf, sizeof(buf));
 //
	i = 0; j = 0;
 //对于HTTP报文来说，第一行的内容即为报文的起始行，格式为<method> <request-URL> <version>，
 //每个字段用空白字符相连
	while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
	{
 //提取其中的请求方式是GET还是POST
		method[i] = buf[j];
		i++; j++;
	}
	method[i] = '\0';
//函数说明：strcasecmp()用来比较参数s1 和s2 字符串，比较时会自动忽略大小写的差异。
//返回值：若参数s1 和s2 字符串相同则返回0。s1 长度大于s2 长度则返回大于0 的值，s1 长度若小于s2 长度则返回小于0 的值。
	if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
	{
 //tinyhttp仅仅实现了GET和POST
		unimplemented(client);
		return NULL;
	}
//cgi为标志位，置1说明开启cgi解析
	if (strcasecmp(method, "POST") == 0)
//如果请求方法为POST，需要cgi解析
		cgi = 1;

	i = 0;
 //将method后面的后边的空白字符略过
	while (ISspace(buf[j]) && (j < sizeof(buf)))
		j++;
 //继续读取request-URL
	while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
	{
		url[i] = buf[j];
		i++; j++;
	}
	url[i] = '\0';
//如果是GET请求，url可能会带有?,有查询参数
	if (strcasecmp(method, "GET") == 0)
	{
		query_string = url;
		while ((*query_string != '?') && (*query_string != '\0'))
			query_string++;
		if (*query_string == '?')
		{
  //如果带有查询参数，需要执行cgi，解析参数，设置标志位为1
			cgi = 1;
  //将解析参数截取下来
			*query_string = '\0';
			query_string++;
		}
	}
//以上已经将起始行解析完毕
//url中的路径格式化到path
	sprintf(path, "htdocs%s", url);
//学习到这里明天继续TODO
//如果path只是一个目录，默认设置为首页index.html
	if (path[strlen(path) - 1] == '/')
		strcat(path, "index.html");

 //函数定义:    int stat(const char *file_name, struct stat *buf); 
 //函数说明:    通过文件名filename获取文件信息，并保存在buf所指的结构体stat中 
 //返回值:     执行成功则返回0，失败返回-1，错误代码存于errno（需要include <errno.h>）
	if (stat(path, &st) == -1) {
 //假如访问的网页不存在，则不断的读取剩下的请求头信息，并丢弃即可
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
		numchars = get_line(client, buf, sizeof(buf));
  //最后声明网页不存在
		not_found(client);
	}
	else
	{
 //如果访问的网页存在则进行处理
  if ((st.st_mode & S_IFMT) == S_IFDIR)//S_IFDIR代表目录
 //如果路径是个目录，那就将主页进行显示
  	strcat(path, "/index.html");
  if ((st.st_mode & S_IXUSR) ||
  	(st.st_mode & S_IXGRP) ||
  	(st.st_mode & S_IXOTH)    )
      //S_IXUSR:文件所有者具可执行权限
      //S_IXGRP:用户组具可执行权限
      //S_IXOTH:其他用户具可读取权限  
  	cgi = 1;
  if (!cgi)
  //将静态文件返回
  	serve_file(client, path);
  else
  //执行cgi动态解析
  	execute_cgi(client, path, method, query_string);
  
}

 close(client);//因为http是面向无连接的，所以要关闭

 return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x898, %rsp            # imm = 0x898
movl (%rdi), %ebx
leaq -0x8c0(%rbp), %rsi
movl %ebx, %edi
movl $0x400, %edx            # imm = 0x400
callq 0x395c
movl %eax, %r14d
xorl %r12d, %r12d
movb -0x8c0(%rbp,%r12), %r15b
movsbl %r15b, %edi
callq 0x3040
testl %eax, %eax
jne 0x3716
cmpq $0xfd, %r12
ja 0x3716
movb %r15b, -0x130(%rbp,%r12)
incq %r12
jmp 0x36eb
movb $0x0, -0x130(%rbp,%r12)
leaq 0x38ee(%rip), %rsi      # 0x7014
leaq -0x130(%rbp), %rdi
callq 0x3380
testl %eax, %eax
je 0x3759
leaq 0x38db(%rip), %rsi      # 0x7018
leaq -0x130(%rbp), %rdi
callq 0x3380
testl %eax, %eax
je 0x3759
movl %ebx, %edi
callq 0x3a1e
jmp 0x3948
movl %ebx, -0x2c(%rbp)
leaq 0x38b5(%rip), %rsi      # 0x7018
leaq -0x130(%rbp), %rdi
callq 0x3380
movl %eax, -0x30(%rbp)
movq %r12, %r15
movb -0x8c0(%rbp,%r12), %r13b
movsbl %r13b, %edi
callq 0x3040
incq %r12
cmpq $0x3ff, %r15            # imm = 0x3FF
ja 0x3796
testl %eax, %eax
jne 0x3772
xorl %r15d, %r15d
leaq (%r12,%r15), %rbx
decq %rbx
movsbl %r13b, %edi
callq 0x3040
cmpq $0x3ff, %rbx            # imm = 0x3FF
ja 0x37da
testl %eax, %eax
jne 0x37da
cmpq $0xfd, %r15
ja 0x37da
movb %r13b, -0x430(%rbp,%r15)
leaq (%r15,%rbp), %rax
addq $-0x8c0, %rax           # imm = 0xF740
incq %r15
movb (%r12,%rax), %r13b
jmp 0x3799
cmpl $0x0, -0x30(%rbp)
sete %r13b
movb $0x0, -0x430(%rbp,%r15)
leaq 0x3822(%rip), %rsi      # 0x7014
leaq -0x130(%rbp), %rdi
callq 0x3380
testl %eax, %eax
je 0x380a
xorl %r15d, %r15d
movl -0x2c(%rbp), %ebx
jmp 0x3830
leaq -0x430(%rbp), %r15
movl -0x2c(%rbp), %ebx
movzbl (%r15), %eax
testl %eax, %eax
je 0x3830
cmpl $0x3f, %eax
je 0x3826
incq %r15
jmp 0x3814
movb $0x0, (%r15)
incq %r15
movb $0x1, %r13b
leaq 0x37e6(%rip), %rsi      # 0x701d
leaq -0x330(%rbp), %r12
leaq -0x430(%rbp), %rdx
movq %r12, %rdi
xorl %eax, %eax
callq 0x3060
movq %r12, %rdi
callq 0x3150
cmpb $0x2f, -0x1(%rax,%r12)
jne 0x3888
leaq -0x330(%rbp), %rdi
callq 0x3150
movabsq $0x74682e7865646e69, %rcx # imm = 0x74682E7865646E69
movq %rcx, -0x330(%rbp,%rax)
movl $0x6c6d74, -0x329(%rbp,%rax) # imm = 0x6C6D74
leaq -0x330(%rbp), %rdi
leaq -0x4c0(%rbp), %rsi
callq 0x32c0
cmpl $-0x1, %eax
je 0x3907
movl -0x4a8(%rbp), %r14d
movl %r14d, %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0x4000, %eax           # imm = 0x4000
jne 0x38df
leaq -0x330(%rbp), %rdi
callq 0x3150
movabsq $0x682e7865646e692f, %rcx # imm = 0x682E7865646E692F
movq %rcx, -0x330(%rbp,%rax)
movl $0x6c6d74, -0x328(%rbp,%rax) # imm = 0x6C6D74
testb $0x49, %r14b
setne %al
orb %r13b, %al
leaq -0x330(%rbp), %rsi
testb $0x1, %al
je 0x393a
leaq -0x130(%rbp), %rdx
movl %ebx, %edi
movq %r15, %rcx
callq 0x3e23
jmp 0x3941
leaq -0x8c0(%rbp), %r15
testl %r14d, %r14d
jle 0x3931
cmpw $0xa, -0x8c0(%rbp)
je 0x3931
movl %ebx, %edi
movq %r15, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x395c
movl %eax, %r14d
jmp 0x390e
movl %ebx, %edi
callq 0x3bc4
jmp 0x3941
movl %ebx, %edi
callq 0x3d99
movl %ebx, %edi
callq 0x3560
xorl %eax, %eax
addq $0x898, %rsp            # imm = 0x898
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq