// File: kztomita[P]http-dump/main.cc
// Function: main
int main(int argc, char *argv[]) {
  namespace asio = boost::asio;

  bool use_http2 = false;
  http_header h;
  http_header_list headers;

  if (argc < 2) {
    usage();
  }

  int opt_argc = argc;
  std::string url;
  if (argv[argc - 1][0] != '-') {
    url = argv[argc - 1];
    opt_argc--;
  }

  static struct option long_options[] = {
    {"http2",     no_argument,       0,  1 },
    {"keylog",    required_argument, 0,  2 },
    {0,           0,                 0,  0 },
  };
  while (true) {
    int opt = getopt_long(opt_argc, argv, "hH:kv",
                          long_options, NULL);
    if (opt == -1) {
      break;
    }
    switch (opt) {
    case 1:     // --http2
      use_http2 = true;
      break;
    case 2:     // --keylog
      g_keylog_file = optarg;
      break;
    case 'H':
      {
        auto h = create_http_header_from_header_line_or_null(optarg);
        if (h) {
          headers.emplace_back(std::move(h));
        }
      }
      break;
    case 'k':
      g_verify_cert = false;
      break;
    case 'v':
      g_verbose = true;
      break;
    case 'h':
    case '?':
      usage();
    }
  }

  try {
    url_components c = parse_url(url);

    uint16_t port = 0;
    if (c.scheme == "http") {
      port = 80;
    } else if (c.scheme == "https") {
      port = 443;
    } else {
      std::cerr << "Unsupported scheme." << std::endl;
      return 1;
    }
    if (c.port) {
      port = c.port.value();
    }

    boost::system::error_code error;
    asio::io_context context;
    asio::ip::tcp::resolver resolver(context);
    auto endpoints = resolver.resolve(asio::ip::tcp::v4(), c.host, "", error);
    if (error) {
      std::cerr << error.message() << std::endl;
      return 1;
    }
    boost::asio::ip::address remote_address(endpoints.begin()->endpoint().address());

    http_scheme scheme;
    if (c.scheme == "http") {
      scheme = http_scheme::http;
    } else if (c.scheme == "https") {
      scheme = http_scheme::https;
    } else {
      throw std::invalid_argument("unsupported scheme.");
    }

    std::unique_ptr<http_protocol> protocol;
    if (use_http2 && scheme == http_scheme::https) {
      protocol.reset(new httpv2);
    } else {
      protocol.reset(new httpv1);
    }
    http_response r = protocol->get(remote_address, port, scheme, c.host, c.path_and_query, headers);
    debug_dump(r);
    std::cout << r.stringify_payload() << std::endl;
  } catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x360, %rsp            # imm = 0x360
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x11(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x109e0
leaq -0x70(%rbp), %rdi
callq 0x10a10
cmpl $0x2, -0x8(%rbp)
jge 0xf913
xorl %eax, %eax
movl %eax, %edi
callq 0xf750
jmp 0xf900
jmp 0xf913
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1022e
movl -0x8(%rbp), %eax
movl %eax, -0x80(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0xd510
movq -0x10(%rbp), %rax
movl -0x8(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0xf978
movq -0x10(%rbp), %rax
movl -0x8(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
leaq -0xa0(%rbp), %rdi
callq 0xd5c0
jmp 0xf95c
movl -0x80(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0xf978
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x10222
jmp 0xf97a
jmp 0xf97c
movl -0x80(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x637ed(%rip), %rdx     # 0x73177
leaq 0x9df4f(%rip), %rcx     # 0xad8e0
xorl %eax, %eax
movl %eax, %r8d
callq 0xdde0
movl %eax, -0xa4(%rbp)
cmpl $-0x1, -0xa4(%rbp)
jne 0xf9af
jmp 0xfb5b
movl -0xa4(%rbp), %eax
movl %eax, -0x2dc(%rbp)
subl $0x1, %eax
je 0xfa23
jmp 0xf9c2
movl -0x2dc(%rbp), %eax
subl $0x2, %eax
je 0xfa2c
jmp 0xf9cf
movl -0x2dc(%rbp), %eax
subl $0x3f, %eax
je 0xfb49
jmp 0xf9e0
movl -0x2dc(%rbp), %eax
subl $0x48, %eax
je 0xfa42
jmp 0xf9ed
movl -0x2dc(%rbp), %eax
subl $0x68, %eax
je 0xfb49
jmp 0xf9fe
movl -0x2dc(%rbp), %eax
subl $0x6b, %eax
je 0xfb37
jmp 0xfa0f
movl -0x2dc(%rbp), %eax
subl $0x76, %eax
je 0xfb40
jmp 0xfb56
movb $0x1, -0x11(%rbp)
jmp 0xfb56
movq 0x9d505(%rip), %rax     # 0xacf38
movq (%rax), %rax
movq %rax, 0x9ebd3(%rip)     # 0xae610
jmp 0xfb56
movq 0x9d4ef(%rip), %rax     # 0xacf38
movq (%rax), %rax
movq %rax, -0x2f0(%rbp)
leaq -0xd1(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
callq 0xddb0
movq -0x2f0(%rbp), %rsi
movq -0x2e8(%rbp), %rdx
leaq -0xd0(%rbp), %rdi
callq 0x10a30
jmp 0xfa82
leaq -0xb0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x4d560
jmp 0xfa97
leaq -0xd0(%rbp), %rdi
callq 0xdac0
leaq -0xd1(%rbp), %rdi
callq 0xe180
leaq -0xb0(%rbp), %rdi
callq 0x10ae0
testb $0x1, %al
jne 0xfac1
jmp 0xfb29
leaq -0x70(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x10b10
jmp 0xfad3
jmp 0xfb29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xfafb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xdac0
leaq -0xd1(%rbp), %rdi
callq 0xe180
jmp 0x10222
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x10b60
jmp 0x10222
leaq -0xb0(%rbp), %rdi
callq 0x10b60
jmp 0xfb56
movb $0x0, 0x9de0a(%rip)     # 0xad948
jmp 0xfb56
movb $0x1, 0x9ead1(%rip)     # 0xae618
jmp 0xfb56
xorl %eax, %eax
movl %eax, %edi
callq 0xf750
jmp 0xfb54
jmp 0xfb56
jmp 0xf97a
leaq -0x140(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x247d0
jmp 0xfb70
movw $0x0, -0x142(%rbp)
leaq 0x635fd(%rip), %rsi     # 0x7317d
leaq -0x140(%rbp), %rdi
callq 0x10bd0
movb %al, -0x2f1(%rbp)
jmp 0xfb94
movb -0x2f1(%rbp), %al
testb $0x1, %al
jne 0xfba0
jmp 0xfbd0
movw $0x50, -0x142(%rbp)
jmp 0xfc4b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1015b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1014f
leaq 0x635ab(%rip), %rsi     # 0x73182
leaq -0x140(%rbp), %rdi
callq 0x10bd0
movb %al, -0x2f2(%rbp)
jmp 0xfbeb
movb -0x2f2(%rbp), %al
testb $0x1, %al
jne 0xfbf7
jmp 0xfc02
movw $0x1bb, -0x142(%rbp)    # imm = 0x1BB
jmp 0xfc49
movq 0x9d39f(%rip), %rdi     # 0xacfa8
leaq 0x63578(%rip), %rsi     # 0x73188
callq 0xd860
movq %rax, -0x300(%rbp)
jmp 0xfc1e
movq -0x300(%rbp), %rdi
movq 0x9d36c(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0xfc33
movl $0x1, -0x4(%rbp)
movl $0x1, -0x148(%rbp)
jmp 0x100cc
jmp 0xfc4b
leaq -0x140(%rbp), %rdi
addq $0x40, %rdi
callq 0x10c00
testb $0x1, %al
jne 0xfc61
jmp 0xfc86
leaq -0x100(%rbp), %rdi
callq 0x10c20
movq %rax, -0x308(%rbp)
jmp 0xfc76
movq -0x308(%rbp), %rax
movl (%rax), %eax
movw %ax, -0x142(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x10c60
leaq -0x168(%rbp), %rdi
callq 0x10ca0
jmp 0xfca0
xorl %eax, %eax
movl %eax, %edx
leaq -0x1b0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x10d50
jmp 0xfcb9
callq 0x10e30
movl %eax, -0x1cc(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xdf20
movq %rax, -0x1e0(%rbp)
movq %rdx, -0x1d8(%rbp)
leaq 0x657a4(%rip), %rsi     # 0x75489
leaq -0x1f0(%rbp), %rdi
callq 0x10e50
movq -0x1e0(%rbp), %rcx
movq -0x1d8(%rbp), %r8
movups -0x1f0(%rbp), %xmm0
movq %rsp, %rax
movups %xmm0, (%rax)
leaq -0x1c8(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
leaq -0x1cc(%rbp), %rdx
leaq -0x158(%rbp), %r9
callq 0x10da0
jmp 0xfd2f
leaq -0x158(%rbp), %rdi
callq 0x10ea0
testb $0x1, %al
jne 0xfd44
jmp 0xfdfc
leaq -0x210(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x10900
jmp 0xfd59
movq 0x9d248(%rip), %rdi     # 0xacfa8
leaq -0x210(%rbp), %rsi
callq 0xd480
movq %rax, -0x310(%rbp)
jmp 0xfd75
movq -0x310(%rbp), %rdi
movq 0x9d215(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0xfd8a
leaq -0x210(%rbp), %rdi
callq 0xdac0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x148(%rbp)
jmp 0x100a8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x10143
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x10137
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1012b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x210(%rbp), %rdi
callq 0xdac0
jmp 0x1012b
leaq -0x268(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x10ec0
jmp 0xfe11
leaq -0x268(%rbp), %rdi
callq 0x10f40
movq %rax, -0x318(%rbp)
jmp 0xfe26
movq -0x318(%rbp), %rsi
leaq -0x24c(%rbp), %rdi
callq 0x10f60
jmp 0xfe3b
leaq -0x230(%rbp), %rdi
leaq -0x24c(%rbp), %rsi
callq 0x10f90
leaq -0x268(%rbp), %rdi
callq 0x10fc0
leaq 0x6331c(%rip), %rsi     # 0x7317d
leaq -0x140(%rbp), %rdi
callq 0x10bd0
movb %al, -0x319(%rbp)
jmp 0xfe75
movb -0x319(%rbp), %al
testb $0x1, %al
jne 0xfe81
jmp 0xfead
movl $0x0, -0x26c(%rbp)
jmp 0xff43
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x10fc0
jmp 0x1012b
leaq 0x632ce(%rip), %rsi     # 0x73182
leaq -0x140(%rbp), %rdi
callq 0x10bd0
movb %al, -0x31a(%rbp)
jmp 0xfec8
movb -0x31a(%rbp), %al
testb $0x1, %al
jne 0xfed4
jmp 0xfee0
movl $0x1, -0x26c(%rbp)
jmp 0xff41
movl $0x10, %edi
callq 0xd580
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x328(%rbp)
leaq 0x6329e(%rip), %rsi     # 0x7319c
callq 0xd2e0
jmp 0xff05
movq -0x328(%rbp), %rdi
movq 0x9d015(%rip), %rsi     # 0xacf28
movq 0x9d006(%rip), %rdx     # 0xacf20
callq 0xd970
jmp 0x10251
movq -0x328(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
callq 0xdc70
jmp 0x1012b
jmp 0xff43
leaq -0x278(%rbp), %rdi
callq 0x10fe0
testb $0x1, -0x11(%rbp)
je 0xffa3
cmpl $0x1, -0x26c(%rbp)
jne 0xffa3
movl $0x8, %edi
callq 0xd240
movq %rax, -0x330(%rbp)
jmp 0xff71
movq -0x330(%rbp), %rdi
callq 0x11040
movq -0x330(%rbp), %rsi
leaq -0x278(%rbp), %rdi
callq 0x11010
jmp 0xffd5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1011f
movl $0x8, %edi
callq 0xd240
movq %rax, -0x338(%rbp)
jmp 0xffb6
movq -0x338(%rbp), %rdi
callq 0x11080
movq -0x338(%rbp), %rsi
leaq -0x278(%rbp), %rdi
callq 0x11010
leaq -0x278(%rbp), %rdi
callq 0x110c0
movq %rax, %rsi
movzwl -0x142(%rbp), %ecx
movl -0x26c(%rbp), %r8d
leaq -0x120(%rbp), %r9
leaq -0xf8(%rbp), %rdi
movq (%rsi), %rax
movq (%rax), %rax
movq %rsp, %rdx
leaq -0x70(%rbp), %r10
movq %r10, 0x8(%rdx)
movq %rdi, (%rdx)
leaq -0x2b0(%rbp), %rdi
leaq -0x230(%rbp), %rdx
callq *%rax
jmp 0x10026
leaq -0x2b0(%rbp), %rdi
callq 0x110e0
jmp 0x10034
leaq -0x2d0(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x4e4f0
jmp 0x10049
movq 0x9cef0(%rip), %rdi     # 0xacf40
leaq -0x2d0(%rbp), %rsi
callq 0xd480
movq %rax, -0x340(%rbp)
jmp 0x10065
movq -0x340(%rbp), %rdi
movq 0x9cf25(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x1007a
leaq -0x2d0(%rbp), %rdi
callq 0xdac0
leaq -0x2b0(%rbp), %rdi
callq 0x11110
leaq -0x278(%rbp), %rdi
callq 0x11140
movl $0x0, -0x148(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x111b0
leaq -0x1b0(%rbp), %rdi
callq 0x111d0
leaq -0x168(%rbp), %rdi
callq 0x11200
leaq -0x140(%rbp), %rdi
callq 0x11220
movl -0x148(%rbp), %eax
testl %eax, %eax
jne 0x101f8
jmp 0x100e8
jmp 0x101e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x10113
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0xdac0
leaq -0x2b0(%rbp), %rdi
callq 0x11110
leaq -0x278(%rbp), %rdi
callq 0x11140
leaq -0x1c8(%rbp), %rdi
callq 0x111b0
leaq -0x1b0(%rbp), %rdi
callq 0x111d0
leaq -0x168(%rbp), %rdi
callq 0x11200
leaq -0x140(%rbp), %rdi
callq 0x11220
movl -0x7c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x10222
movq -0x78(%rbp), %rdi
callq 0xd0d0
movq %rax, -0x2d8(%rbp)
movq -0x2d8(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0x9ce13(%rip), %rdi     # 0xacfa8
callq 0xd860
movq %rax, -0x348(%rbp)
jmp 0x101a3
movq -0x348(%rbp), %rdi
movq 0x9cde7(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x101b8
movl $0x1, -0x4(%rbp)
movl $0x1, -0x148(%rbp)
callq 0xdae0
jmp 0x101e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
callq 0xdae0
jmp 0x101e5
jmp 0x101f8
jmp 0x10222
movl $0x0, -0x4(%rbp)
movl $0x1, -0x148(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0xdac0
leaq -0x70(%rbp), %rdi
callq 0x11260
leaq -0x58(%rbp), %rdi
callq 0x11280
movl -0x4(%rbp), %eax
addq $0x360, %rsp            # imm = 0x360
popq %rbp
retq
leaq -0xa0(%rbp), %rdi
callq 0xdac0
leaq -0x70(%rbp), %rdi
callq 0x11260
leaq -0x58(%rbp), %rdi
callq 0x11280
movq -0x78(%rbp), %rdi
callq 0xd990
movq %rax, %rdi
callq 0x10770
nopw %cs:(%rax,%rax)