// File: guoxuanhan[P]NetServer/httpserver.cpp
// Function: HttpServer::HandleMessage(std::shared_ptr<TcpConnection> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
void HttpServer::HandleMessage(const spTcpConnection& sptcpconn, std::string &msg)
{
    std::shared_ptr<HttpSession> sphttpsession;
    spTimer sptimer;
    {
        std::lock_guard <std::mutex> lock(mutex_);
        sphttpsession = httpsessionnlist_[sptcpconn];
        sptimer = timerlist_[sptcpconn];
    }
    sptimer->Adjust(5000, Timer::TimerType::TIMER_ONCE, std::bind(&TcpConnection::Shutdown, sptcpconn));

    if(threadpool_.GetThreadNum() > 0)
    {
        //Bug20190320：多线程下，对象的声明周期管理问题，就像在这里，向线程池传入了phttpsession和ptcpconn，怎么知道其指向对象是否已经析构了呢？
        //所以，需要采用智能指针来管理对象,替换原始指针
        //线程池处理业务，处理完后投递回本IO线程执行send
        //std::cout << "threadpool_.AddTask" << std::endl;
        HttpRequestContext httprequestcontext;
        std::string responsecontext;
        bool result = sphttpsession->PraseHttpRequest(msg, httprequestcontext);
        if(result == false)
        {
            sphttpsession->HttpError(400, "Bad request", httprequestcontext, responsecontext); //请求报文解析错误，报400
            sptcpconn->Send(responsecontext);
            return;
        }

        sptcpconn->SetAsyncProcessing(true);
        threadpool_.AddTask([=]() {
            //HttpRequestContext req = httprequestcontext;
            std::string responsemsg;
            sphttpsession->HttpProcess(httprequestcontext, responsemsg);

            sptcpconn->Send(responsemsg); //任务已经处理完成，执行跨线程调度，即回调

            if(!sphttpsession->KeepAlive())
            {
                //短连接，可以告诉框架层数据发完就可以关掉TCP连接，不过这里注释掉，还是交给客户端主动关闭吧
                //sptcpconn->HandleClose();
            }
        });
    }
    else
    {
        //没有开启业务线程池，业务计算直接在IO线程执行
        HttpRequestContext httprequestcontext;
        std::string responsecontext;
        bool result = sphttpsession->PraseHttpRequest(msg, httprequestcontext);
        if(result == false)
        {
            sphttpsession->HttpError(400, "Bad request", httprequestcontext, responsecontext); //请求报文解析错误，报400
            sptcpconn->Send(responsecontext);
            return;
        }

        sphttpsession->HttpProcess(httprequestcontext, responsecontext);

        sptcpconn->Send(responsecontext);

        if(!sphttpsession->KeepAlive())
        {
            //短连接，可以告诉框架层数据发完就可以关掉TCP连接，不过这里注释掉，还是交给客户端主动关闭吧
            //sptcpconn->HandleClose();
        }
    }
}

// Assembly:
subq $0x418, %rsp            # imm = 0x418
movq %rdi, 0x410(%rsp)
movq %rsi, 0x408(%rsp)
movq %rdx, 0x400(%rsp)
movq 0x410(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0x3f0(%rsp), %rdi
callq 0xdbb0
leaq 0x3e0(%rsp), %rdi
callq 0xdbc0
movq 0x80(%rsp), %rsi
addq $0x60, %rsi
leaq 0x3d8(%rsp), %rdi
callq 0x8c20
jmp 0xc694
movq 0x80(%rsp), %rdi
movq 0x408(%rsp), %rsi
callq 0xd950
movq %rax, 0x78(%rsp)
jmp 0xc6b0
movq 0x78(%rsp), %rsi
leaq 0x3f0(%rsp), %rdi
callq 0xda40
movq 0x80(%rsp), %rdi
addq $0x30, %rdi
movq 0x408(%rsp), %rsi
callq 0xda70
movq %rax, 0x70(%rsp)
jmp 0xc6e2
movq 0x70(%rsp), %rsi
leaq 0x3e0(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0xdb60
leaq 0x3d8(%rsp), %rdi
callq 0x8cc0
movq 0x60(%rsp), %rdi
callq 0xd940
movq %rax, 0x68(%rsp)
leaq 0x107c4(%rip), %rax     # 0x1cee0
movq %rax, 0x378(%rsp)
movq $0x0, 0x380(%rsp)
movq 0x408(%rsp), %rdx
leaq 0x388(%rsp), %rdi
leaq 0x378(%rsp), %rsi
callq 0xd8e0
jmp 0xc74f
leaq 0x3a8(%rsp), %rdi
leaq 0x388(%rsp), %rsi
callq 0xdbd0
jmp 0xc766
movq 0x68(%rsp), %rdi
movl $0x1388, %esi           # imm = 0x1388
xorl %edx, %edx
leaq 0x3a8(%rsp), %rcx
callq 0x25f20
jmp 0xc781
leaq 0x3a8(%rsp), %rdi
callq 0x5ef0
leaq 0x388(%rsp), %rdi
callq 0xd920
movq 0x80(%rsp), %rdi
addq $0x250, %rdi            # imm = 0x250
callq 0x23780
movl %eax, 0x5c(%rsp)
jmp 0xc7b5
movl 0x5c(%rsp), %eax
cmpl $0x0, %eax
jle 0xcb3e
leaq 0x2c8(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0xdc80
leaq 0x2a8(%rsp), %rdi
callq 0x54f0
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq 0x50(%rsp), %rdx
movq %rax, %rdi
movq 0x400(%rsp), %rsi
callq 0x14ea0
movb %al, 0x5b(%rsp)
jmp 0xc809
movb 0x5b(%rsp), %al
andb $0x1, %al
movb %al, 0x2a7(%rsp)
movb 0x2a7(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xc9c6
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq %rax, 0x40(%rsp)
leaq 0x27f(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x5670
movq 0x48(%rsp), %rdx
leaq 0x1bd64(%rip), %rsi     # 0x285bf
leaq 0x280(%rsp), %rdi
callq 0x54d0
jmp 0xc86a
movq 0x40(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
leaq 0x280(%rsp), %rdx
leaq 0x2c8(%rsp), %rcx
leaq 0x2a8(%rsp), %r8
callq 0x16490
jmp 0xc893
leaq 0x280(%rsp), %rdi
callq 0x5270
leaq 0x27f(%rsp), %rdi
callq 0x5400
movq 0x408(%rsp), %rdi
callq 0x6aa0
movq %rax, %rdi
leaq 0x2a8(%rsp), %rsi
callq 0x1ca10
jmp 0xc8cc
movl $0x1, 0x278(%rsp)
jmp 0xca8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xcda4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
leaq 0x3d8(%rsp), %rdi
callq 0x8cc0
jmp 0xcda4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xc952
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
leaq 0x3a8(%rsp), %rdi
callq 0x5ef0
leaq 0x388(%rsp), %rdi
callq 0xd920
jmp 0xcda4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xcb1f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xc9b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
leaq 0x280(%rsp), %rdi
callq 0x5270
leaq 0x27f(%rsp), %rdi
callq 0x5400
jmp 0xcb1f
movq 0x408(%rsp), %rdi
callq 0x6aa0
movq %rax, %rdi
movl $0x1, %esi
callq 0xdcf0
jmp 0xc9e2
movq 0x80(%rsp), %rax
addq $0x250, %rax            # imm = 0x250
movq %rax, 0x30(%rsp)
leaq 0x188(%rsp), %rdi
movq %rdi, 0x38(%rsp)
leaq 0x3f0(%rsp), %rsi
callq 0xdd10
leaq 0x198(%rsp), %rdi
leaq 0x2c8(%rsp), %rsi
callq 0xdd40
jmp 0xca26
leaq 0x248(%rsp), %rdi
movq 0x408(%rsp), %rsi
callq 0xde60
leaq 0x258(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0xcf30
jmp 0xca52
movq 0x30(%rsp), %rdi
leaq 0x258(%rsp), %rsi
callq 0x23700
jmp 0xca66
leaq 0x258(%rsp), %rdi
callq 0x5ef0
leaq 0x188(%rsp), %rdi
callq 0xcfe0
movl $0x0, 0x278(%rsp)
leaq 0x2a8(%rsp), %rdi
callq 0x5270
leaq 0x2c8(%rsp), %rdi
callq 0xde90
movl 0x278(%rsp), %eax
testl %eax, %eax
jne 0xcd82
jmp 0xcab6
jmp 0xcd77
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
callq 0xdba0
jmp 0xcb1f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xcb12
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
leaq 0x258(%rsp), %rdi
callq 0x5ef0
leaq 0x188(%rsp), %rdi
callq 0xcfe0
leaq 0x2a8(%rsp), %rdi
callq 0x5270
leaq 0x2c8(%rsp), %rdi
callq 0xde90
jmp 0xcda4
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xdc80
leaq 0xb8(%rsp), %rdi
callq 0x54f0
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq 0x20(%rsp), %rdx
movq %rax, %rdi
movq 0x400(%rsp), %rsi
callq 0x14ea0
movb %al, 0x2f(%rsp)
jmp 0xcb85
movb 0x2f(%rsp), %al
andb $0x1, %al
movb %al, 0xb7(%rsp)
movb 0xb7(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xccba
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq %rax, 0x10(%rsp)
leaq 0x8f(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x5670
movq 0x18(%rsp), %rdx
leaq 0x1b9e8(%rip), %rsi     # 0x285bf
leaq 0x90(%rsp), %rdi
callq 0x54d0
jmp 0xcbe6
movq 0x10(%rsp), %rdi
movl $0x190, %esi            # imm = 0x190
leaq 0x90(%rsp), %rdx
leaq 0xd8(%rsp), %rcx
leaq 0xb8(%rsp), %r8
callq 0x16490
jmp 0xcc0f
leaq 0x90(%rsp), %rdi
callq 0x5270
leaq 0x8f(%rsp), %rdi
callq 0x5400
movq 0x408(%rsp), %rdi
callq 0x6aa0
movq %rax, %rdi
leaq 0xb8(%rsp), %rsi
callq 0x1ca10
jmp 0xcc48
movl $0x1, 0x278(%rsp)
jmp 0xcd32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xcd5b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
jmp 0xcca8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3d0(%rsp)
movl %eax, 0x3cc(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x5270
leaq 0x8f(%rsp), %rdi
callq 0x5400
jmp 0xcd5b
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq %rax, %rdi
leaq 0xd8(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0x15530
jmp 0xcce1
movq 0x408(%rsp), %rdi
callq 0x6aa0
movq %rax, %rdi
leaq 0xb8(%rsp), %rsi
callq 0x1ca10
jmp 0xcd00
leaq 0x3f0(%rsp), %rdi
callq 0xdce0
movq %rax, %rdi
callq 0xdef0
movb %al, 0xf(%rsp)
jmp 0xcd1b
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0xcd27
jmp 0xcd25
jmp 0xcd27
movl $0x0, 0x278(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x5270
leaq 0xd8(%rsp), %rdi
callq 0xde90
movl 0x278(%rsp), %eax
testl %eax, %eax
jne 0xcd82
jmp 0xcd59
jmp 0xcd77
leaq 0xb8(%rsp), %rdi
callq 0x5270
leaq 0xd8(%rsp), %rdi
callq 0xde90
jmp 0xcda4
movl $0x0, 0x278(%rsp)
leaq 0x3e0(%rsp), %rdi
callq 0xdb90
leaq 0x3f0(%rsp), %rdi
callq 0xdba0
addq $0x418, %rsp            # imm = 0x418
retq
leaq 0x3e0(%rsp), %rdi
callq 0xdb90
leaq 0x3f0(%rsp), %rdi
callq 0xdba0
movq 0x3d0(%rsp), %rdi
callq 0x5660
nopl (%rax,%rax)