// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x530, %rsp            # imm = 0x530
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x3cac
jmp 0x3ccb
leaq 0x3882(%rip), %rdi      # 0x7535
leaq 0x3c8e(%rip), %rsi      # 0x7948
movl $0xfa, %edx
leaq 0x40e8(%rip), %rcx      # 0x7dae
callq 0x2100
cmpq $0x0, -0x18(%rbp)
je 0x3cd4
jmp 0x3cf3
leaq 0x3d1e(%rip), %rdi      # 0x79f9
leaq 0x3c66(%rip), %rsi      # 0x7948
movl $0xfb, %edx
leaq 0x40c0(%rip), %rcx      # 0x7dae
callq 0x2100
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movl $0xff, %esi
callq 0x34a0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x3d33
movl $0x1, -0x4(%rbp)
jmp 0x445e
jmp 0x3d35
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq %rax, %rdi
callq 0x4470
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x4da(%rbp)
jge 0x3d78
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpq $0x1000, 0x10(%rax)     # imm = 0x1000
setle %al
movb %al, -0x4da(%rbp)
movb -0x4da(%rbp), %al
testb $0x1, %al
jne 0x3d84
jmp 0x3df9
leaq -0x130(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2130
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rcx
movl 0x40(%rcx), %esi
leaq -0x130(%rbp), %rdx
movl $0xff, %ecx
callq *%rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x130(%rbp), %rdx
callq 0x3540
movsbl -0x130(%rbp), %eax
cmpl $0x0, %eax
jne 0x3df4
jmp 0x3df9
jmp 0x3d35
cmpq $0x0, -0x28(%rbp)
jne 0x3e1a
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x3, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq %rax, %rdx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rcx
leaq -0x269(%rbp), %rdi
leaq 0x3f96(%rip), %rsi      # 0x7dde
callq 0x3ab0
leaq -0x269(%rbp), %rdi
addq $0x32, %rdi
callq 0x2290
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq %rax, %rdi
callq 0x4470
movq %rax, -0x278(%rbp)
movq -0x278(%rbp), %rax
subq $0x4, %rax
movq %rax, -0x280(%rbp)
cmpq $0x0, -0x278(%rbp)
jl 0x3eb8
movq -0x28(%rbp), %rax
subq -0x278(%rbp), %rax
movq %rax, -0x4e8(%rbp)
jmp 0x3ec3
xorl %eax, %eax
movq %rax, -0x4e8(%rbp)
jmp 0x3ec3
movq -0x4e8(%rbp), %rax
movq %rax, -0x288(%rbp)
cmpq $0x0, -0x280(%rbp)
jle 0x3f45
movq -0x10(%rbp), %rdi
movq -0x280(%rbp), %rsi
addq $0x1, %rsi
callq 0x45b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x4f0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x4f0(%rbp), %rdi
movq %rax, %rsi
movq -0x280(%rbp), %rdx
callq 0x2060
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x280(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x3f69
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x45b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movb $0x0, (%rax)
jmp 0x3f6b
movq -0x288(%rbp), %rcx
movq -0x18(%rbp), %rdx
xorl %eax, %eax
cmpq 0x28(%rdx), %rcx
movb %al, -0x4f1(%rbp)
jge 0x3f9d
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpq $0x1000, 0x10(%rax)     # imm = 0x1000
setle %al
movb %al, -0x4f1(%rbp)
movb -0x4f1(%rbp), %al
testb $0x1, %al
jne 0x3fa9
jmp 0x4027
leaq -0x390(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2130
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rcx
movl 0x40(%rcx), %esi
leaq -0x390(%rbp), %rdx
movl $0xff, %ecx
callq *%rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jle 0x4020
movq -0x20(%rbp), %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x390(%rbp), %rdx
callq 0x3540
movq -0x28(%rbp), %rax
subq -0x278(%rbp), %rax
movq %rax, -0x288(%rbp)
jmp 0x4022
jmp 0x4027
jmp 0x3f6b
cmpq $0x0, -0x28(%rbp)
jg 0x406d
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x3db0(%rip), %rdx      # 0x7ded
callq 0x37e0
cmpl $0x0, %eax
je 0x4053
movl $0x1, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x3, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq %rax, %rdi
callq 0x46a0
movl %eax, -0x394(%rbp)
cmpl $0x64, -0x394(%rbp)
jne 0x40d4
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x3d65(%rip), %rdx      # 0x7e09
callq 0x37e0
cmpl $0x0, %eax
je 0x40ba
movl $0x1, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x3, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
jmp 0x445e
cmpl $0x65, -0x394(%rbp)
jne 0x40e8
xorl %eax, %eax
movq %rax, -0x500(%rbp)
jmp 0x4127
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq %rax, -0x508(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq %rax, %rdi
callq 0x4470
movq %rax, %rcx
movq -0x508(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x500(%rbp)
movq -0x500(%rbp), %rax
movq %rax, -0x3a0(%rbp)
movl -0x394(%rbp), %edx
movl $0x5, %eax
movl $0x4, %ecx
cmpl $0x65, %edx
cmovel %ecx, %eax
cltq
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jge 0x41ac
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x20(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jne 0x419c
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x41ac
jmp 0x419e
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x4151
movl -0x394(%rbp), %edx
movl $0x5, %eax
movl $0x4, %ecx
cmpl $0x65, %edx
cmovel %ecx, %eax
cltq
movq %rax, -0x3a8(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x3a8(%rbp), %rcx
movsbl 0x1(%rax,%rcx), %eax
cmpl $0x2f, %eax
jne 0x422c
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x3c3f(%rip), %rdx      # 0x7e3b
callq 0x37e0
cmpl $0x0, %eax
je 0x4212
movl $0x1, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x3, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
jmp 0x445e
jmp 0x422e
movq -0x3a8(%rbp), %rax
movq -0x20(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jge 0x42e1
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x3a8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x2e, %eax
jne 0x42c8
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x3a8(%rbp), %rcx
movsbl 0x1(%rax,%rcx), %eax
cmpl $0x2e, %eax
jne 0x42c8
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x3bc4(%rip), %rdx      # 0x7e5c
callq 0x37e0
cmpl $0x0, %eax
je 0x42ae
movl $0x1, -0x4(%rbp)
jmp 0x445e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x3, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
jmp 0x445e
jmp 0x42ca
movq -0x3a8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x3a8(%rbp)
jmp 0x422e
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x510(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x20b0
movq -0x510(%rbp), %rdx
movq %rax, %rcx
leaq -0x4d9(%rbp), %rdi
leaq 0x3b6b(%rip), %rsi      # 0x7e80
callq 0x3ab0
leaq -0x4d9(%rbp), %rdi
addq $0x32, %rdi
callq 0x20b0
movq %rax, -0x3a8(%rbp)
cmpq $0x0, -0x3a8(%rbp)
jle 0x43a8
movq -0x10(%rbp), %rdi
movq -0x3a8(%rbp), %rsi
addq $0x1, %rsi
callq 0x45b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x4d9(%rbp), %rsi
addq $0x32, %rsi
movq -0x3a8(%rbp), %rdx
callq 0x2060
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
leaq 0x32fe(%rip), %rsi      # 0x7686
callq 0x4760
cmpl $0x0, %eax
je 0x43a6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x3a0(%rbp), %rdx
callq 0x47d0
jmp 0x43cc
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x45b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movb $0x0, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x518(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x528(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x520(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x3610
movq -0x528(%rbp), %rdi
movq -0x520(%rbp), %rsi
movq %rax, %rdx
movq -0x518(%rbp), %rax
movl -0x394(%rbp), %r9d
movl $0x6, %ecx
movl $0x5, %r8d
cmpl $0x65, %r9d
cmovel %r8d, %ecx
movslq %ecx, %rcx
addq %rcx, %rdx
movq -0x3a0(%rbp), %rcx
movl -0x394(%rbp), %r8d
callq *%rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x1, %edx
callq 0x44f0
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x530, %rsp            # imm = 0x530
popq %rbp
retq
nopw (%rax,%rax)