// File: /workspace/github_c_makefile_star2_O3/niuyuling[P]CProxy/http_request.c
// Function: extract_host
int extract_host(char *header, char *host, char *port)
{

//printf("%s\n", header);
    char *_p = strstr(header, "CONNECT"); // 在 CONNECT 方法中解析 隧道主机名称及端口号
    if (_p) {

        if (strchr(header, '[') || strchr(header, ']')) { // IPv6
            char *_p1 = strchr(header, '[');
            char *_p2 = strchr(_p1 + 1, ']');
            memcpy(host, _p1 + 1, (int)(_p2 - _p1) - 1);

            char *_p3 = strchr(_p2 + 1, ' ');
            memcpy(port, _p2 + 2, (int)(_p3 - _p2) - 1);

            return 0;
        }

        char *_p1 = strchr(_p, ' ');
        char *_p2 = strchr(_p1 + 1, ':');
        char *_p3 = strchr(_p1 + 1, ' ');

        if (_p2) {
            memcpy(host, _p1 + 1, (int)(_p2 - _p1) - 1);
            memcpy(port, _p2 + 1, (int)(_p3 - _p2) - 1);
        } else {                // 如果_p2等于空就返回-1
            return -1;
        }

        return 0;
    } else {

        char *_p = strstr(header, "Host:");
        if (_p == NULL) {
            _p = strstr(header, "host:");
        }
        if (_p == NULL) {       // 都为空时
            return -1;
        }

        char *_p1 = strchr(_p, '\n'); // 指向末尾'\n'
        if (!_p1) {
            return -1;
        }

        char *_p2 = strchr(_p + 5, ':'); // 5是指'Host:'的长度
        int h_len = (int)(_p1 - _p - 6);
        char s_host[h_len];
        memcpy(s_host, _p + 6, _p1 - _p - 6);
        s_host[h_len] = '\0';

        char *_p3 = strchr(s_host, ':');
        char *_p4 = NULL;
        if (_p3)
            _p4 = strchr(_p3 + 1, ':'); // 二次确认':'
        {                       // IPV6
            if (_p4 != NULL) {
                char *_p5 = NULL;
                char *_p6 = NULL;
                _p5 = strchr(header, ' ');
                if (_p5)
                    _p6 = strchr(_p5 + 1, ' ');

                char url[_p6 - _p5 - 1];
                memset(url, 0, _p6 - _p5 - 1);
                memcpy(url, _p5 + 1, _p6 - _p5 - 1);
                url[_p6 - _p5 - 1] = '\0';

                if (strstr(url, "http") != NULL) { // 去除 'http://'
                    memcpy(url, url + 7, (_p6 - _p5 - 1) - 7);
                    url[(_p6 - _p5 - 1) - 7] = '\0';
                    char *_p7 = strchr(url, '/');
                    if (_p7)    // 去除 uri
                        url[_p7 - url] = '\0';

                    char *_p8 = strchr(url, ']');
                    char *_p9 = strchr(url, '\0');
                    if (_p8) {
                        if ((_p9 - _p8) == 1) { // 如果不带端口就默认80, 并结束
                            memcpy(port, "80", 2);
                            memcpy(host, url + 1, _p8 - (url + 1));
                            return 0;
                        }

                        memcpy(port, _p8 + 2, _p9 - (_p8 + 2));
                        memcpy(host, url + 1, _p8 - (url + 1));
                    }
                    return 0;
                } else {        // HTTP头为不规范的url时处理Host, 主要Proxifier转发url为'/'时
                    //printf("s_host: %s\n", s_host);
                    char *_p1 = strchr(s_host, '[');
                    if (_p1 == NULL) // 涉及到自定义的Host, 不带'['、']'时, 默认截取最后为端口
                    {
                        char *_p2 = strrchr(s_host, ':');
                        remote_port = atoi(_p2 + 1);
                        memcpy(remote_host, s_host, _p2 - s_host);
                        return 0;
                    }

                    char *_p2 = strchr(_p1 + 1, ']');
                    char *_p3 = strchr(s_host, '\0');
                    if (_p1 && _p2) {
                        memcpy(host, _p1 + 1, _p2 - _p1 - 1);
                        if ((_p3-(_p2+1)) < 2) {
                            memcpy(port, "80", 2);
                        } else {
                            memcpy(port, _p2 + 2, _p3 - (_p2 + 2));
                        }

                    }
                    return 0;
                }

                return -1;
            }
        }
        // HTTP 非 CONNECT 方法
        {
            if (_p2 && _p2 < _p1) { // 带端口, p2指向':', p1指向末尾'\n', _p指向Host
                memcpy(port, _p2 + 1, (int)(_p1 - _p2 - 1));
                memcpy(host, _p + 5 + 1, (int)(_p2 - _p - 5 - 1));
            } else {            // 不带端口
                if (0 < (int)(_p1 - _p - 5 - 1 - 1)) {
                    memcpy(host, _p + 5 + 1, (_p1 - _p - 5 - 1 - 1));
                    memcpy(port, "80", 2);
                } else {
                    memcpy(host, _p + 5 + 1, (_p1 - _p) - 6);
                    memcpy(port, "80", 2);
                }
            }
        }

        return 0;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, %r13
movq %rsi, %r15
movq %rdi, %r12
leaq 0x4fcf(%rip), %rsi      # 0x9305
callq 0x2540
testq %rax, %rax
je 0x43cb
movq %rax, %r14
movq %r15, -0x30(%rbp)
movq %r12, %rdi
movl $0x5b, %esi
callq 0x2160
movq %rax, %rbx
testq %rax, %rax
jne 0x4376
movq %r12, %rdi
movl $0x5d, %esi
callq 0x2160
testq %rax, %rax
je 0x4516
movq %rbx, %r14
incq %r14
movq %r14, %rdi
movl $0x5d, %esi
callq 0x2160
movq %rax, %r15
notl %ebx
addl %r15d, %ebx
movslq %ebx, %rdx
movq -0x30(%rbp), %rdi
movq %r14, %rsi
callq 0x22e0
leaq 0x1(%r15), %rdi
movl $0x20, %esi
callq 0x2160
movq %r15, %rsi
addq $0x2, %rsi
notl %r15d
addl %r15d, %eax
movslq %eax, %rdx
movq %r13, %rdi
callq 0x22e0
jmp 0x4776
movq %r13, -0x38(%rbp)
leaq 0x4f94(%rip), %rsi      # 0x936a
movq %r12, %rdi
callq 0x2540
testq %rax, %rax
jne 0x43fb
leaq 0x4f86(%rip), %rsi      # 0x9370
movq %r12, %rdi
callq 0x2540
testq %rax, %rax
je 0x4577
movq %rax, %r13
movq %rax, %rdi
movl $0xa, %esi
callq 0x2160
testq %rax, %rax
je 0x4577
movq %rax, %r14
movq %r15, -0x30(%rbp)
leaq 0x5(%r13), %rdi
movl $0x3a, %esi
callq 0x2160
movq %rax, -0x60(%rbp)
movq %rsp, -0x68(%rbp)
movq %r14, -0x58(%rbp)
subq %r13, %r14
leaq -0x6(%r14), %rbx
movl %ebx, %eax
addq $0xf, %rax
andq $-0x10, %rax
movq %rsp, %r15
subq %rax, %r15
movq %r15, %rsp
leaq 0x6(%r13), %rsi
movq %r15, %rdi
movq %rsi, -0x40(%rbp)
movq %rbx, %rdx
callq 0x22e0
movq %rbx, -0x50(%rbp)
movslq %ebx, %rax
movb $0x0, (%rax,%r15)
movq %r15, -0x48(%rbp)
movq %r15, %rdi
movl $0x3a, %esi
callq 0x2160
testq %rax, %rax
je 0x44c5
incq %rax
movq %rax, %rdi
movl $0x3a, %esi
callq 0x2160
testq %rax, %rax
je 0x44c5
movq %r12, %rdi
movl $0x20, %esi
callq 0x2160
movq %rax, %rbx
testq %rax, %rax
je 0x459e
leaq 0x1(%rbx), %rdi
movl $0x20, %esi
callq 0x2160
jmp 0x45a0
movq -0x60(%rbp), %r15
testq %r15, %r15
sete %al
movq -0x58(%rbp), %rdx
cmpq %rdx, %r15
setae %cl
orb %al, %cl
jne 0x4581
movq %r15, %rsi
incq %rsi
movl %r15d, %eax
notl %eax
addl %eax, %edx
movslq %edx, %rdx
movq -0x38(%rbp), %rdi
callq 0x22e0
subl %r13d, %r15d
addl $-0x6, %r15d
movslq %r15d, %rdx
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x22e0
jmp 0x4772
movq %r14, %rdi
movl $0x20, %esi
callq 0x2160
movq %rax, %r15
leaq 0x1(%rax), %r14
movq %r14, %rdi
movl $0x3a, %esi
callq 0x2160
testq %rax, %rax
je 0x4577
movq %rax, %rbx
movq %r14, %rdi
movl $0x20, %esi
callq 0x2160
movq %rax, %r12
notl %r15d
addl %ebx, %r15d
movslq %r15d, %rdx
movq -0x30(%rbp), %rdi
movq %r14, %rsi
callq 0x22e0
movq %rbx, %rsi
incq %rsi
notl %ebx
addl %ebx, %r12d
movslq %r12d, %rdx
jmp 0x43be
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x4778
addq $-0x7, %r14
testl %r14d, %r14d
jle 0x46e2
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq %r14, %rdx
jmp 0x46ee
xorl %eax, %eax
movq -0x30(%rbp), %r15
movq %rsp, %r13
movq %rbx, %rcx
notq %rcx
leaq (%rax,%rcx), %r14
addq %rcx, %rax
addq $0xf, %rax
andq $-0x10, %rax
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
incq %rbx
movq %r12, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x22e0
movb $0x0, (%r12,%r14)
leaq 0x4d94(%rip), %rsi      # 0x9376
movq %r12, %rdi
callq 0x2540
testq %rax, %rax
je 0x465d
leaq 0x7(%r12), %rsi
leaq -0x7(%r14), %rdx
movq %r12, %rdi
callq 0x22e0
movb $0x0, -0x7(%r12,%r14)
movq %r12, %rdi
movl $0x2f, %esi
callq 0x2160
testq %rax, %rax
je 0x461b
movb $0x0, (%rax)
movq %r12, %rdi
movl $0x5d, %esi
callq 0x2160
testq %rax, %rax
je 0x476f
movq %rax, %rbx
movq %r12, %rdi
callq 0x2140
addq %r12, %rax
movq %rax, %rcx
subq %rbx, %rcx
cmpq $0x1, %rcx
jne 0x46fe
movq -0x38(%rbp), %rax
movw $0x3038, (%rax)         # imm = 0x3038
jmp 0x4711
movq -0x48(%rbp), %r12
movq %r12, %rdi
movl $0x5b, %esi
callq 0x2160
testq %rax, %rax
je 0x471c
movq %rax, %r14
leaq 0x1(%rax), %r12
movq %r12, %rdi
movl $0x5d, %esi
callq 0x2160
testq %rax, %rax
je 0x476f
movq %rax, %rbx
movq %r13, -0x30(%rbp)
movq -0x48(%rbp), %r13
movq %r13, %rdi
callq 0x2140
movq %r15, %rdi
movq %rax, %r15
addq %r13, %r15
notq %r14
addq %rbx, %r14
movq %r12, %rsi
movq %r14, %rdx
callq 0x22e0
movq %rbx, %rax
notq %rax
addq %r15, %rax
cmpq $0x1, %rax
jg 0x4755
movq -0x38(%rbp), %rax
movw $0x3038, (%rax)         # imm = 0x3038
jmp 0x476b
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x22e0
movq -0x38(%rbp), %rax
movw $0x3038, (%rax)         # imm = 0x3038
jmp 0x4772
leaq 0x2(%rbx), %rsi
subq %rsi, %rax
movq -0x38(%rbp), %rdi
movq %rax, %rdx
callq 0x22e0
incq %r12
subq %r12, %rbx
movq %r15, %rdi
jmp 0x4748
movq %r12, %rdi
movl $0x3a, %esi
callq 0x2190
movq %rax, %rbx
leaq 0x1(%rax), %rdi
callq 0x2480
leaq 0x14f24(%rip), %rcx     # 0x19660
movl %eax, (%rcx)
subq %r12, %rbx
leaq 0x14e08(%rip), %rdi     # 0x19550
movq %r12, %rsi
movq %rbx, %rdx
callq 0x22e0
jmp 0x476f
addq $0x2, %rbx
subq %rbx, %r15
movq -0x38(%rbp), %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x22e0
movq -0x30(%rbp), %r13
movq %r13, %rsp
movq -0x68(%rbp), %rsp
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq