// File: /workspace/github_cpp_makefile_star2_O2/dentiny[P]HTTP-Cache-Proxy/Proxy.cpp
// Function: Proxy::checkCaching(int, int, int, Request&)
bool checkCaching(int client_id, int client_fd, int server_fd, Request & request)
	{
		// (1) url not exist in the cache
		const std::string url = request.url;
		if(!cache.existsUrl(url))
		{
			std::string log_content = std::to_string(client_id) + ": not in cache";
			logger.log(log_content);
			return false;
		}
		Response response = cache.get(url);

		// (2) check expiration time
		// note: expiration time = response time + max-age 
		// if there's no no-cache mark in the response, and the response hasn't been expired, directly fetch it from cache
		time_t cur_time = time(NULL);
		if(cur_time <= response.expiration_time && !response.no_cache)
		{
			std::string log_content = std::to_string(client_id) + ": in cache, valid";
			logger.log(log_content);
			respondCached(client_fd, url);
			return true;
		}

		// (3) check e-tag
		// if these's etag, request If-None-Match tag to the web server
		// format: insert "If-None-Match: etag value" into the content 
		if(!response.etag.empty())
		{
			// write to log
			std::string log_content = std::to_string(client_id) + ": in cache, requires validation";
			logger.log(log_content);

			// create If-None-Match section
			std::string if_none_match = "\r\nIf-None-Match: " + response.etag;

			// insert the section into the request
			std::vector<char> content_to_send = insertSectionToContent(request.content, if_none_match);

			// resend and check the status code
			try
			{
				resendCheckStatus(client_id, client_fd, server_fd, content_to_send, url);
			}
			catch(std::exception & e)
			{
				throw e;
			}

			// has resolved re-validation, updated cache and resending
			return true;
		}

		// (4) check last-modified
		// if there's no etag, but there is last-modified
		else if(response.last_modified != 0)
		{
			// write to log
			std::string log_content = std::to_string(client_id) + ": in cache, requires validation";
			logger.log(log_content);

			// create If-Modified-Since section
  			std::string if_modified_since = "\r\nIf-Modified-Since: " + response.kv["Last-Modified"];

  			// insert the section into the request
  			std::vector<char> content_to_send = insertSectionToContent(request.content, if_modified_since);

  			// resend and check the status code
			try
			{
				resendCheckStatus(client_id, client_fd, server_fd, content_to_send, url);
			}
			catch(std::exception & e)
			{
				throw e;
			}

			// has resolved re-validation, updated cache and resending
			return true;
		}

		// convert expiration time to string
		tm * tm = localtime(&response.expiration_time);
		char * dt = asctime(tm);
		std::string expiration(dt);

		// write to log
		std::string log_content = std::to_string(client_id) + ": in cache, but expired at "  + expiration;
		logger.log(log_content);

		return false;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %r8, %r12
movl %ecx, %r15d
movl %edx, 0xc(%rsp)
movl %esi, %r14d
movq %rdi, %rbx
leaq 0x60(%r8), %rsi
leaq 0x70(%rsp), %rbp
movq %rbp, %rdi
callq 0x33d0
leaq 0x250(%rbx), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x5d66
testb %al, %al
je 0x518e
leaq 0xb0(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %r13, %rsi
callq 0x5dc2
xorl %edi, %edi
callq 0x32e0
cmpq 0x178(%rsp), %rax
jg 0x50ee
cmpb $0x0, 0x169(%rsp)
je 0x52c7
cmpq $0x0, 0x190(%rsp)
je 0x51e6
leaq 0x10(%rsp), %rdi
movl %r14d, %esi
callq 0x4a4e
leaq 0x51e2(%rip), %rdx      # 0xa2f3
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4a2f
leaq 0x10(%rsp), %rdi
callq 0x3150
leaq 0x8(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x4aa8
leaq 0x188(%rsp), %rdx
leaq 0x51cc(%rip), %rsi      # 0xa313
leaq 0x10(%rsp), %rdi
callq 0x5fc8
addq $0xc0, %r12
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rcx
movq %rbx, %rsi
movq %r12, %rdx
callq 0x603e
leaq 0x50(%rsp), %r8
leaq 0x70(%rsp), %r9
movq %rbx, %rdi
movl %r14d, %esi
movl 0xc(%rsp), %edx
movl %r15d, %ecx
callq 0x60ee
jmp 0x52b1
leaq 0x30(%rsp), %rdi
movl %r14d, %esi
callq 0x4a4e
leaq 0x5130(%rip), %rdx      # 0xa2d2
leaq 0xb0(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x4a2f
leaq 0x30(%rsp), %rdi
callq 0x3150
addq $0x8, %rbx
leaq 0xb0(%rsp), %rsi
movq %rbx, %rdi
callq 0x4aa8
leaq 0xb0(%rsp), %rdi
callq 0x3150
xorl %ebx, %ebx
jmp 0x532c
cmpq $0x0, 0x180(%rsp)
je 0x534a
leaq 0x10(%rsp), %rdi
movl %r14d, %esi
callq 0x4a4e
leaq 0x50ea(%rip), %rdx      # 0xa2f3
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4a2f
leaq 0x10(%rsp), %rdi
callq 0x3150
leaq 0x8(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x4aa8
leaq 0x5104(%rip), %rsi      # 0xa33b
leaq 0x50(%rsp), %rdi
leaq 0x90(%rsp), %rdx
callq 0x386c
leaq 0x130(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x98fa
leaq 0x50c3(%rip), %rsi      # 0xa325
leaq 0x10(%rsp), %rdi
movq %rax, %rdx
callq 0x5fc8
leaq 0x50(%rsp), %rdi
callq 0x3150
addq $0xc0, %r12
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rcx
movq %rbx, %rsi
movq %r12, %rdx
callq 0x603e
leaq 0x50(%rsp), %r8
leaq 0x70(%rsp), %r9
movq %rbx, %rdi
movl %r14d, %esi
movl 0xc(%rsp), %edx
movl %r15d, %ecx
callq 0x60ee
leaq 0x50(%rsp), %rdi
callq 0x3dda
leaq 0x10(%rsp), %rdi
callq 0x3150
jmp 0x5313
leaq 0x10(%rsp), %rdi
movl %r14d, %esi
callq 0x4a4e
leaq 0x5006(%rip), %rdx      # 0xa2e1
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4a2f
leaq 0x10(%rsp), %rdi
callq 0x3150
leaq 0x8(%rbx), %rdi
leaq 0x30(%rsp), %rsi
callq 0x4aa8
leaq 0x70(%rsp), %rdx
movq %rbx, %rdi
movl 0xc(%rsp), %esi
callq 0x5eca
leaq 0x30(%rsp), %rdi
callq 0x3150
movb $0x1, %bl
leaq 0xb0(%rsp), %rdi
callq 0x3c54
leaq 0x70(%rsp), %rdi
callq 0x3150
movl %ebx, %eax
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x178(%rsp), %rdi
callq 0x3250
movq %rax, %rdi
callq 0x3110
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rdx
movq %rax, %rsi
callq 0x386c
leaq 0x90(%rsp), %rdi
movl %r14d, %esi
callq 0x4a4e
leaq 0x4fc1(%rip), %rdx      # 0xa349
leaq 0x50(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4a2f
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x4a10
leaq 0x50(%rsp), %rdi
callq 0x3150
leaq 0x90(%rsp), %rdi
callq 0x3150
addq $0x8, %rbx
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x4aa8
leaq 0x10(%rsp), %rdi
callq 0x3150
leaq 0x30(%rsp), %rdi
callq 0x3150
xorl %ebx, %ebx
jmp 0x531f
jmp 0x54e4
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x3150
jmp 0x5408
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
jmp 0x54ec
jmp 0x5506
jmp 0x5501
movq %rax, %rbx
cmpl $0x1, %edx
jne 0x54d0
movq %rbx, %rdi
callq 0x3100
pushq $0x8
popq %rdi
callq 0x3190
movq 0xab6e(%rip), %rcx      # 0xffb0
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0xab80(%rip), %rsi      # 0xffd0
movq 0xab99(%rip), %rdx      # 0xfff0
movq %rax, %rdi
callq 0x3490
jmp 0x54c8
movq %rax, %rbx
callq 0x3470
jmp 0x54d0
jmp 0x54e4
jmp 0x5506
jmp 0x5506
jmp 0x54f7
jmp 0x5501
jmp 0x54f7
jmp 0x5501
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
jmp 0x54ec
movq %rax, %rbx
cmpl $0x1, %edx
jne 0x54d0
movq %rbx, %rdi
callq 0x3100
pushq $0x8
popq %rdi
callq 0x3190
movq 0xab05(%rip), %rcx      # 0xffb0
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0xab17(%rip), %rsi      # 0xffd0
movq 0xab30(%rip), %rdx      # 0xfff0
movq %rax, %rdi
callq 0x3490
movq %rax, %rbx
callq 0x3470
leaq 0x50(%rsp), %rdi
callq 0x3dda
jmp 0x54e7
movq %rax, %rdi
callq 0x3b8d
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x3150
jmp 0x5509
jmp 0x5506
jmp 0x5506
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0x550e
movq %rax, %rbx
jmp 0x5513
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x3150
leaq 0xb0(%rsp), %rdi
callq 0x3c54
jmp 0x5545
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
jmp 0x5537
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x3150
jmp 0x5545
jmp 0x5542
jmp 0x5542
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x3150
movq %rbx, %rdi
callq 0x34b0
nop