// File: alibakhtiar[P]ExampleHTTPServer/./HttpServer.hh
// Function: SimpleHttpServer::httpRequestParse(SimpleHttpServer::Request*, char const*, unsigned long)
bool httpRequestParse(Request *req, const char *buffer, size_t length)
{
	std::string tmp = "";
	int state = PARSER_STATE_METHOD;
	bool isKey = true;

	size_t i;
	for (i=0; i<length; ++i)
	{
		switch (state) {
			case PARSER_STATE_METHOD:
				if (buffer[i] == ' ') {
					req->method = tmp;
					state = PARSER_STATE_URL;
					tmp = "";
					break;
				}
				tmp += buffer[i];
			break;

			case PARSER_STATE_URL:
				if (buffer[i] == ' ' || buffer[i] == '?') {
					req->url = tmp;
					state = buffer[i] == '?' ? PARSER_STATE_URL_QS : PARSER_STATE_PROTOCOL;
					tmp = "";
					continue;
				}

				// Simple XSS filter
				// ascii 34 == "
				// ascii 39 == '
				if (buffer[i] == '<' || buffer[i] == '>' || buffer[i] == 34 || buffer[i] == 39)
					continue;

				tmp += buffer[i];
			break;

			case PARSER_STATE_URL_QS:
				if (buffer[i] == ' ') {
					req->queryString = tmp;
					state = PARSER_STATE_PROTOCOL;
					tmp = "";
					continue;
				}

				// Simple XSS filter
				// ascii 34 == "
				// ascii 39 == '
				if (buffer[i] == '<' || buffer[i] == '>' || buffer[i] == 34 || buffer[i] == 39)
					continue;

				tmp += buffer[i];
			break;

			case PARSER_STATE_PROTOCOL:
				if (buffer[i] == '/') {
					if (tmp != "HTTP")
						req->hasError = true;

					state = PARSER_STATE_MAJOR;
					tmp = "";
					continue;
				}
				else {
					tmp += buffer[i];
				}
			break;

			case PARSER_STATE_MAJOR:
				if (isdigit(buffer[i]) != 0) {
					req->httpMajorVersion = (int)buffer[i] - '0';
				}
				else if (buffer[i] == '.') {
					state = PARSER_STATE_MINOR;
				}
			break;

			case PARSER_STATE_MINOR:
				if (isdigit(buffer[i]) != 0) {
					req->httpMinorVersion = (int)buffer[i] - '0';
				}

				if (buffer[i] == '\n')
					state = PARSER_STATE_HEADERS;
			break;

			case PARSER_STATE_HEADERS:
				if (buffer[i] == '\n') {
					isKey = true;
					tmp = "";
				}
				else if (isKey == true && buffer[i] == ':') {
					strtolower(tmp);
					req->headers[tmp] = "";
					isKey = false;
				}
				else if (isKey == true) {
					tmp += buffer[i];
				}
				else if (isKey == false) {
					if (buffer[i] == '\r' || (req->headers[tmp].size() == 0 && buffer[i] == ' '))
						continue;

					req->headers[tmp] += buffer[i];
				}
			break;
		}
	}

	tmp.clear();

	if (req->httpMajorVersion != 1) {
		req->hasError = true;
	}

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x68(%rbp)
callq 0x3450
movq -0x68(%rbp), %rdx
leaq 0x5cd7(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x4dc0
jmp 0x362a
leaq -0x39(%rbp), %rdi
callq 0x3300
movl $0x1, -0x50(%rbp)
movb $0x1, -0x51(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x3b07
movl -0x50(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x70(%rbp)
subl $0x6, %eax
ja 0x3af4
movq -0x70(%rbp), %rax
leaq 0x5991(%rip), %rcx      # 0x9004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x3300
jmp 0x3b3b
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jne 0x36f2
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
leaq -0x38(%rbp), %rsi
callq 0x3050
jmp 0x36ba
movl $0x2, -0x50(%rbp)
leaq 0x5c2e(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x33a0
jmp 0x36d3
jmp 0x3af4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x31b0
jmp 0x3b3b
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %esi
leaq -0x38(%rbp), %rdi
callq 0x31c0
jmp 0x3709
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
je 0x3730
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3f, %eax
jne 0x3773
movq -0x8(%rbp), %rdi
addq $0x40, %rdi
leaq -0x38(%rbp), %rsi
callq 0x3050
jmp 0x3743
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movb (%rax,%rcx), %al
subb $0x3f, %al
setne %al
movzbl %al, %eax
addl $0x3, %eax
movl %eax, -0x50(%rbp)
leaq 0x5b93(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x33a0
jmp 0x376e
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3c, %eax
je 0x37b7
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3e, %eax
je 0x37b7
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x22, %eax
je 0x37b7
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x27, %eax
jne 0x37bc
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %esi
leaq -0x38(%rbp), %rdi
callq 0x31c0
jmp 0x37d3
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jne 0x381a
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
leaq -0x38(%rbp), %rsi
callq 0x3050
jmp 0x37fc
movl $0x4, -0x50(%rbp)
leaq 0x5aec(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x33a0
jmp 0x3815
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3c, %eax
je 0x385e
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3e, %eax
je 0x385e
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x22, %eax
je 0x385e
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x27, %eax
jne 0x3863
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %esi
leaq -0x38(%rbp), %rdi
callq 0x31c0
jmp 0x387a
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x2f, %eax
jne 0x38d4
leaq 0x57a5(%rip), %rsi      # 0x903c
leaq -0x38(%rbp), %rdi
callq 0x4e70
movb %al, -0x71(%rbp)
jmp 0x38a5
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x38ae
jmp 0x38b6
movq -0x8(%rbp), %rax
movb $0x1, 0x1c(%rax)
movl $0x5, -0x50(%rbp)
leaq 0x5a32(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x33a0
jmp 0x38cf
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %esi
leaq -0x38(%rbp), %rdi
callq 0x31c0
jmp 0x38eb
jmp 0x38ed
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %edi
callq 0x3260
cmpl $0x0, %eax
je 0x3923
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %ecx
subl $0x30, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x80(%rax)
jmp 0x393d
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x2e, %eax
jne 0x393b
movl $0x6, -0x50(%rbp)
jmp 0x393d
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %edi
callq 0x3260
cmpl $0x0, %eax
je 0x3971
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %ecx
subl $0x30, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x84(%rax)
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xa, %eax
jne 0x3989
movl $0x7, -0x50(%rbp)
jmp 0x3af4
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xa, %eax
jne 0x39ba
movb $0x1, -0x51(%rbp)
leaq 0x594c(%rip), %rsi      # 0x92f6
leaq -0x38(%rbp), %rdi
callq 0x33a0
jmp 0x39b5
jmp 0x3af2
movb -0x51(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x3a18
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3a, %eax
jne 0x3a18
leaq -0x38(%rbp), %rdi
callq 0x3b50
jmp 0x39e3
movq -0x8(%rbp), %rdi
addq $0x88, %rdi
leaq -0x38(%rbp), %rsi
callq 0x4ea0
movq %rax, -0x80(%rbp)
jmp 0x39fd
movq -0x80(%rbp), %rdi
leaq 0x58ee(%rip), %rsi      # 0x92f6
callq 0x33a0
jmp 0x3a0f
movb $0x0, -0x51(%rbp)
jmp 0x3af0
movb -0x51(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x3a41
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %esi
leaq -0x38(%rbp), %rdi
callq 0x31c0
jmp 0x3a3c
jmp 0x3aee
movb -0x51(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3aec
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0xd, %eax
je 0x3aa3
movq -0x8(%rbp), %rdi
addq $0x88, %rdi
leaq -0x38(%rbp), %rsi
callq 0x4ea0
movq %rax, -0x88(%rbp)
jmp 0x3a80
movq -0x88(%rbp), %rdi
callq 0x31f0
cmpq $0x0, %rax
jne 0x3aa5
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jne 0x3aa5
jmp 0x3af6
movq -0x10(%rbp), %rax
movq -0x60(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x91(%rbp)
movq -0x8(%rbp), %rdi
addq $0x88, %rdi
leaq -0x38(%rbp), %rsi
callq 0x4ea0
movq %rax, -0x90(%rbp)
jmp 0x3ad3
movq -0x90(%rbp), %rdi
movb -0x91(%rbp), %al
movsbl %al, %esi
callq 0x31c0
jmp 0x3aea
jmp 0x3aec
jmp 0x3aee
jmp 0x3af0
jmp 0x3af2
jmp 0x3af4
jmp 0x3af6
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x3646
leaq -0x38(%rbp), %rdi
callq 0x3390
movq -0x8(%rbp), %rax
cmpl $0x1, 0x80(%rax)
je 0x3b25
movq -0x8(%rbp), %rax
movb $0x1, 0x1c(%rax)
leaq -0x38(%rbp), %rdi
callq 0x31b0
movb $0x1, %al
andb $0x1, %al
addq $0xa0, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x3440
nopw %cs:(%rax,%rax)