// File: /workspace/github_c_makefile_star2_O2/howerj[P]eweb/eweb.c
// Function: eweb_hit
int eweb_hit(eweb_os_t *w, eweb_os_hit_args_t *args) {
	assert(w);
	assert(args);

	long i = 0, request_size = 0;
	args->buffer = string_new(w, READ_BUF_LEN);
	if (!args->buffer) {
		return EWEB_ERROR;
	}

	/* We need to read the HTTP headers first so loop until we receive "\r\n\r\n" */
	while (eweb_get_body_start(string_chars(w, args->buffer)) < 0 && args->buffer->used_bytes <= MAX_INCOMING_REQUEST) {
		char buf[READ_BUF_LEN + 1] = { 0 };
		const long rd = w->read(w, args->socketfd, buf, READ_BUF_LEN); // !!
		request_size += rd;
		string_add(w, args->buffer, buf); // !!
		if (buf[0] == 0)
			break;
	}

	if (request_size == 0)
		return eweb_finish_hit(w, args, 3);

	eweb_http_header_t content_length = eweb_get_header("Content-Length", string_chars(w, args->buffer), args->buffer->used_bytes);
	args->content_length   = atol(content_length.value);
	const long body_start  = eweb_get_body_start(string_chars(w, args->buffer)); // !?
	const long headers_end = body_start - 4;
	long body_size         = body_start >= 0 ? request_size - body_start : 0;

	if (headers_end > 0) {
		args->headers = eweb_malloc_or_die(w, headers_end + 1); // !!
		strncpy(args->headers, string_chars(w, args->buffer), headers_end);
		args->headers[headers_end] = 0;
	} else {
		args->headers = eweb_malloc_or_die(w, 1); // !!
		args->headers[0] = 0;
	}

	/* safari seems to send the headers, and then the body slightly later */
	while (body_size < args->content_length && args->buffer->used_bytes <= MAX_INCOMING_REQUEST) {
		char buf[READ_BUF_LEN + 1] = { 0 };
		i = w->read(w, args->socketfd, buf, READ_BUF_LEN);
		if (i > 0) {
			request_size += i;
			string_add(w, args->buffer, buf); // !!
			body_size = request_size - body_start;
		} else {
			/* stop looping if we cannot read any more bytes */
			break;
		}
	}

	if (request_size <= 0) { /* cannot read request, so we'll stop */
		if (eweb_forbidden_403(w, args, "failed to read http request") != EWEB_OK) // !? Odd error message...
			return EWEB_ERROR; // !! call eweb_finish_hit??
		return eweb_finish_hit(w, args, 3);
	}

	//w->log(w, EWEB_OK, "request: %s/%ld", string_chars(w, args->buffer), args->hit);

	const http_verb type = eweb_request_type(string_chars(w, args->buffer));
	if (type == EWEB_RT_HTTP_NOT_SUPPORTED_E) {
		if (eweb_forbidden_403(w, args, "Only simple GET and POST operations are supported") != EWEB_OK)
			return EWEB_ERROR;
		return eweb_finish_hit(w, args, 3);
	}
	/* get a pointer to the request body (or NULL if it's not there) */
	char *body = (type == EWEB_RT_HTTP_GET_E) ? NULL : (char*)args->buffer->ptr + eweb_get_body_start(string_chars(w, args->buffer));

	/* the request will be "GET [URL] " or "POST [URL] " followed by other details
	we will terminate after the second space, to ignore everything else */
	for (i = (type == EWEB_RT_HTTP_GET_E) ? 4 : 5; i < args->buffer->used_bytes; i++) {
		if (string_chars(w, args->buffer)[i] == ' ') {
			string_chars(w, args->buffer)[i] = 0;	/* second space, terminate string here */
			break;
		}
	}

	long j = (type == EWEB_RT_HTTP_GET_E) ? 4 : 5;

	/* check for an absolute directory */
	if (string_chars(w, args->buffer)[j + 1] == '/') {
		if (eweb_forbidden_403(w, args, "Absolute paths are not permitted") != EWEB_OK)
			return EWEB_ERROR;
		return eweb_finish_hit(w, args, 3);
	}

	for (; j < i - 1; j++) {
		/* check for any parent directory use */
		if (string_chars(w, args->buffer)[j] == '.' && string_chars(w, args->buffer)[j + 1] == '.') {
			if (eweb_forbidden_403(w, args, "Parent paths (..) are not permitted") != EWEB_OK)
				return EWEB_ERROR;
			return eweb_finish_hit(w, args, 3);
		}
	}

	eweb_http_header_t ctype = eweb_get_header("Content-Type", args->headers, strlen(args->headers));
	j = strlen(ctype.value);
	if (j > 0) {
		args->content_type = eweb_malloc_or_die(w, j + 1); // !!
		strncpy(args->content_type, ctype.value, j);
		if (eweb_string_matches_value(args->content_type, "application/x-www-form-urlencoded"))
			eweb_get_form_values(w, args, body);
	} else {
		args->content_type = eweb_malloc_or_die(w, 1); // !!
		args->content_type[0] = 0;
	}

	/* call the "responder function" which has been provided to do the rest */
	args->responder_function(w, args, string_chars(w, args->buffer) + ((type == EWEB_RT_HTTP_GET_E) ? 5 : 6), body, type);
	return eweb_finish_hit(w, args, 1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2b8, %rsp            # imm = 0x2B8
testq %rdi, %rdi
je 0x39f2
movq %rsi, %rbx
testq %rsi, %rsi
je 0x3a11
movq %rdi, %r14
movl $0xff, %esi
callq 0x2e76
movq %rax, 0x8(%rbx)
testq %rax, %rax
je 0x3953
xorl %ebp, %ebp
leaq 0x40(%rsp), %r15
movq 0x8(%rbx), %rsi
callq 0x2f9d
movq %rax, %rdi
callq 0x3a6c
testq %rax, %rax
jns 0x34c8
movq 0x8(%rbx), %rax
cmpq $0x1000, 0x10(%rax)     # imm = 0x1000
jg 0x34c8
movl $0x100, %edx            # imm = 0x100
movq %r15, %rdi
xorl %esi, %esi
callq 0x2100
movl 0x40(%rbx), %esi
movl $0xff, %ecx
movq %r14, %rdi
movq %r15, %rdx
callq *0x38(%r14)
addq %rax, %rbp
movq 0x8(%rbx), %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x2f18
cmpb $0x0, 0x40(%rsp)
jne 0x346a
testq %rbp, %rbp
je 0x3958
movq 0x8(%rbx), %rsi
callq 0x2f9d
movq 0x8(%rbx), %rcx
movq 0x10(%rcx), %rcx
leaq 0x2838(%rip), %rsi      # 0x5d21
leaq 0x40(%rsp), %rdi
movq %rax, %rdx
callq 0x3311
leaq 0x72(%rsp), %rdi
callq 0x2260
movq %rax, 0x28(%rbx)
movq 0x8(%rbx), %rsi
callq 0x2f9d
movq %rax, %rdi
callq 0x3a6c
movq %rax, %r15
movq %rbp, %rax
subq %r15, %rax
xorl %r13d, %r13d
testq %r15, %r15
cmovnsq %rax, %r13
cmpq $0x5, %r15
jl 0x3566
leaq -0x4(%r15), %r12
leaq -0x3(%r15), %rsi
movq %r14, %rdi
callq 0x3b18
movq %rax, 0x8(%rsp)
movq %rax, 0x10(%rbx)
movq 0x8(%rbx), %rsi
callq 0x2f9d
movq 0x8(%rsp), %rdi
movq %rax, %rsi
movq %r12, %rdx
callq 0x2060
addq 0x10(%rbx), %r12
jmp 0x3578
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x3b18
movq %rax, %r12
movq %rax, 0x10(%rbx)
movb $0x0, (%r12)
leaq 0x180(%rsp), %r12
cmpq 0x28(%rbx), %r13
jge 0x35d9
movq 0x8(%rbx), %rax
cmpq $0x1000, 0x10(%rax)     # imm = 0x1000
jg 0x35d9
movl $0x100, %edx            # imm = 0x100
movq %r12, %rdi
xorl %esi, %esi
callq 0x2100
movl 0x40(%rbx), %esi
movl $0xff, %ecx
movq %r14, %rdi
movq %r12, %rdx
callq *0x38(%r14)
testq %rax, %rax
jle 0x35d9
addq %rax, %rbp
movq 0x8(%rbx), %rsi
movq %r14, %rdi
movq %r12, %rdx
callq 0x2f18
movq %rbp, %r13
subq %r15, %r13
jmp 0x3585
testq %rbp, %rbp
jle 0x3678
movq 0x8(%rbx), %rsi
callq 0x2f9d
testq %rax, %rax
je 0x3a30
movq %rax, %r12
leaq 0x2b79(%rip), %rsi      # 0x6177
pushq $0x4
popq %r13
movq %rax, %rdi
movq %r13, %rdx
callq 0x2070
pushq $0x65
popq %rbp
pushq $0x5
popq %r15
testl %eax, %eax
je 0x366e
leaq 0x2b5d(%rip), %rsi      # 0x617c
pushq $0x4
popq %r13
movq %r12, %rdi
movq %r13, %rdx
callq 0x2070
testl %eax, %eax
je 0x366e
leaq 0x2b48(%rip), %rsi      # 0x6181
pushq $0x5
popq %r13
movq %r12, %rdi
movq %r13, %rdx
callq 0x2070
testl %eax, %eax
je 0x3684
leaq 0x2b34(%rip), %rsi      # 0x6187
pushq $0x5
popq %rdx
movq %r12, %rdi
callq 0x2070
testl %eax, %eax
je 0x3684
leaq 0x26e3(%rip), %rdx      # 0x5d4c
jmp 0x3944
movq %r15, 0x8(%rsp)
xorl %r12d, %r12d
jmp 0x36a4
leaq 0x26b1(%rip), %rdx      # 0x5d30
jmp 0x3944
movq 0x8(%rbx), %rax
movq (%rax), %r15
movq %r15, %rdi
callq 0x3a6c
movq %rax, %r12
addq %r15, %r12
pushq $0x66
popq %rbp
pushq $0x6
popq %rax
movq %rax, 0x8(%rsp)
movq %r13, %r15
movq 0x8(%rbx), %rsi
cmpq 0x10(%rsi), %r15
jge 0x36d4
callq 0x2f9d
cmpb $0x20, (%rax,%r15)
je 0x36c2
incq %r15
jmp 0x36a7
movq 0x8(%rbx), %rsi
callq 0x2f9d
movb $0x0, (%rax,%r15)
movq 0x8(%rbx), %rsi
callq 0x2f9d
cmpb $0x2f, 0x1(%rax,%r13)
jne 0x36ed
leaq 0x2696(%rip), %rdx      # 0x5d7e
jmp 0x3944
decq %r15
cmpq %r15, %r13
jae 0x371f
movq 0x8(%rbx), %rsi
callq 0x2f9d
cmpb $0x2e, (%rax,%r13)
jne 0x371a
movq 0x8(%rbx), %rsi
callq 0x2f9d
cmpb $0x2e, 0x1(%rax,%r13)
je 0x393d
incq %r13
jmp 0x36f0
movq %r12, 0x30(%rsp)
movq 0x10(%rbx), %r15
movq %r15, %rdi
callq 0x20b0
leaq 0x268c(%rip), %rsi      # 0x5dc3
leaq 0x180(%rsp), %rdi
movq %r15, %rdx
movq %rax, %rcx
callq 0x3311
leaq 0x1b2(%rsp), %r12
movq %r12, %rdi
callq 0x20b0
testq %rax, %rax
jle 0x397a
movq %rax, %r13
movq %rax, %rsi
incq %rsi
movq %r14, %rdi
callq 0x3b18
movq %rax, 0x18(%rbx)
movq %rax, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x2060
movq 0x18(%rbx), %rdi
leaq 0x1e38(%rip), %rsi      # 0x55c9
callq 0x3bb3
testl %eax, %eax
je 0x39c6
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3a4f
leaq 0x38(%rsp), %rsi
andq $0x0, (%rsi)
callq 0x41de
movq %rax, %r12
pushq $0x18
popq %rsi
pushq $0xa
popq %rdx
movq %r14, %rdi
movq %rdx, 0x28(%rsp)
callq 0x3d77
movq %rax, 0x20(%rbx)
testq %rax, %rax
je 0x39bb
movq $0x0, 0x18(%rsp)
movl %ebp, 0x14(%rsp)
testq %r12, %r12
je 0x398e
movq %r12, %rdi
callq 0x20b0
movq %rax, %r15
incq %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x3b18
testq %rax, %rax
je 0x39bb
movq %rax, %r13
movq %rax, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x21b0
movq %r14, %rdi
movq %r13, %rsi
callq 0x3e37
testl %eax, %eax
jne 0x3999
movq %r13, %rdi
callq 0x20b0
movq %rax, %r12
negq %rax
pushq $0x1
popq %r15
leaq (%rax,%r15), %rcx
cmpq $0x1, %rcx
je 0x391e
cmpb $0x3d, -0x1(%r13,%r15)
je 0x3866
incq %r15
jmp 0x384b
movq 0x28(%rsp), %rbp
cmpq 0x18(%rsp), %rbp
jle 0x3879
movq %rbp, 0x20(%rsp)
jmp 0x38b2
leaq 0xa(%rbp), %rax
movq 0x20(%rbx), %rsi
movq %rax, 0x20(%rsp)
imulq $0x18, %rax, %rdx
movq %r14, %rdi
callq 0x4038
testq %rax, %rax
je 0x39ac
movq %rax, 0x20(%rbx)
imulq $0x18, %rbp, %rdi
addq %rax, %rdi
movl $0xf0, %edx
xorl %esi, %esi
callq 0x2100
movq %r13, %rdi
callq 0x20b0
leaq 0x1(%rax), %rsi
movq %r14, %rdi
callq 0x3b18
movq 0x20(%rbx), %rcx
imulq $0x18, 0x18(%rsp), %rbp
movq %rax, 0x10(%rcx,%rbp)
testq %rax, %rax
je 0x39ac
incq %r12
movq %rax, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x21b0
movq 0x20(%rbx), %rax
movq 0x10(%rax,%rbp), %rcx
movq %rcx, (%rax,%rbp)
leaq (%rcx,%r15), %rdx
movq %rdx, 0x8(%rax,%rbp)
incq 0x18(%rsp)
movb $0x0, -0x1(%rcx,%r15)
movq 0x20(%rsp), %rax
movq %rax, 0x28(%rsp)
movl 0x14(%rsp), %ebp
xorl %edi, %edi
leaq 0x38(%rsp), %rsi
callq 0x41de
movq %rax, %r12
movq %r14, %rdi
movq %r13, %rsi
callq 0x3f84
jmp 0x37ea
leaq 0x245b(%rip), %rdx      # 0x5d9f
movq %r14, %rdi
movq %rbx, %rsi
callq 0x30fb
testl %eax, %eax
je 0x3958
pushq $0x1
popq %rax
jmp 0x3968
pushq $0x3
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3abb
xorl %eax, %eax
addq $0x2b8, %rsp            # imm = 0x2B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x3b18
movq %rax, 0x18(%rbx)
movb $0x0, (%rax)
jmp 0x39c6
movq 0x18(%rsp), %rax
movq %rax, 0x30(%rbx)
jmp 0x39c6
leaq 0x2838(%rip), %rdx      # 0x61d8
pushq $0x1
popq %rsi
movq %r14, %rdi
xorl %eax, %eax
callq *0x50(%r14)
movq %r14, %rdi
movq %r13, %rsi
callq 0x3f84
movl 0x14(%rsp), %ebp
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4190
movq (%rbx), %r15
movq 0x8(%rbx), %rsi
callq 0x2f9d
movq 0x8(%rsp), %rdx
addq %rax, %rdx
movq %r14, %rdi
movq %rbx, %rsi
movq 0x30(%rsp), %rcx
movl %ebp, %r8d
callq *%r15
pushq $0x1
jmp 0x395a
leaq 0x1b34(%rip), %rdi      # 0x552d
leaq 0x1e8b(%rip), %rsi      # 0x588b
leaq 0x22ea(%rip), %rcx      # 0x5cf1
movl $0xfa, %edx
callq 0x20e0
leaq 0x1f24(%rip), %rdi      # 0x593c
leaq 0x1e6c(%rip), %rsi      # 0x588b
leaq 0x22cb(%rip), %rcx      # 0x5cf1
movl $0xfb, %edx
callq 0x20e0
leaq 0x1b8a(%rip), %rdi      # 0x55c1
leaq 0x1e4d(%rip), %rsi      # 0x588b
leaq 0x2708(%rip), %rcx      # 0x614d
movl $0xf0, %edx
callq 0x20e0
leaq 0x277b(%rip), %rdi      # 0x61d1
leaq 0x1e2e(%rip), %rsi      # 0x588b
leaq 0x2729(%rip), %rcx      # 0x618d
pushq $0x35
popq %rdx
callq 0x20e0