// File: nilnilnil[P]autocomplete/deps/mongoose/mongoose.c
// Function: parse_auth_header
static int parse_auth_header(struct mg_connection *conn, char *buf,
                             size_t buf_size, struct ah *ah) {
  char *name, *value, *s;
  const char *auth_header;

  if ((auth_header = mg_get_header(conn, "Authorization")) == NULL ||
      mg_strncasecmp(auth_header, "Digest ", 7) != 0) {
    return 0;
  }

  // Make modifiable copy of the auth header
  (void) mg_strlcpy(buf, auth_header + 7, buf_size);

  s = buf;
  (void) memset(ah, 0, sizeof(*ah));

  // Parse authorization header
  for (;;) {
    // Gobble initial spaces
    while (isspace(* (unsigned char *) s)) {
      s++;
    }
    name = skip_quoted(&s, "=", " ", 0);
    /* Value is either quote-delimited, or ends at first comma or space. */
    if (s[0] == '\"') {
      s++;
      value = skip_quoted(&s, "\"", " ", '\\');
      if (s[0] == ',') {
        s++;
      }
    } else {
      value = skip_quoted(&s, ", ", " ", 0);  // IE uses commas, FF uses spaces
    }
    if (*name == '\0') {
      break;
    }

    if (!strcmp(name, "username")) {
      ah->user = value;
    } else if (!strcmp(name, "cnonce")) {
      ah->cnonce = value;
    } else if (!strcmp(name, "response")) {
      ah->response = value;
    } else if (!strcmp(name, "uri")) {
      ah->uri = value;
    } else if (!strcmp(name, "qop")) {
      ah->qop = value;
    } else if (!strcmp(name, "nc")) {
      ah->nc = value;
    } else if (!strcmp(name, "nonce")) {
      ah->nonce = value;
    }
  }

  // CGI needs it as REMOTE_USER
  if (ah->user != NULL) {
    conn->request_info.remote_user = mg_strdup(ah->user);
  } else {
    return 0;
  }

  return 1;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x38(%rsp)
movq %rsi, 0x30(%rsp)
movq %rdx, 0x28(%rsp)
movq %rcx, 0x20(%rsp)
movq 0x38(%rsp), %rdi
leaq 0x3db3(%rip), %rsi      # 0x231b7
callq 0x16b70
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x1f42d
movq (%rsp), %rdi
leaq 0x3da7(%rip), %rsi      # 0x231c5
movl $0x7, %edx
callq 0x17390
cmpl $0x0, %eax
je 0x1f43a
movl $0x0, 0x44(%rsp)
jmp 0x1f6a2
movq 0x30(%rsp), %rdi
movq (%rsp), %rsi
addq $0x7, %rsi
movq 0x28(%rsp), %rdx
callq 0x17840
movq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x52a0
jmp 0x1f46e
callq 0x5610
movq (%rax), %rax
movq 0x8(%rsp), %rcx
movzbl (%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x2000, %eax           # imm = 0x2000
cmpl $0x0, %eax
je 0x1f49f
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0x1f46e
leaq 0x8(%rsp), %rdi
leaq 0x3d22(%rip), %rsi      # 0x231cd
leaq 0x2dfa(%rip), %rdx      # 0x222ac
xorl %ecx, %ecx
callq 0x1cf70
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x1f518
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
leaq 0x8(%rsp), %rdi
leaq 0x2da1(%rip), %rsi      # 0x22286
leaq 0x2dc0(%rip), %rdx      # 0x222ac
movl $0x5c, %ecx
callq 0x1cf70
movq %rax, 0x10(%rsp)
movq 0x8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2c, %eax
jne 0x1f516
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0x1f537
leaq 0x8(%rsp), %rdi
leaq 0x2d87(%rip), %rsi      # 0x222ab
leaq 0x2d81(%rip), %rdx      # 0x222ac
xorl %ecx, %ecx
callq 0x1cf70
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x1f549
jmp 0x1f66a
movq 0x18(%rsp), %rdi
leaq 0x3c7a(%rip), %rsi      # 0x231cf
callq 0x5810
cmpl $0x0, %eax
jne 0x1f571
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, (%rax)
jmp 0x1f665
movq 0x18(%rsp), %rdi
leaq 0x3c5b(%rip), %rsi      # 0x231d8
callq 0x5810
cmpl $0x0, %eax
jne 0x1f59a
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x10(%rax)
jmp 0x1f663
movq 0x18(%rsp), %rdi
leaq 0x3c39(%rip), %rsi      # 0x231df
callq 0x5810
cmpl $0x0, %eax
jne 0x1f5c3
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x18(%rax)
jmp 0x1f661
movq 0x18(%rsp), %rdi
leaq 0x328a(%rip), %rsi      # 0x22859
callq 0x5810
cmpl $0x0, %eax
jne 0x1f5e9
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x8(%rax)
jmp 0x1f65f
movq 0x18(%rsp), %rdi
leaq 0x3bf3(%rip), %rsi      # 0x231e8
callq 0x5810
cmpl $0x0, %eax
jne 0x1f60f
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1f65d
movq 0x18(%rsp), %rdi
leaq 0x3bd1(%rip), %rsi      # 0x231ec
callq 0x5810
cmpl $0x0, %eax
jne 0x1f635
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1f65b
movq 0x18(%rsp), %rdi
leaq 0x3b98(%rip), %rsi      # 0x231d9
callq 0x5810
cmpl $0x0, %eax
jne 0x1f659
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x30(%rax)
jmp 0x1f65b
jmp 0x1f65d
jmp 0x1f65f
jmp 0x1f661
jmp 0x1f663
jmp 0x1f665
jmp 0x1f46c
movq 0x20(%rsp), %rax
cmpq $0x0, (%rax)
je 0x1f690
movq 0x20(%rsp), %rax
movq (%rax), %rdi
callq 0x18770
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x30(%rax)
jmp 0x1f69a
movl $0x0, 0x44(%rsp)
jmp 0x1f6a2
movl $0x1, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nopl (%rax,%rax)