// File: Computer-Kids-Club[P]screenshare-pro-backend/http.cpp
// Function: parse_header[abi:cxx11](char const*, char const*)
std::unordered_map<std::string, std::string> parse_header(const char *msg, const char *msg_end) {
    const char *head = msg;
    const char *tail = msg;

    std::unordered_map<std::string, std::string> http_request;

    // Find request type
    while (tail != msg_end && *tail != ' ')
        ++tail;
    http_request["Type"] = std::string(head, tail);

    // Find path
    while (tail != msg_end && *tail == ' ')
        ++tail;
    head = tail;
    while (tail != msg_end && *tail != ' ')
        ++tail;
    http_request["Path"] = std::string(head, tail);

    // Find HTTP version
    while (tail != msg_end && *tail == ' ')
        ++tail;
    head = tail;
    while (tail != msg_end && *tail != '\r')
        ++tail;
    http_request["Version"] = std::string(head, tail);
    if (tail != msg_end)
        ++tail;  // skip '\r'
    // TODO: what about the trailing '\n'?

    // Map all headers from a key to a value
    head = tail;
    while (head < msg_end && *head != '\r') {
        tail = head;
        while (tail < msg_end && *tail != '\r')
            ++tail;
        const char *colon = (const char *)memchr(head, ':', tail - head);
        if (colon == NULL) {
            // TODO: malformed headers, what should happen?
            break;
        }
        const char *value = colon + 1;
        while (value < tail && *value == ' ')
            ++value;
        if (head < colon && value < tail && tail <= msg_end) {
            http_request[std::string(head, colon)] = std::string(value, tail);
        }
        head = tail + 1;
        while (head < msg_end && (*head == '\n' || *head == '\r' || *head == ' '))
            head++;
        //printf("%d\n", head - msg);
        // TODO: what about the trailing '\n'?
    }

    return http_request;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x280, %rsp            # imm = 0x280
movq %rdi, -0x1a0(%rbp)
movq %rdi, %rax
movq %rax, -0x198(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
callq 0xf740
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x1a1(%rbp)
je 0xef16
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
setne %al
movb %al, -0x1a1(%rbp)
movb -0x1a1(%rbp), %al
testb $0x1, %al
jne 0xef22
jmp 0xef30
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xeef1
movq -0x20(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x1b8(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0x1b0(%rbp)
callq 0x3510
movq -0x1c0(%rbp), %rsi
movq -0x1b8(%rbp), %rdx
movq -0x1b0(%rbp), %rcx
leaq -0x50(%rbp), %rdi
callq 0xf760
jmp 0xef76
leaq -0x89(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x3510
movq -0x1c8(%rbp), %rdx
leaq 0x25e4(%rip), %rsi      # 0x1157b
leaq -0x88(%rbp), %rdi
callq 0x5700
jmp 0xefa5
movq -0x1a0(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x6090
movq %rax, -0x1d0(%rbp)
jmp 0xefc1
movq -0x1d0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x33c0
leaq -0x88(%rbp), %rdi
callq 0x3230
leaq -0x89(%rbp), %rdi
callq 0x3340
leaq -0x50(%rbp), %rdi
callq 0x3230
leaq -0x51(%rbp), %rdi
callq 0x3340
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x1d1(%rbp)
je 0xf020
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
sete %al
movb %al, -0x1d1(%rbp)
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0xf02c
jmp 0xf091
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xeffb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf083
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf06e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x3230
leaq -0x89(%rbp), %rdi
callq 0x3340
leaq -0x50(%rbp), %rdi
callq 0x3230
leaq -0x51(%rbp), %rdi
callq 0x3340
jmp 0xf729
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x1d2(%rbp)
je 0xf0be
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
setne %al
movb %al, -0x1d2(%rbp)
movb -0x1d2(%rbp), %al
testb $0x1, %al
jne 0xf0ca
jmp 0xf0d8
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xf099
movq -0x20(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x1e8(%rbp)
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0x3510
movq -0x1f0(%rbp), %rsi
movq -0x1e8(%rbp), %rdx
movq -0x1e0(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
callq 0xf760
jmp 0xf124
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x3510
movq -0x1f8(%rbp), %rdx
leaq 0x243b(%rip), %rsi      # 0x11580
leaq -0xd8(%rbp), %rdi
callq 0x5700
jmp 0xf153
movq -0x1a0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x6090
movq %rax, -0x200(%rbp)
jmp 0xf16f
movq -0x200(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x33c0
leaq -0xd8(%rbp), %rdi
callq 0x3230
leaq -0xd9(%rbp), %rdi
callq 0x3340
leaq -0xb0(%rbp), %rdi
callq 0x3230
leaq -0xb1(%rbp), %rdi
callq 0x3340
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x201(%rbp)
je 0xf1d7
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
sete %al
movb %al, -0x201(%rbp)
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0xf1e3
jmp 0xf24e
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xf1b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf23d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf225
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x3230
leaq -0xd9(%rbp), %rdi
callq 0x3340
leaq -0xb0(%rbp), %rdi
callq 0x3230
leaq -0xb1(%rbp), %rdi
callq 0x3340
jmp 0xf729
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x202(%rbp)
je 0xf27b
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xd, %eax
setne %al
movb %al, -0x202(%rbp)
movb -0x202(%rbp), %al
testb $0x1, %al
jne 0xf287
jmp 0xf295
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xf256
movq -0x20(%rbp), %rax
movq %rax, -0x220(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x218(%rbp)
leaq -0x101(%rbp), %rdi
movq %rdi, -0x210(%rbp)
callq 0x3510
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rdx
movq -0x210(%rbp), %rcx
leaq -0x100(%rbp), %rdi
callq 0xf760
jmp 0xf2e1
leaq -0x129(%rbp), %rdi
movq %rdi, -0x228(%rbp)
callq 0x3510
movq -0x228(%rbp), %rdx
leaq 0x2283(%rip), %rsi      # 0x11585
leaq -0x128(%rbp), %rdi
callq 0x5700
jmp 0xf310
movq -0x1a0(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x6090
movq %rax, -0x230(%rbp)
jmp 0xf32c
movq -0x230(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x33c0
leaq -0x128(%rbp), %rdi
callq 0x3230
leaq -0x129(%rbp), %rdi
callq 0x3340
leaq -0x100(%rbp), %rdi
callq 0x3230
leaq -0x101(%rbp), %rdi
callq 0x3340
movq -0x28(%rbp), %rax
cmpq -0x18(%rbp), %rax
je 0xf3e4
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xf3e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf3d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf3bb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x3230
leaq -0x129(%rbp), %rdi
callq 0x3340
leaq -0x100(%rbp), %rdi
callq 0x3230
leaq -0x101(%rbp), %rdi
callq 0x3340
jmp 0xf729
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x231(%rbp)
jae 0xf411
movq -0x20(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xd, %eax
setne %al
movb %al, -0x231(%rbp)
movb -0x231(%rbp), %al
testb $0x1, %al
jne 0xf420
jmp 0xf703
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x232(%rbp)
jae 0xf44d
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xd, %eax
setne %al
movb %al, -0x232(%rbp)
movb -0x232(%rbp), %al
testb $0x1, %al
jne 0xf459
jmp 0xf467
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xf428
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rax
subq %rax, %rdx
movl $0x3a, %esi
callq 0x3370
movq %rax, -0x138(%rbp)
cmpq $0x0, -0x138(%rbp)
jne 0xf496
jmp 0xf703
movq -0x138(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rcx
xorl %eax, %eax
cmpq -0x28(%rbp), %rcx
movb %al, -0x233(%rbp)
jae 0xf4d3
movq -0x140(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
sete %al
movb %al, -0x233(%rbp)
movb -0x233(%rbp), %al
testb $0x1, %al
jne 0xf4df
jmp 0xf4f3
movq -0x140(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x140(%rbp)
jmp 0xf4a8
movq -0x20(%rbp), %rax
cmpq -0x138(%rbp), %rax
jae 0xf67f
movq -0x140(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0xf67f
movq -0x28(%rbp), %rax
cmpq -0x18(%rbp), %rax
ja 0xf67f
movq -0x140(%rbp), %rax
movq %rax, -0x250(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x248(%rbp)
leaq -0x161(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x3510
movq -0x250(%rbp), %rsi
movq -0x248(%rbp), %rdx
movq -0x240(%rbp), %rcx
leaq -0x160(%rbp), %rdi
callq 0xf760
jmp 0xf572
movq -0x20(%rbp), %rax
movq %rax, -0x268(%rbp)
movq -0x138(%rbp), %rax
movq %rax, -0x260(%rbp)
leaq -0x189(%rbp), %rdi
movq %rdi, -0x258(%rbp)
callq 0x3510
movq -0x268(%rbp), %rsi
movq -0x260(%rbp), %rdx
movq -0x258(%rbp), %rcx
leaq -0x188(%rbp), %rdi
callq 0xf760
jmp 0xf5c1
movq -0x1a0(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x6090
movq %rax, -0x270(%rbp)
jmp 0xf5dd
movq -0x270(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x33c0
leaq -0x188(%rbp), %rdi
callq 0x3230
leaq -0x189(%rbp), %rdi
callq 0x3340
leaq -0x160(%rbp), %rdi
callq 0x3230
leaq -0x161(%rbp), %rdi
callq 0x3340
jmp 0xf67f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf66e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0xf656
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x3230
leaq -0x189(%rbp), %rdi
callq 0x3340
leaq -0x160(%rbp), %rdi
callq 0x3230
leaq -0x161(%rbp), %rdi
callq 0x3340
jmp 0xf729
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x271(%rbp)
jae 0xf6e4
movq -0x20(%rbp), %rax
movsbl (%rax), %ecx
movb $0x1, %al
cmpl $0xa, %ecx
movb %al, -0x272(%rbp)
je 0xf6d8
movq -0x20(%rbp), %rax
movsbl (%rax), %ecx
movb $0x1, %al
cmpl $0xd, %ecx
movb %al, -0x272(%rbp)
je 0xf6d8
movq -0x20(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
sete %al
movb %al, -0x272(%rbp)
movb -0x272(%rbp), %al
movb %al, -0x271(%rbp)
movb -0x271(%rbp), %al
testb $0x1, %al
jne 0xf6f0
jmp 0xf6fe
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0xf68b
jmp 0xf3ec
movb $0x1, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
jne 0xf719
movq -0x1a0(%rbp), %rdi
callq 0x60c0
movq -0x198(%rbp), %rax
addq $0x280, %rsp            # imm = 0x280
popq %rbp
retq
movq -0x1a0(%rbp), %rdi
callq 0x60c0
movq -0x60(%rbp), %rdi
callq 0x3500
nop