// File: dentiny[P]HTTP-Cache-Proxy/Proxy.cpp
// Function: Proxy::handleRequest(int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void handleRequest(int client_id, int client_fd, const std::string & client_ip)
	{
		int server_fd = -1;
		Request request;

		try
		{
			// try to accept the request,
			// if an error occurs, throw the exception
			try
			{
				request = acceptRequest(client_fd);

				// record request to log
				std::string log_content = std::to_string(client_id) + ": " + request.httpAction + " from " + client_ip + " @ " + request.request_time;
				logger.log(log_content);
			}
			catch(std::exception & e)
			{
				throw e;
			}

			// try to connect server, and get the server fd
			// if an error occurs, throw the exception
			try
			{
				connectServer(request, server_fd);	
			}
			catch(std::exception & e)
			{
				throw e;
			}

			// handle specific http request
			try
			{
				std::string httpAction = request.httpAction;

				// record request to log, applied to GET, POST and CONNECT
				std::string log_content = std::to_string(client_id) + ": Requesting " + request.first_line + " from " + request.url;
				logger.log(log_content);

				if(httpAction == "CONNECT")
				{
					handleConnect(client_id, client_fd, server_fd, request);

					// write tunnel status to log
					std::string log_content = std::to_string(client_id) + ": Tunnel closed";
					logger.log(log_content); 
				}
				else if(httpAction == "GET")
				{
					// for GET http action, check caching first
					// if get return value true,
					// (1) either the cache is valid, has been sent by cache
					// (2) or the cache is invalid, needs to update the cache and resend it to client
					// anyway, the response has been sent to the client
					try
					{
						bool cacheValid = checkCaching(client_id, client_fd, server_fd, request);
						if(!cacheValid)
						{
							handleGetPost(client_id, client_fd, server_fd, request);
						}
					}
					catch(std::exception & e)
					{
						throw e;
					}
				}
				else if(httpAction == "POST")
				{
					std::cout << "begin post action" << std::endl;
					handleGetPost(client_id, client_fd, server_fd, request);
				}	
				else
				{
					throw ProxyException("Unknown HTTP request category");
				}

				// release client and server fd
				close(server_fd);
				close(client_fd);
			}
			catch(std::exception & e)
			{
				throw e;
			}
		}

		// when an exception happens, write the exception into log and quit the thread
		catch(std::exception & e)
		{
			// write exception into log
			std::string errMsg(e.what());
			std::string log_content = std::to_string(client_id) + ": ERROR " + errMsg;
			logger.log(log_content);

			// close the allocated resource
			close(client_fd);
			if(server_fd != -1) close(server_fd);
			return;
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x510, %rsp            # imm = 0x510
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x4b0(%rbp)
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
leaq -0xf8(%rbp), %rdi
callq 0x7610
movq -0x4b0(%rbp), %rsi
movl -0x10(%rbp), %edx
leaq -0x1d0(%rbp), %rdi
callq 0x7690
jmp 0x693f
leaq -0xf8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x79c0
jmp 0x6954
leaq -0x1d0(%rbp), %rdi
callq 0x7a90
movl -0xc(%rbp), %esi
leaq -0x2c0(%rbp), %rdi
callq 0x7bb0
jmp 0x6971
leaq 0x129a8(%rip), %rdx     # 0x19320
leaq -0x2a0(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x7b60
jmp 0x698d
leaq -0xb8(%rbp), %rdx
leaq -0x280(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0x7b10
jmp 0x69a9
leaq 0x12742(%rip), %rdx     # 0x190f2
leaq -0x260(%rbp), %rdi
leaq -0x280(%rbp), %rsi
callq 0x7b60
jmp 0x69c5
movq -0x18(%rbp), %rdx
leaq -0x240(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x7b10
jmp 0x69de
leaq 0x12714(%rip), %rdx     # 0x190f9
leaq -0x220(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x7b60
jmp 0x69fa
leaq -0x200(%rbp), %rdi
leaq -0x220(%rbp), %rsi
leaq -0xf8(%rbp), %rdx
callq 0x7b10
jmp 0x6a16
leaq -0x220(%rbp), %rdi
callq 0x4250
leaq -0x240(%rbp), %rdi
callq 0x4250
leaq -0x260(%rbp), %rdi
callq 0x4250
leaq -0x280(%rbp), %rdi
callq 0x4250
leaq -0x2a0(%rbp), %rdi
callq 0x4250
leaq -0x2c0(%rbp), %rdi
callq 0x4250
movq -0x4b0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x200(%rbp), %rsi
callq 0x7cd0
jmp 0x6a77
leaq -0x200(%rbp), %rdi
callq 0x4250
jmp 0x6c26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6ba3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x7a90
jmp 0x6ba3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6b77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6b6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6b5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6b53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6b47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x4250
leaq -0x240(%rbp), %rdi
callq 0x4250
leaq -0x260(%rbp), %rdi
callq 0x4250
leaq -0x280(%rbp), %rdi
callq 0x4250
leaq -0x2a0(%rbp), %rdi
callq 0x4250
leaq -0x2c0(%rbp), %rdi
callq 0x4250
jmp 0x6ba3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x4250
movl -0x1dc(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x72b3
movq -0x1d8(%rbp), %rdi
callq 0x4120
movq %rax, -0x2c8(%rbp)
movl $0x8, %edi
callq 0x41b0
movq %rax, %rdi
movq %rdi, -0x4b8(%rbp)
movq -0x2c8(%rbp), %rsi
callq 0x7db0
movq -0x4b8(%rbp), %rdi
movq 0x1d3d9(%rip), %rsi     # 0x23fd0
movq 0x1d3f2(%rip), %rdx     # 0x23ff0
callq 0x4610
jmp 0x74fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
callq 0x45d0
jmp 0x6c21
jmp 0x72b3
movq -0x4b0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x7dd0
jmp 0x6c3f
jmp 0x6cd9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
movl -0x1dc(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x72b3
movq -0x1d8(%rbp), %rdi
callq 0x4120
movq %rax, -0x2d0(%rbp)
movl $0x8, %edi
callq 0x41b0
movq %rax, %rdi
movq %rdi, -0x4c0(%rbp)
movq -0x2d0(%rbp), %rsi
callq 0x7db0
movq -0x4c0(%rbp), %rdi
movq 0x1d326(%rip), %rsi     # 0x23fd0
movq 0x1d33f(%rip), %rdx     # 0x23ff0
callq 0x4610
jmp 0x74fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
callq 0x45d0
jmp 0x6cd4
jmp 0x72b3
leaq -0xb8(%rbp), %rsi
leaq -0x2f0(%rbp), %rdi
callq 0x4150
jmp 0x6cee
movl -0xc(%rbp), %esi
leaq -0x390(%rbp), %rdi
callq 0x7bb0
jmp 0x6cff
leaq 0x123f7(%rip), %rdx     # 0x190fd
leaq -0x370(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0x7b60
jmp 0x6d1b
leaq -0xd8(%rbp), %rdx
leaq -0x350(%rbp), %rdi
leaq -0x370(%rbp), %rsi
callq 0x7b10
jmp 0x6d37
leaq 0x123b4(%rip), %rdx     # 0x190f2
leaq -0x330(%rbp), %rdi
leaq -0x350(%rbp), %rsi
callq 0x7b60
jmp 0x6d53
leaq -0x98(%rbp), %rdx
leaq -0x310(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0x7b10
jmp 0x6d6f
leaq -0x330(%rbp), %rdi
callq 0x4250
leaq -0x350(%rbp), %rdi
callq 0x4250
leaq -0x370(%rbp), %rdi
callq 0x4250
leaq -0x390(%rbp), %rdi
callq 0x4250
movq -0x4b0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x310(%rbp), %rsi
callq 0x7cd0
jmp 0x6db8
leaq 0x1234c(%rip), %rsi     # 0x1910b
leaq -0x2f0(%rbp), %rdi
callq 0x81a0
movb %al, -0x4c1(%rbp)
jmp 0x6dd3
movb -0x4c1(%rbp), %al
testb $0x1, %al
jne 0x6de2
jmp 0x6f71
movq -0x4b0(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq -0xf8(%rbp), %r8
callq 0x81d0
jmp 0x6e00
movl -0xc(%rbp), %esi
leaq -0x3d0(%rbp), %rdi
callq 0x7bb0
jmp 0x6e11
leaq 0x122fb(%rip), %rdx     # 0x19113
leaq -0x3b0(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0x7b60
jmp 0x6e2d
leaq -0x3d0(%rbp), %rdi
callq 0x4250
movq -0x4b0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x7cd0
jmp 0x6e52
leaq -0x3b0(%rbp), %rdi
callq 0x4250
jmp 0x71ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x7237
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x722b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6f03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6ef7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x6eeb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x4250
leaq -0x350(%rbp), %rdi
callq 0x4250
leaq -0x370(%rbp), %rdi
callq 0x4250
leaq -0x390(%rbp), %rdi
callq 0x4250
jmp 0x722b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x721f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x4250
jmp 0x721f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x3b0(%rbp), %rdi
callq 0x4250
jmp 0x721f
leaq 0x121ab(%rip), %rsi     # 0x19123
leaq -0x2f0(%rbp), %rdi
callq 0x81a0
movb %al, -0x4c2(%rbp)
jmp 0x6f8c
movb -0x4c2(%rbp), %al
testb $0x1, %al
jne 0x6f9b
jmp 0x7096
movq -0x4b0(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq -0xf8(%rbp), %r8
callq 0x88c0
movb %al, -0x4c3(%rbp)
jmp 0x6fbf
movb -0x4c3(%rbp), %al
andb $0x1, %al
movb %al, -0x3d1(%rbp)
testb $0x1, -0x3d1(%rbp)
jne 0x7071
movq -0x4b0(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq -0xf8(%rbp), %r8
callq 0x9170
jmp 0x6ff8
jmp 0x7071
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
movl -0x1dc(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x721f
movq -0x1d8(%rbp), %rdi
callq 0x4120
movq %rax, -0x3e0(%rbp)
movl $0x8, %edi
callq 0x41b0
movq %rax, %rdi
movq %rdi, -0x4d0(%rbp)
movq -0x3e0(%rbp), %rsi
callq 0x7db0
movq -0x4d0(%rbp), %rdi
movq 0x1cf70(%rip), %rsi     # 0x23fd0
movq 0x1cf89(%rip), %rdx     # 0x23ff0
callq 0x4610
jmp 0x74fc
jmp 0x7091
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
callq 0x45d0
jmp 0x708c
jmp 0x721f
jmp 0x71ec
leaq 0x1208a(%rip), %rsi     # 0x19127
leaq -0x2f0(%rbp), %rdi
callq 0x81a0
movb %al, -0x4d1(%rbp)
jmp 0x70b1
movb -0x4d1(%rbp), %al
testb $0x1, %al
jne 0x70bd
jmp 0x7111
movq 0x1cef4(%rip), %rdi     # 0x23fb8
leaq 0x12061(%rip), %rsi     # 0x1912c
callq 0x43c0
movq %rax, -0x4e0(%rbp)
jmp 0x70d9
movq -0x4e0(%rbp), %rdi
movq 0x1ceb1(%rip), %rsi     # 0x23f98
callq 0x4400
jmp 0x70ee
movq -0x4b0(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq -0xf8(%rbp), %r8
callq 0x9170
jmp 0x710c
jmp 0x71ea
movb $0x1, -0x402(%rbp)
movl $0x28, %edi
callq 0x41b0
movq %rax, -0x4f0(%rbp)
leaq -0x401(%rbp), %rdi
movq %rdi, -0x4e8(%rbp)
callq 0x4650
movq -0x4e8(%rbp), %rdx
leaq 0x11ff4(%rip), %rsi     # 0x1913e
leaq -0x400(%rbp), %rdi
callq 0x4bf0
jmp 0x7158
movq -0x4f0(%rbp), %rdi
leaq -0x400(%rbp), %rsi
callq 0x9240
jmp 0x716d
movq -0x4f0(%rbp), %rdi
movb $0x0, -0x402(%rbp)
leaq 0x1cb76(%rip), %rsi     # 0x23cf8
leaq 0x2127(%rip), %rdx      # 0x92b0
callq 0x4610
jmp 0x74fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x71c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x400(%rbp), %rdi
callq 0x4250
leaq -0x401(%rbp), %rdi
callq 0x4420
testb $0x1, -0x402(%rbp)
jne 0x71dc
jmp 0x71e8
movq -0x4f0(%rbp), %rdi
callq 0x42d0
jmp 0x721f
jmp 0x71ec
jmp 0x71ee
movl -0x1c(%rbp), %edi
callq 0x46d0
jmp 0x71f8
movl -0x10(%rbp), %edi
callq 0x46d0
jmp 0x7202
leaq -0x310(%rbp), %rdi
callq 0x4250
leaq -0x2f0(%rbp), %rdi
callq 0x4250
jmp 0x73c8
leaq -0x310(%rbp), %rdi
callq 0x4250
leaq -0x2f0(%rbp), %rdi
callq 0x4250
movl -0x1dc(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x72b3
movq -0x1d8(%rbp), %rdi
callq 0x4120
movq %rax, -0x410(%rbp)
movl $0x8, %edi
callq 0x41b0
movq %rax, %rdi
movq %rdi, -0x4f8(%rbp)
movq -0x410(%rbp), %rsi
callq 0x7db0
movq -0x4f8(%rbp), %rdi
movq 0x1cd49(%rip), %rsi     # 0x23fd0
movq 0x1cd62(%rip), %rdx     # 0x23ff0
callq 0x4610
jmp 0x74fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
callq 0x45d0
jmp 0x72b1
jmp 0x72b3
movl -0x1dc(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x74dc
movq -0x1d8(%rbp), %rdi
callq 0x4120
movq %rax, -0x418(%rbp)
movq -0x418(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x508(%rbp)
leaq -0x439(%rbp), %rdi
movq %rdi, -0x500(%rbp)
callq 0x4650
movq -0x508(%rbp), %rsi
movq -0x500(%rbp), %rdx
leaq -0x438(%rbp), %rdi
callq 0x4bf0
jmp 0x731f
leaq -0x439(%rbp), %rdi
callq 0x4420
movl -0xc(%rbp), %esi
leaq -0x4a0(%rbp), %rdi
callq 0x7bb0
jmp 0x733c
leaq 0x11e19(%rip), %rdx     # 0x1915c
leaq -0x480(%rbp), %rdi
leaq -0x4a0(%rbp), %rsi
callq 0x7b60
jmp 0x7358
leaq -0x460(%rbp), %rdi
leaq -0x480(%rbp), %rsi
leaq -0x438(%rbp), %rdx
callq 0x7b10
jmp 0x7374
leaq -0x480(%rbp), %rdi
callq 0x4250
leaq -0x4a0(%rbp), %rdi
callq 0x4250
movq -0x4b0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x460(%rbp), %rsi
callq 0x7cd0
jmp 0x73a5
movl -0x10(%rbp), %edi
callq 0x46d0
jmp 0x73af
cmpl $-0x1, -0x1c(%rbp)
je 0x7467
movl -0x1c(%rbp), %edi
callq 0x46d0
jmp 0x73c3
jmp 0x7467
jmp 0x74bd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x439(%rbp), %rdi
callq 0x4420
jmp 0x74b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x7490
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x7439
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x480(%rbp), %rdi
callq 0x4250
leaq -0x4a0(%rbp), %rdi
callq 0x4250
jmp 0x7490
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x4250
jmp 0x7490
movl $0x1, -0x4a4(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x4250
leaq -0x438(%rbp), %rdi
callq 0x4250
callq 0x45d0
jmp 0x749e
leaq -0x438(%rbp), %rdi
callq 0x4250
jmp 0x74b4
jmp 0x74c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d8(%rbp)
movl %eax, -0x1dc(%rbp)
jmp 0x74dc
callq 0x45d0
jmp 0x74bb
jmp 0x74dc
movl $0x0, -0x4a4(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x7a90
addq $0x510, %rsp            # imm = 0x510
popq %rbp
retq
leaq -0xf8(%rbp), %rdi
callq 0x7a90
movq -0x1d8(%rbp), %rdi
callq 0x4640
movq %rax, %rdi
callq 0x52e0
nopl (%rax)