// File: 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
subq $0x8f0, %rsp            # imm = 0x8F0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x8d4(%rbp)
movq $0x0, -0x8e0(%rbp)
movl -0x14(%rbp), %edi
leaq -0x420(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x3bb0
movl %eax, -0x424(%rbp)
movq $0x0, -0x838(%rbp)
movq $0x0, -0x840(%rbp)
movq -0x840(%rbp), %rax
movsbl -0x420(%rbp,%rax), %edi
callq 0x3050
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x8e1(%rbp)
jne 0x37a4
cmpq $0xfe, -0x838(%rbp)
setb %al
movb %al, -0x8e1(%rbp)
movb -0x8e1(%rbp), %al
testb $0x1, %al
jne 0x37b0
jmp 0x37f5
movq -0x840(%rbp), %rax
movb -0x420(%rbp,%rax), %cl
movq -0x838(%rbp), %rax
movb %cl, -0x530(%rbp,%rax)
movq -0x838(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x838(%rbp)
movq -0x840(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x840(%rbp)
jmp 0x376d
movq -0x838(%rbp), %rax
movb $0x0, -0x530(%rbp,%rax)
leaq -0x530(%rbp), %rdi
leaq 0xb85e(%rip), %rsi      # 0xf070
callq 0x33d0
cmpl $0x0, %eax
je 0x3849
leaq -0x530(%rbp), %rdi
leaq 0xb84a(%rip), %rsi      # 0xf074
callq 0x33d0
cmpl $0x0, %eax
je 0x3849
movl -0x14(%rbp), %edi
callq 0x3ca0
movq $0x0, -0x8(%rbp)
jmp 0x3b96
leaq -0x530(%rbp), %rdi
leaq 0xb81d(%rip), %rsi      # 0xf074
callq 0x33d0
cmpl $0x0, %eax
jne 0x386b
movl $0x1, -0x8d4(%rbp)
movq $0x0, -0x838(%rbp)
movq -0x840(%rbp), %rax
movsbl -0x420(%rbp,%rax), %edi
callq 0x3050
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x8e2(%rbp)
je 0x38ad
cmpq $0x400, -0x840(%rbp) # imm = 0x400
setb %al
movb %al, -0x8e2(%rbp)
movb -0x8e2(%rbp), %al
testb $0x1, %al
jne 0x38b9
jmp 0x38cd
movq -0x840(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x840(%rbp)
jmp 0x3876
jmp 0x38cf
movq -0x840(%rbp), %rax
movsbl -0x420(%rbp,%rax), %edi
callq 0x3050
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x8e3(%rbp)
jne 0x391b
xorl %eax, %eax
cmpq $0xfe, -0x838(%rbp)
movb %al, -0x8e3(%rbp)
jae 0x391b
cmpq $0x400, -0x840(%rbp) # imm = 0x400
setb %al
movb %al, -0x8e3(%rbp)
movb -0x8e3(%rbp), %al
testb $0x1, %al
jne 0x3927
jmp 0x396c
movq -0x840(%rbp), %rax
movb -0x420(%rbp,%rax), %cl
movq -0x838(%rbp), %rax
movb %cl, -0x630(%rbp,%rax)
movq -0x838(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x838(%rbp)
movq -0x840(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x840(%rbp)
jmp 0x38cf
movq -0x838(%rbp), %rax
movb $0x0, -0x630(%rbp,%rax)
leaq -0x530(%rbp), %rdi
leaq 0xb6e7(%rip), %rsi      # 0xf070
callq 0x33d0
cmpl $0x0, %eax
jne 0x3a29
leaq -0x630(%rbp), %rax
movq %rax, -0x8e0(%rbp)
movq -0x8e0(%rbp), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x3f, %ecx
movb %al, -0x8e4(%rbp)
je 0x39d2
movq -0x8e0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
setne %al
movb %al, -0x8e4(%rbp)
movb -0x8e4(%rbp), %al
testb $0x1, %al
jne 0x39de
jmp 0x39f2
movq -0x8e0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x8e0(%rbp)
jmp 0x39a5
movq -0x8e0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3f, %eax
jne 0x3a27
movl $0x1, -0x8d4(%rbp)
movq -0x8e0(%rbp), %rax
movb $0x0, (%rax)
movq -0x8e0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x8e0(%rbp)
jmp 0x3a29
leaq -0x830(%rbp), %rdi
leaq -0x630(%rbp), %rdx
leaq 0xb63b(%rip), %rsi      # 0xf079
movb $0x0, %al
callq 0x3070
leaq -0x830(%rbp), %rdi
callq 0x3170
subq $0x1, %rax
movsbl -0x830(%rbp,%rax), %eax
cmpl $0x2f, %eax
jne 0x3a75
leaq -0x830(%rbp), %rdi
leaq 0xb613(%rip), %rsi      # 0xf083
callq 0x3560
leaq -0x830(%rbp), %rdi
leaq -0x8d0(%rbp), %rsi
callq 0x32f0
cmpl $-0x1, %eax
jne 0x3af4
jmp 0x3a8f
xorl %eax, %eax
cmpl $0x0, -0x424(%rbp)
movb %al, -0x8e5(%rbp)
jle 0x3abf
leaq -0x420(%rbp), %rsi
leaq 0xb8ab(%rip), %rdi      # 0xf359
callq 0x3460
cmpl $0x0, %eax
setne %al
movb %al, -0x8e5(%rbp)
movb -0x8e5(%rbp), %al
testb $0x1, %al
jne 0x3acb
jmp 0x3ae7
movl -0x14(%rbp), %edi
leaq -0x420(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x3bb0
movl %eax, -0x424(%rbp)
jmp 0x3a8f
movl -0x14(%rbp), %edi
callq 0x3f30
jmp 0x3b86
movl -0x8b8(%rbp), %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0x4000, %eax           # imm = 0x4000
jne 0x3b19
leaq -0x830(%rbp), %rdi
leaq 0xb56e(%rip), %rsi      # 0xf082
callq 0x3560
movl -0x8b8(%rbp), %eax
andl $0x40, %eax
cmpl $0x0, %eax
jne 0x3b43
movl -0x8b8(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x3b43
movl -0x8b8(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x3b4d
movl $0x1, -0x8d4(%rbp)
cmpl $0x0, -0x8d4(%rbp)
jne 0x3b67
movl -0x14(%rbp), %edi
leaq -0x830(%rbp), %rsi
callq 0x4210
jmp 0x3b84
movl -0x14(%rbp), %edi
leaq -0x830(%rbp), %rsi
leaq -0x530(%rbp), %rdx
movq -0x8e0(%rbp), %rcx
callq 0x42e0
jmp 0x3b86
movl -0x14(%rbp), %edi
callq 0x35b0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x8f0, %rsp            # imm = 0x8F0
popq %rbp
retq
nopw %cs:(%rax,%rax)