// File: nilnilnil[P]autocomplete/deps/mongoose/mongoose.c
// Function: handle_proxy_request
static void handle_proxy_request(struct mg_connection *conn) {
  struct mg_request_info *ri = &conn->request_info;
  char host[1025], buf[BUFSIZ];
  int port, is_ssl, len, i, n;

  DEBUG_TRACE(("URL: %s", ri->uri));
  if (conn->request_info.uri[0] == '/' ||
      (ri->uri == NULL || (len = parse_url(ri->uri, host, &port))) == 0) {
    return;
  }

  if (conn->peer == NULL) {
    is_ssl = !strcmp(ri->request_method, "CONNECT");
    if ((conn->peer = mg_connect(conn, host, port, is_ssl)) == NULL) {
      return;
    }
    conn->peer->client.is_ssl = is_ssl;
  }
  
  // Forward client's request to the target
  mg_printf(conn->peer, "%s %s HTTP/%s\r\n", ri->request_method, ri->uri + len,
            ri->http_version);

  // And also all headers. TODO(lsm): anonymize!
  for (i = 0; i < ri->num_headers; i++) {
    mg_printf(conn->peer, "%s: %s\r\n", ri->http_headers[i].name,
              ri->http_headers[i].value);
  }
  // End of headers, final newline
  mg_write(conn->peer, "\r\n", 2);

  // Read and forward body data if any
  if (!strcmp(ri->request_method, "POST")) {
    forward_body_data(conn, NULL, conn->peer->client.sock, conn->peer->ssl);
  }

  // Read data from the target and forward it to the client
  while ((n = pull(NULL, conn->peer->client.sock, conn->peer->ssl,
                   buf, sizeof(buf))) > 0) {
    if (mg_write(conn, buf, (size_t)n) != n) {
      break;
    }
  }

  if (!conn->peer->client.is_ssl) {
    close_connection(conn->peer);
    free(conn->peer);
    conn->peer = NULL;
  }
}

// Assembly:
subq $0x2438, %rsp           # imm = 0x2438
movq %rdi, 0x2430(%rsp)
movq 0x2430(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x2428(%rsp)
movq 0x2430(%rsp), %rax
movq 0x18(%rax), %rax
movsbl (%rax), %eax
cmpl $0x2f, %eax
je 0x1c346
movq 0x2428(%rsp), %rcx
movb $0x1, %al
cmpq $0x0, 0x10(%rcx)
movb %al, 0xb(%rsp)
je 0x1c338
movq 0x2428(%rsp), %rax
movq 0x10(%rax), %rdi
leaq 0x2020(%rsp), %rsi
leaq 0x1c(%rsp), %rdx
callq 0x1d190
movl %eax, 0x14(%rsp)
cmpl $0x0, %eax
setne %al
movb %al, 0xb(%rsp)
movb 0xb(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1c34b
jmp 0x1c598
movq 0x2430(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x1c3ca
movq 0x2428(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x6bb9(%rip), %rsi      # 0x22f25
callq 0x5810
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x18(%rsp)
movq 0x2430(%rsp), %rdi
leaq 0x2020(%rsp), %rsi
movl 0x1c(%rsp), %edx
movl 0x18(%rsp), %ecx
callq 0x1d260
movq 0x2430(%rsp), %rcx
movq %rax, (%rcx)
cmpq $0x0, %rax
jne 0x1c3b5
jmp 0x1c598
movl 0x18(%rsp), %ecx
movq 0x2430(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x49c(%rax)
movq 0x2430(%rsp), %rax
movq (%rax), %rdi
movq 0x2428(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x2428(%rsp), %rax
movq 0x10(%rax), %rcx
movslq 0x14(%rsp), %rax
addq %rax, %rcx
movq 0x2428(%rsp), %rax
movq 0x18(%rax), %r8
leaq 0x6b7f(%rip), %rsi      # 0x22f87
movb $0x0, %al
callq 0x17030
movl $0x0, 0x10(%rsp)
movl 0x10(%rsp), %eax
movq 0x2428(%rsp), %rcx
cmpl 0x4c(%rcx), %eax
jge 0x1c485
movq 0x2430(%rsp), %rax
movq (%rax), %rdi
movq 0x2428(%rsp), %rax
addq $0x50, %rax
movslq 0x10(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdx
movq 0x2428(%rsp), %rax
addq $0x50, %rax
movslq 0x10(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
leaq 0x6b26(%rip), %rsi      # 0x22f97
movb $0x0, %al
callq 0x17030
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x1c417
movq 0x2430(%rsp), %rax
movq (%rax), %rdi
leaq 0x6db1(%rip), %rsi      # 0x23248
movl $0x2, %edx
callq 0x16ed0
movq 0x2428(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x6a67(%rip), %rsi      # 0x22f1b
callq 0x5810
cmpl $0x0, %eax
jne 0x1c4f2
movq 0x2430(%rsp), %rdi
movq 0x2430(%rsp), %rax
movq (%rax), %rax
movl 0x470(%rax), %edx
movq 0x2430(%rsp), %rax
movq (%rax), %rax
movq 0x460(%rax), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x1d4c0
jmp 0x1c4f4
movq 0x2430(%rsp), %rax
movq (%rax), %rax
movl 0x470(%rax), %esi
movq 0x2430(%rsp), %rax
movq (%rax), %rax
movq 0x460(%rax), %rdx
leaq 0x20(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edi
movl $0x2000, %r8d           # imm = 0x2000
callq 0x16e30
movl %eax, 0xc(%rsp)
cmpl $0x0, %eax
jle 0x1c555
movq 0x2430(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movslq 0xc(%rsp), %rdx
callq 0x16ed0
cmpl 0xc(%rsp), %eax
je 0x1c553
jmp 0x1c555
jmp 0x1c4f4
movq 0x2430(%rsp), %rax
movq (%rax), %rax
cmpl $0x0, 0x49c(%rax)
jne 0x1c598
movq 0x2430(%rsp), %rax
movq (%rax), %rdi
callq 0x1b8f0
movq 0x2430(%rsp), %rax
movq (%rax), %rdi
callq 0x56c0
movq 0x2430(%rsp), %rax
movq $0x0, (%rax)
addq $0x2438, %rsp           # imm = 0x2438
retq