// File: /workspace/github_cpp_makefile_star2_O2/dentiny[P]HTTP-Cache-Proxy/Proxy.cpp
// Function: Proxy::handleConnect(int, int, int, Request const&)
void handleConnect(int client_id, int client_fd, int server_fd, const Request & request)
	{
		// send a 200 OK to client
		const char * okMsg = "200 OK";
		int len = send(client_fd, okMsg, strlen(okMsg) + 1, 0);
		if(len == -1)
		{
			throw ProxyException("Send 200 OK to client error");
		}

		// select and keep listening
		bool connectionEnd = false;
		fd_set rfds;
		int fds[] = { client_fd, server_fd };
		int max_fd = std::max(fds[0], fds[1]) + 1; // argument of select() is the maximum fd + 1
		std::vector<char> buffer(BUFFER_SIZE, '\0'); // buffer to store request or response
		while(true)
		{
			// check if break loop
			if(connectionEnd)
			{
				break;
			}

			// initialize the fd set
			FD_ZERO(&rfds);
			FD_SET(fds[0], &rfds);
			FD_SET(fds[1], &rfds);

			// listen to fds in a blocking way
			status = select(max_fd, &rfds, NULL, NULL, NULL); 
			if(status == -1)
			{
				throw ProxyException("Server or client select error");
			}

			// receive request or respond from the set fd
			// send to the other fd
			for(int i = 0; i < 2; ++i)
			{
				if(FD_ISSET(fds[i], &rfds))
				{
					// receive
					len = recv(fds[i], &buffer.data()[0], BUFFER_SIZE - 1, 0);
					if(len == -1)
					{
						throw ProxyException("Receive request or respond error");
					}

					// decide the end of CONNECT
					else if(len == 0)
					{
						connectionEnd = true;
						break;
					}
					buffer[len] = '\0';

					// send
					len = send(fds[1 - i], &buffer.data()[0], len, 0);
					if(len == -1)
					{
						throw ProxyException("Send to client or server error");
					}
				}
			}
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movl %ecx, %r14d
movl %edx, %ebx
movq %rdi, 0x18(%rsp)
leaq 0x552d(%rip), %rsi      # 0xa251
pushq $0x7
popq %rdx
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x31a0
cmpl $-0x1, %eax
je 0x4f9f
movl %ebx, 0x10(%rsp)
movl %r14d, 0x14(%rsp)
cmpl %r14d, %ebx
movl %r14d, %ebp
cmovgl %ebx, %ebp
leaq 0xe(%rsp), %rdx
movb $0x0, (%rdx)
leaq 0x30(%rsp), %rdi
leaq 0xf(%rsp), %rcx
movl $0x10000, %esi          # imm = 0x10000
callq 0x563e
pushq $0x40
popq %r12
movl %ebx, %eax
cltd
idivl %r12d
movslq %eax, %rcx
movq %rcx, 0x28(%rsp)
shll $0x6, %eax
subl %eax, %ebx
pushq $0x1
popq %r15
movq %r15, %rax
movl %ebx, %ecx
shlq %cl, %rax
movq %rax, 0x20(%rsp)
movl %r14d, %eax
cltd
idivl %r12d
movslq %eax, %rbx
shll $0x6, %eax
subl %eax, %r14d
movl %r14d, %ecx
shlq %cl, %r15
incl %ebp
xorl %eax, %eax
cmpq $0x10, %rax
jne 0x4e69
movq 0x28(%rsp), %rax
movq 0x20(%rsp), %rcx
orq %rcx, 0xc8(%rsp,%rax,8)
orq %r15, 0xc8(%rsp,%rbx,8)
movl %ebp, %edi
leaq 0xc8(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x32f0
movq 0x18(%rsp), %rcx
movl %eax, 0x2b0(%rcx)
cmpl $-0x1, %eax
je 0x4f4e
movl %ebp, %r14d
leaq 0x14(%rsp), %r13
xorl %ebp, %ebp
cmpq $0x2, %rbp
je 0x4e7a
movl 0x10(%rsp,%rbp,4), %edi
movl %edi, %eax
cltd
idivl %r12d
cltq
movq 0xc8(%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x4e60
movq 0x30(%rsp), %rsi
movl $0xffff, %edx           # imm = 0xFFFF
xorl %ecx, %ecx
callq 0x30e0
testl %eax, %eax
je 0x4e84
cmpl $-0x1, %eax
je 0x4f00
movslq %eax, %rdx
movq 0x30(%rsp), %rax
movb $0x0, (%rax,%rdx)
movl (%r13), %edi
movq 0x30(%rsp), %rsi
xorl %ecx, %ecx
callq 0x31a0
cmpl $-0x1, %eax
je 0x4eb2
incq %rbp
addq $-0x4, %r13
jmp 0x4e01
andq $0x0, 0xc8(%rsp,%rax,8)
incq %rax
jmp 0x4da9
xorl %eax, %eax
movl %r14d, %ebp
jmp 0x4da9
movl $0x0, %eax
cmpq $0x2, %rbp
movl %r14d, %ebp
je 0x4da9
leaq 0x30(%rsp), %rdi
callq 0x3dda
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x28
popq %rdi
callq 0x3190
movq %rax, %r14
leaq 0x53ef(%rip), %rsi      # 0xa2b3
leaq 0x48(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x386c
movb $0x1, %bpl
leaq 0x48(%rsp), %rsi
movq %r14, %rdi
callq 0x55e8
xorl %ebp, %ebp
leaq 0xae1c(%rip), %rsi      # 0xfd08
leaq 0x72b(%rip), %rdx       # 0x561e
movq %r14, %rdi
callq 0x3490
jmp 0x4ff1
pushq $0x28
popq %rdi
callq 0x3190
movq %rax, %r14
leaq 0x5380(%rip), %rsi      # 0xa292
leaq 0x68(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x386c
movb $0x1, %bpl
leaq 0x68(%rsp), %rsi
movq %r14, %rdi
callq 0x55e8
xorl %ebp, %ebp
leaq 0xadce(%rip), %rsi      # 0xfd08
leaq 0x6dd(%rip), %rdx       # 0x561e
movq %r14, %rdi
callq 0x3490
jmp 0x4ff1
pushq $0x28
popq %rdi
callq 0x3190
movq %rax, %r14
leaq 0x5314(%rip), %rsi      # 0xa274
leaq 0x88(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0x386c
movb $0x1, %bpl
leaq 0x88(%rsp), %rsi
movq %r14, %rdi
callq 0x55e8
xorl %ebp, %ebp
leaq 0xad7a(%rip), %rsi      # 0xfd08
leaq 0x689(%rip), %rdx       # 0x561e
movq %r14, %rdi
callq 0x3490
jmp 0x4ff1
pushq $0x28
popq %rdi
callq 0x3190
movq %rax, %r14
leaq 0x52a7(%rip), %rsi      # 0xa258
leaq 0xa8(%rsp), %rdi
leaq 0xc8(%rsp), %rdx
callq 0x386c
movb $0x1, %bpl
leaq 0xa8(%rsp), %rsi
movq %r14, %rdi
callq 0x55e8
xorl %ebp, %ebp
leaq 0xad26(%rip), %rsi      # 0xfd08
leaq 0x635(%rip), %rdx       # 0x561e
movq %r14, %rdi
callq 0x3490
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x3150
testb %bpl, %bpl
jne 0x500b
jmp 0x5065
movq %rax, %rbx
movq %r14, %rdi
callq 0x3240
jmp 0x5065
movq %rax, %rbx
jmp 0x5065
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
jmp 0x503f
jmp 0x504b
jmp 0x5058
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
jmp 0x503f
jmp 0x504b
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x3150
testb %bpl, %bpl
jne 0x504e
jmp 0x505b
movq %rax, %rbx
movq %r14, %rdi
callq 0x3240
jmp 0x505b
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x3dda
movq %rbx, %rdi
callq 0x34b0
nop