// File: /workspace/github_cpp_makefile_star2_O2/nurseiit[P]cpp-server/client.cpp
// Function: main
int main(int argc, char *argv[]) {
  try {
    if (argc != 3) {
      std::cout << "Usage: " << argv[0] << " <url> <port>\n";
      std::cout << "Examples:\n";
      std::cout << "  " << argv[0] << " www.example.com 80\n";
      std::cout << "  " << argv[0] << " www.google.com/test.html 80\n";
      return EXIT_FAILURE;
    }

    std::string hostname = hostname_from_url(argv[1]);
    std::string path = path_from_url(argv[1]);
    std::string port = argv[2];

    asio::io_context io_context;

    // Get endpoints for server name
    tcp::resolver resolver(io_context);
    tcp::resolver::results_type endpoints = resolver.resolve(hostname, port);

    // Find first successful endpoint
    tcp::socket socket(io_context);
    asio::connect(socket, endpoints);

    // Set bare minimum request headers for GET to work
    // https://stackoverflow.com/questions/6686261/what-at-the-bare-minimum-is-required-for-an-http-request
    asio::streambuf request;
    std::ostream request_stream(&request);
    request_stream << "GET " << path << " HTTP/1.0\r\n";
    request_stream << "Host: " << hostname << "\r\n";
    // Set "Connection: close" so server ends response with EOF
    request_stream << "Connection: close\r\n\r\n";

    // Send request
    asio::write(socket, request);

    // Read response status line
    asio::streambuf response;
    asio::read_until(socket, response, "\r\n");

    // Check response
    std::istream response_stream(&response);
    std::string http_version;
    response_stream >> http_version;
    unsigned int status_code;
    response_stream >> status_code;
    std::string status_message;
    std::getline(response_stream, status_message);

    if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
      std::cout << "Invalid response\n";
      return EXIT_FAILURE;
    }

    std::cout << "STATUS CODE: " << status_code << std::endl;

    // Read & Print to console response headers
    asio::read_until(socket, response, "\r\n\r\n");

    std::string header;
    while (std::getline(response_stream, header) && header != "\r")
      std::cout << header << "\n";
    std::cout << "\n";

    // Read and print response till EOF
    if (response.size() > 0)
      std::cout << &response;

    asio::error_code error;
    while (asio::read(socket, response, asio::transfer_at_least(1), error))
      std::cout << &response;

    // If read throws EOF, it's expected
    if (error != asio::error::eof)
      throw asio::system_error(error);
  } catch (std::exception &e) {
    std::cout << "ERROR: " << e.what() << "\n";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x448, %rsp            # imm = 0x448
movq %rsi, %r14
pushq $0x1
popq %rbx
cmpl $0x3, %edi
jne 0x5c68
movq 0x8(%r14), %rsi
leaq 0x1c0(%rsp), %rdi
leaq 0x338(%rsp), %rdx
callq 0x5170
leaq 0xb8(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0x5872
leaq 0x1c0(%rsp), %rdi
callq 0x5190
movq 0x8(%r14), %rsi
leaq 0x1c0(%rsp), %rdi
leaq 0x338(%rsp), %rdx
callq 0x5170
leaq 0x118(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0x581c
leaq 0x1c0(%rsp), %rdi
callq 0x5190
movq 0x10(%r14), %rsi
leaq 0xf8(%rsp), %rdi
leaq 0x1c0(%rsp), %rdx
callq 0x5170
leaq 0x40(%rsp), %rdi
callq 0x61d2
leaq 0x198(%rsp), %rdi
leaq 0x40(%rsp), %rsi
xorl %edx, %edx
callq 0x7f00
leaq 0xa0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
leaq 0xf8(%rsp), %rcx
callq 0x6232
leaq 0x70(%rsp), %rdi
leaq 0x40(%rsp), %rsi
xorl %edx, %edx
callq 0x94fc
leaq 0x1c0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
xorl %ecx, %ecx
callq 0x6243
leaq 0x2d8(%rsp), %rdi
pushq $-0x1
popq %rsi
leaq 0x1c0(%rsp), %rdx
callq 0x629e
leaq 0x338(%rsp), %rdi
leaq 0x2d8(%rsp), %rsi
callq 0x5160
leaq 0x66c7(%rip), %rsi      # 0xc0d4
leaq 0x338(%rsp), %rdi
callq 0x5330
leaq 0x118(%rsp), %rsi
movq %rax, %rdi
callq 0x5300
leaq 0x66a8(%rip), %rsi      # 0xc0d9
movq %rax, %rdi
callq 0x5330
leaq 0x66a5(%rip), %rsi      # 0xc0e5
leaq 0x338(%rsp), %rdi
callq 0x5330
leaq 0xb8(%rsp), %rsi
movq %rax, %rdi
callq 0x5300
leaq 0x669b(%rip), %rsi      # 0xc0ff
movq %rax, %rdi
callq 0x5330
leaq 0x6679(%rip), %rsi      # 0xc0ec
leaq 0x338(%rsp), %rdi
callq 0x5330
leaq 0x70(%rsp), %rdi
leaq 0x2d8(%rsp), %rsi
callq 0x6339
leaq 0x138(%rsp), %rdi
pushq $-0x1
popq %rsi
leaq 0x1c0(%rsp), %rdx
callq 0x629e
leaq 0x664e(%rip), %rsi      # 0xc0ff
leaq 0x1c0(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x5170
leaq 0x70(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x1c0(%rsp), %rdx
callq 0x634c
leaq 0x1c0(%rsp), %rdi
callq 0x5190
leaq 0x1c0(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x5590
leaq 0x60(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x1c0(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x53d0
leaq 0x1c0(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0x5520
leaq 0xe8(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x1c0(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x5070
movq 0x1c0(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x1e0(%rsp,%rax)
jne 0x5bad
leaq 0x20(%rsp), %rdi
leaq 0x50(%rsp), %rsi
pushq $0x5
popq %rcx
xorl %edx, %edx
callq 0x5350
leaq 0x6574(%rip), %rsi      # 0xc102
leaq 0x20(%rsp), %rdi
callq 0x635f
movl %eax, %ebp
leaq 0x20(%rsp), %rdi
callq 0x5190
testb %bpl, %bpl
je 0x5d16
movq 0xe404(%rip), %rdi      # 0x13fb8
leaq 0x654d(%rip), %rsi      # 0xc108
callq 0x5330
pushq $0x1
popq %rbx
leaq 0xd8(%rsp), %rdi
callq 0x5190
leaq 0x50(%rsp), %rdi
callq 0x5190
leaq 0x1c0(%rsp), %rdi
callq 0x5500
leaq 0x138(%rsp), %rdi
callq 0x63ee
leaq 0x340(%rsp), %rdi
callq 0x5120
leaq 0x2d8(%rsp), %rdi
callq 0x63ee
leaq 0x70(%rsp), %rdi
callq 0x9f34
leaq 0xa8(%rsp), %rdi
callq 0x7df8
leaq 0x198(%rsp), %rdi
callq 0x8b3e
leaq 0x40(%rsp), %rdi
callq 0x640e
leaq 0xf8(%rsp), %rdi
callq 0x5190
leaq 0x118(%rsp), %rdi
callq 0x5190
leaq 0xb8(%rsp), %rdi
callq 0x5190
jmp 0x5d02
movq 0xe349(%rip), %rdi      # 0x13fb8
leaq 0x6406(%rip), %rsi      # 0xc07c
callq 0x5330
movq (%r14), %rsi
movq %rax, %rdi
callq 0x5330
leaq 0x63f7(%rip), %rsi      # 0xc084
movq %rax, %rdi
callq 0x5330
movq 0xe31c(%rip), %rdi      # 0x13fb8
leaq 0x63f0(%rip), %rsi      # 0xc093
callq 0x5330
movq 0xe309(%rip), %rdi      # 0x13fb8
leaq 0x63e8(%rip), %rsi      # 0xc09e
callq 0x5330
movq (%r14), %rsi
movq %rax, %rdi
callq 0x5330
leaq 0x63d4(%rip), %rsi      # 0xc0a1
movq %rax, %rdi
callq 0x5330
movq 0xe2dc(%rip), %rdi      # 0x13fb8
leaq 0x63bb(%rip), %rsi      # 0xc09e
callq 0x5330
movq (%r14), %rsi
movq %rax, %rdi
callq 0x5330
leaq 0x63bc(%rip), %rsi      # 0xc0b6
movq %rax, %rdi
callq 0x5330
movl %ebx, %eax
addq $0x448, %rsp            # imm = 0x448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xe29b(%rip), %rdi      # 0x13fb8
leaq 0x63f6(%rip), %rsi      # 0xc11a
callq 0x5330
movl 0xc(%rsp), %esi
movq %rax, %rdi
callq 0x5250
movq %rax, %rdi
callq 0x51b0
leaq 0x63b9(%rip), %rsi      # 0xc0fd
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x5170
leaq 0x70(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x634c
leaq 0x20(%rsp), %r14
movq %r14, %rdi
callq 0x5190
leaq 0x30(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x1c0(%rsp), %r15
leaq 0x6391(%rip), %r12      # 0xc128
movq 0xe21a(%rip), %r13      # 0x13fb8
leaq 0x635b(%rip), %rbp      # 0xc100
movq %r15, %rdi
movq %r14, %rsi
callq 0x5070
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x5de5
movq %r14, %rdi
movq %r12, %rsi
callq 0x635f
testb %al, %al
je 0x5de5
movq %r13, %rdi
movq %r14, %rsi
callq 0x5300
movq %rax, %rdi
movq %rbp, %rsi
callq 0x5330
jmp 0x5da5
movq 0xe1cc(%rip), %rdi      # 0x13fb8
leaq 0x630d(%rip), %rsi      # 0xc100
callq 0x5330
movq 0x160(%rsp), %rax
cmpq 0x148(%rsp), %rax
je 0x5e1e
movq 0xe1a7(%rip), %rdi      # 0x13fb8
leaq 0x138(%rsp), %rsi
callq 0x5080
leaq 0x10(%rsp), %r14
andl $0x0, (%r14)
callq 0x5210
movq %rax, 0x8(%r14)
leaq 0x70(%rsp), %r15
leaq 0x138(%rsp), %r12
pushq $0x1
popq %r13
movq 0xe170(%rip), %rbp      # 0x13fb8
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %r14, %rcx
callq 0x6369
testq %rax, %rax
je 0x5e6b
movq %rbp, %rdi
movq %r12, %rsi
callq 0x5080
jmp 0x5e48
callq 0x6182
cmpq %rax, 0x18(%rsp)
jne 0x5e8f
cmpl $0x2, 0x10(%rsp)
jne 0x5e8f
leaq 0x20(%rsp), %rdi
callq 0x5190
xorl %ebx, %ebx
jmp 0x5bc3
pushq $0x20
popq %rdi
callq 0x51c0
movq %rax, %r12
movl 0x10(%rsp), %esi
movq 0x18(%rsp), %rdx
movq %rax, %rdi
callq 0x637e
movq 0xe0ce(%rip), %rsi      # 0x13f80
movq 0xe0e7(%rip), %rdx      # 0x13fa0
movq %r12, %rdi
callq 0x5510
jmp 0x5fc8
movq %rdx, %r14
movq %rax, %r15
movq %r12, %rdi
callq 0x5270
jmp 0x5fce
jmp 0x5fc8
jmp 0x5fab
jmp 0x5fc8
jmp 0x5fc8
jmp 0x5fab
jmp 0x5ef4
movq %rdx, %r14
movq %rax, %r15
jmp 0x5fe5
jmp 0x5f19
movq %rdx, %r14
movq %rax, %r15
leaq 0x1c0(%rsp), %rdi
callq 0x5190
jmp 0x5ffc
movq %rdx, %r14
movq %rax, %r15
jmp 0x5ffc
jmp 0x5fb3
movq %rdx, %r14
movq %rax, %r15
jmp 0x6016
jmp 0x5f36
movq %rdx, %r14
movq %rax, %r15
jmp 0x6023
movq %rdx, %r14
movq %rax, %r15
jmp 0x602d
movq %rdx, %r14
movq %rax, %r15
jmp 0x603a
movq %rdx, %r14
movq %rax, %r15
jmp 0x6047
movq %rdx, %r14
movq %rax, %r15
jmp 0x6051
movq %rdx, %r14
movq %rax, %r15
jmp 0x605e
movq %rdx, %r14
movq %rax, %r15
leaq 0x1c0(%rsp), %rdi
jmp 0x6066
movq %rdx, %r14
movq %rax, %r15
jmp 0x606b
movq %rdx, %r14
movq %rax, %r15
leaq 0x1c0(%rsp), %rdi
jmp 0x6073
jmp 0x5fbb
movq %rdx, %r14
movq %rax, %r15
jmp 0x5fd8
movq %rdx, %r14
movq %rax, %r15
jmp 0x6009
movq %rdx, %r14
movq %rax, %r15
jmp 0x6078
jmp 0x5fc8
movq %rdx, %r14
movq %rax, %r15
leaq 0x20(%rsp), %rdi
callq 0x5190
leaq 0xd8(%rsp), %rdi
callq 0x5190
leaq 0x50(%rsp), %rdi
callq 0x5190
leaq 0x1c0(%rsp), %rdi
callq 0x5500
leaq 0x138(%rsp), %rdi
callq 0x63ee
leaq 0x340(%rsp), %rdi
callq 0x5120
leaq 0x2d8(%rsp), %rdi
callq 0x63ee
leaq 0x70(%rsp), %rdi
callq 0x9f34
leaq 0xa8(%rsp), %rdi
callq 0x7df8
leaq 0x198(%rsp), %rdi
callq 0x8b3e
leaq 0x40(%rsp), %rdi
callq 0x640e
leaq 0xf8(%rsp), %rdi
callq 0x5190
leaq 0x118(%rsp), %rdi
callq 0x5190
leaq 0xb8(%rsp), %rdi
callq 0x5190
cmpl $0x1, %r14d
jne 0x60d4
movq %r15, %rdi
callq 0x5180
movq %rax, %r14
movq 0xdf28(%rip), %rdi      # 0x13fb8
leaq 0x6093(%rip), %rsi      # 0xc12a
callq 0x5330
movq %rax, %r15
movq (%r14), %rax
movq %r14, %rdi
callq *0x10(%rax)
movq %r15, %rdi
movq %rax, %rsi
callq 0x5330
leaq 0x6046(%rip), %rsi      # 0xc100
movq %rax, %rdi
callq 0x5330
callq 0x54e0
jmp 0x5d02
movq %rax, %r15
callq 0x54e0
movq %r15, %rdi
callq 0x5530
movq %rax, %rdi
callq 0x6441