// File: /workspace/github_cpp_makefile_star2_O3/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 $0x8a8, %rsp            # imm = 0x8A8
movl (%rdi), %r12d
leaq -0x8d0(%rbp), %r15
movl %r12d, %edi
movq %r15, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x3b25
movl %eax, %r13d
movb (%r15), %r14b
movsbl %r14b, %edi
callq 0x3050
testl %eax, %eax
je 0x3891
xorl %ebx, %ebx
jmp 0x38c1
xorl %r15d, %r15d
movb %r14b, -0x140(%rbp,%r15)
leaq 0x1(%r15), %rbx
movb -0x8cf(%rbp,%r15), %r14b
movsbl %r14b, %edi
callq 0x3050
testl %eax, %eax
jne 0x38c1
cmpq $0xfd, %r15
movq %rbx, %r15
jb 0x3894
movb $0x0, -0x140(%rbp,%rbx)
leaq 0x3744(%rip), %rsi      # 0x7014
leaq -0x140(%rbp), %rdi
callq 0x3370
testl %eax, %eax
je 0x3904
leaq 0x3731(%rip), %rsi      # 0x7018
leaq -0x140(%rbp), %rdi
callq 0x3370
testl %eax, %eax
je 0x3904
movl %r12d, %edi
callq 0x3bd3
jmp 0x3b11
movl %r13d, -0x30(%rbp)
movl %r12d, -0x34(%rbp)
leaq 0x3705(%rip), %rsi      # 0x7018
leaq -0x140(%rbp), %rdi
callq 0x3370
movl %eax, %r15d
movq %rbx, %r12
movb -0x8d0(%rbp,%rbx), %r14b
movsbl %r14b, %edi
callq 0x3050
incq %rbx
cmpq $0x3ff, %r12            # imm = 0x3FF
ja 0x3946
testl %eax, %eax
jne 0x3922
testl %r15d, %r15d
sete -0x29(%rbp)
xorl %r13d, %r13d
cmpq $0x3ff, %r12            # imm = 0x3FF
ja 0x399c
testl %eax, %eax
jne 0x399c
decq %rbx
xorl %r15d, %r15d
movb %r14b, -0x440(%rbp,%r15)
leaq 0x1(%r15), %r13
movb -0x8cf(%rbp,%rbx), %r14b
movsbl %r14b, %edi
callq 0x3050
cmpq $0x3fe, %rbx            # imm = 0x3FE
ja 0x399c
testl %eax, %eax
jne 0x399c
incq %rbx
cmpq $0xfd, %r15
movq %r13, %r15
jb 0x3963
movb $0x0, -0x440(%rbp,%r13)
leaq 0x3668(%rip), %rsi      # 0x7014
leaq -0x140(%rbp), %rdi
callq 0x3370
testl %eax, %eax
je 0x39c4
xorl %r15d, %r15d
movl -0x30(%rbp), %ebx
jmp 0x39eb
leaq -0x440(%rbp), %r15
movl -0x30(%rbp), %ebx
movzbl (%r15), %eax
testl %eax, %eax
je 0x39eb
cmpl $0x3f, %eax
je 0x39e0
incq %r15
jmp 0x39ce
movb $0x0, (%r15)
incq %r15
movb $0x1, -0x29(%rbp)
leaq 0x362b(%rip), %rsi      # 0x701d
leaq -0x340(%rbp), %r12
leaq -0x440(%rbp), %rdx
movq %r12, %rdi
xorl %eax, %eax
callq 0x3070
movq %r12, %rdi
callq 0x3150
cmpb $0x2f, -0x1(%rax,%r12)
jne 0x3a43
leaq -0x340(%rbp), %rdi
callq 0x3150
movabsq $0x74682e7865646e69, %rcx # imm = 0x74682E7865646E69
movq %rcx, -0x340(%rbp,%rax)
movl $0x6c6d74, -0x339(%rbp,%rax) # imm = 0x6C6D74
leaq -0x340(%rbp), %rdi
leaq -0x4d0(%rbp), %rsi
callq 0x32b0
cmpl $-0x1, %eax
movl -0x34(%rbp), %r12d
je 0x3ac4
movl -0x4b8(%rbp), %ebx
movl %ebx, %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0x4000, %eax           # imm = 0x4000
jne 0x3a9c
leaq -0x340(%rbp), %rdi
callq 0x3150
movabsq $0x682e7865646e692f, %rcx # imm = 0x682E7865646E692F
movq %rcx, -0x340(%rbp,%rax)
movl $0x6c6d74, -0x338(%rbp,%rax) # imm = 0x6C6D74
testb $0x49, %bl
setne %al
orb -0x29(%rbp), %al
leaq -0x340(%rbp), %rsi
testb $0x1, %al
je 0x3b01
leaq -0x140(%rbp), %rdx
movl %r12d, %edi
movq %r15, %rcx
callq 0x3fdc
jmp 0x3b09
testl %ebx, %ebx
jle 0x3af7
cmpw $0xa, -0x8d0(%rbp)
je 0x3af7
leaq -0x8d0(%rbp), %r14
movl %r12d, %edi
movq %r14, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x3b25
testl %eax, %eax
jle 0x3af7
cmpw $0xa, -0x8d0(%rbp)
jne 0x3ad9
movl %r12d, %edi
callq 0x3d79
jmp 0x3b09
movl %r12d, %edi
callq 0x3f4e
movl %r12d, %edi
callq 0x3570
xorl %eax, %eax
addq $0x8a8, %rsp            # imm = 0x8A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq