// File: kztomita[P]http-dump/./socket.h
// Function: http_response read_response<sync_stream_wrapper>(sync_stream_wrapper&)
http_response read_response(SyncReadStream& socket) {
  namespace asio = boost::asio;

  std::string line;
  asio::streambuf receive_buffer;

  http_response r;

  // Status Line読み込み
  read_line(socket, receive_buffer, line);
  auto elements = string_util::split(line, " ");
  r.code_ = std::atoi(elements[1].c_str());

  // ヘッダー読み込み
  std::optional<std::string> transfer_encoding;
  std::optional<std::size_t> content_length;

  while (true) {
    if (!read_line(socket, receive_buffer, line)) {
      break;
    }
    if (line.size() == 0) {
      // ヘッダー終了
      break;
    }
    auto h = create_http_header_from_header_line(line);

    if (string_util::tolower(h->key) == "transfer-encoding") {
      transfer_encoding = h->value;
    } else if (string_util::tolower(h->key) == "content-length") {
      content_length = std::atoi(h->value.c_str());
    }

    r.headers_.push_back(std::move(h));
  }

  // payload読み込み

  if (!transfer_encoding ||
      transfer_encoding == "identity") {
    if (!content_length) {
      throw std::runtime_error("Content-Length not found.");
    }
    std::size_t length = content_length.value();

    fill_streambuf(socket, receive_buffer, length);
    const char* data = asio::buffer_cast<const char*>(receive_buffer.data());
    http_response::payload_type payload(data, data + length);
    receive_buffer.consume(length);

    using std::swap;
    swap(r.payload_, payload);
  } else if (transfer_encoding == "chunked") {
    http_response::payload_type payload;
    std::string line;
    while (read_line(socket, receive_buffer, line)) {
      if (line.size() == 0) {
        break;
      }
      std::size_t pos;
      std::size_t chunk_size = std::stoi(line.c_str(), &pos, 16);
      if (pos != line.size()) {
        throw std::runtime_error("Can't parse chunk size.");
      }
      if (chunk_size == 0) {
        // \r\n読み捨て
        std::string l;
        read_line(socket, receive_buffer, l);
        break;
      }

      fill_streambuf(socket, receive_buffer, chunk_size);
      const char* data = asio::buffer_cast<const char*>(receive_buffer.data());
      payload.resize(payload.size() + chunk_size);
      std::copy(data, data + chunk_size, payload.end() - chunk_size);
      receive_buffer.consume(chunk_size);

      // \r\n読み捨て
      fill_streambuf(socket, receive_buffer, 2);
      receive_buffer.consume(2);
    }

    using std::swap;
    swap(r.payload_, payload);
  } else {
    std::ostringstream msg;
    msg << "Unsupported Transfer-Encoding type ("
        << transfer_encoding.value()
        << ").";
    throw std::runtime_error(msg.str());
  }

  return r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movq %rdi, -0x408(%rbp)
movq %rdi, %rax
movq %rax, -0x400(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xd510
callq 0x16fc0
movq %rax, -0x3f8(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x3f0(%rbp)
callq 0xddb0
movq -0x3f8(%rbp), %rsi
movq -0x3f0(%rbp), %rdx
leaq -0x90(%rbp), %rdi
callq 0x52b20
jmp 0x4efe8
leaq -0x91(%rbp), %rdi
callq 0xe180
movq -0x408(%rbp), %rdi
movb $0x0, -0xa5(%rbp)
callq 0x52cd0
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x52d00
jmp 0x4f01d
leaq 0x2687e(%rip), %rdx     # 0x758a2
leaq -0xc0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x52f00
jmp 0x4f036
leaq -0xc0(%rbp), %rdi
movl $0x1, %esi
callq 0x53160
movq %rax, %rdi
callq 0xd1a0
movq %rax, %rdi
callq 0xd4e0
movl %eax, %ecx
movq -0x408(%rbp), %rax
movl %ecx, (%rax)
leaq -0xe8(%rbp), %rdi
callq 0x53180
leaq -0xf8(%rbp), %rdi
callq 0x531a0
jmp 0x4f07c
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x52d00
movb %al, -0x409(%rbp)
jmp 0x4f098
movb -0x409(%rbp), %al
testb $0x1, %al
jne 0x4f0fa
jmp 0x4f0a4
jmp 0x4f2b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x91(%rbp), %rdi
callq 0xe180
jmp 0x4fa8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4fa73
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4fa28
leaq -0x30(%rbp), %rdi
callq 0xd440
cmpq $0x0, %rax
jne 0x4f10e
jmp 0x4f2b8
leaq -0x100(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4d920
jmp 0x4f120
leaq -0x100(%rbp), %rdi
callq 0x4ee20
movq %rax, %rsi
leaq -0x120(%rbp), %rdi
callq 0x531c0
jmp 0x4f13d
leaq 0x26b0f(%rip), %rsi     # 0x75c53
leaq -0x120(%rbp), %rdi
callq 0x10bd0
movb %al, -0x40a(%rbp)
jmp 0x4f158
leaq -0x120(%rbp), %rdi
callq 0xdac0
movb -0x40a(%rbp), %al
testb $0x1, %al
jne 0x4f170
jmp 0x4f1d0
leaq -0x100(%rbp), %rdi
callq 0x4ee20
movq %rax, %rsi
addq $0x20, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x53280
jmp 0x4f191
jmp 0x4f27d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4f2a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x120(%rbp), %rdi
callq 0xdac0
jmp 0x4f2a7
leaq -0x100(%rbp), %rdi
callq 0x4ee20
movq %rax, %rsi
leaq -0x140(%rbp), %rdi
callq 0x531c0
jmp 0x4f1ed
leaq 0x268f9(%rip), %rsi     # 0x75aed
leaq -0x140(%rbp), %rdi
callq 0x10bd0
movb %al, -0x40b(%rbp)
jmp 0x4f208
leaq -0x140(%rbp), %rdi
callq 0xdac0
movb -0x40b(%rbp), %al
testb $0x1, %al
jne 0x4f220
jmp 0x4f27b
leaq -0x100(%rbp), %rdi
callq 0x4ee20
movq %rax, %rdi
addq $0x20, %rdi
callq 0xd1a0
movq %rax, %rdi
callq 0xd4e0
movl %eax, -0x144(%rbp)
leaq -0xf8(%rbp), %rdi
leaq -0x144(%rbp), %rsi
callq 0x532e0
jmp 0x4f27b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x140(%rbp), %rdi
callq 0xdac0
jmp 0x4f2a7
jmp 0x4f27d
movq -0x408(%rbp), %rdi
addq $0x8, %rdi
leaq -0x100(%rbp), %rsi
callq 0x53340
jmp 0x4f296
leaq -0x100(%rbp), %rdi
callq 0x10b60
jmp 0x4f07a
leaq -0x100(%rbp), %rdi
callq 0x10b60
jmp 0x4fa28
leaq -0xe8(%rbp), %rdi
callq 0x53370
testb $0x1, %al
jne 0x4f2ca
jmp 0x4f2f4
leaq 0x25e50(%rip), %rsi     # 0x75121
leaq -0xe8(%rbp), %rdi
callq 0x53390
movb %al, -0x40c(%rbp)
jmp 0x4f2e5
movb -0x40c(%rbp), %al
testb $0x1, %al
jne 0x4f2f4
jmp 0x4f4bb
leaq -0xf8(%rbp), %rdi
callq 0x533e0
testb $0x1, %al
jne 0x4f36b
movl $0x10, %edi
callq 0xd580
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x418(%rbp)
leaq 0x25e08(%rip), %rsi     # 0x7512a
callq 0xd3b0
jmp 0x4f329
movq -0x418(%rbp), %rdi
movq 0x5dc59(%rip), %rsi     # 0xacf90
movq 0x5dc22(%rip), %rdx     # 0xacf60
callq 0xd970
jmp 0x4faa0
movq -0x418(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
callq 0xdc70
jmp 0x4fa28
leaq -0xf8(%rbp), %rdi
callq 0x53400
movq %rax, -0x420(%rbp)
jmp 0x4f380
movq -0x420(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x150(%rbp)
movq -0x10(%rbp), %rdi
movq -0x150(%rbp), %rdx
leaq -0x90(%rbp), %rsi
callq 0x53440
jmp 0x4f3aa
leaq -0x90(%rbp), %rdi
callq 0x534d0
movq %rax, -0x168(%rbp)
movq %rdx, -0x160(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x534b0
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rax
movq %rax, -0x438(%rbp)
movq -0x150(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x430(%rbp)
leaq -0x181(%rbp), %rdi
movq %rdi, -0x428(%rbp)
callq 0x53550
movq -0x438(%rbp), %rsi
movq -0x430(%rbp), %rdx
movq -0x428(%rbp), %rcx
leaq -0x180(%rbp), %rdi
callq 0x53570
jmp 0x4f42c
leaq -0x181(%rbp), %rdi
callq 0x18d00
movq -0x150(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x535f0
jmp 0x4f44d
movq -0x408(%rbp), %rdi
addq $0x20, %rdi
leaq -0x180(%rbp), %rsi
callq 0x536d0
leaq -0x180(%rbp), %rdi
callq 0x18ac0
jmp 0x4f9fe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x181(%rbp), %rdi
callq 0x18d00
jmp 0x4fa28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x18ac0
jmp 0x4fa28
leaq 0x25c82(%rip), %rsi     # 0x75144
leaq -0xe8(%rbp), %rdi
callq 0x53700
movb %al, -0x439(%rbp)
jmp 0x4f4d6
movb -0x439(%rbp), %al
testb $0x1, %al
jne 0x4f4e5
jmp 0x4f8b7
leaq -0x1a0(%rbp), %rdi
callq 0x53750
leaq -0x1c0(%rbp), %rdi
callq 0xd510
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x1c0(%rbp), %rdx
callq 0x52d00
movb %al, -0x43a(%rbp)
jmp 0x4f51c
movb -0x43a(%rbp), %al
testb $0x1, %al
jne 0x4f52b
jmp 0x4f866
leaq -0x1c0(%rbp), %rdi
callq 0xd440
cmpq $0x0, %rax
jne 0x4f559
jmp 0x4f866
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4f89a
leaq -0x1c0(%rbp), %rdi
callq 0xd1a0
movq %rax, -0x450(%rbp)
leaq -0x1f1(%rbp), %rdi
movq %rdi, -0x448(%rbp)
callq 0xddb0
movq -0x450(%rbp), %rsi
movq -0x448(%rbp), %rdx
leaq -0x1f0(%rbp), %rdi
callq 0x10a30
jmp 0x4f59b
leaq -0x1f0(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
movl $0x10, %edx
callq 0x24e50
movl %eax, -0x454(%rbp)
jmp 0x4f5bb
movl -0x454(%rbp), %eax
cltq
movq %rax, -0x468(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0xdac0
leaq -0x1f1(%rbp), %rdi
callq 0xe180
movq -0x468(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x1c8(%rbp), %rax
movq %rax, -0x460(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0xd440
movq %rax, %rcx
movq -0x460(%rbp), %rax
cmpq %rcx, %rax
je 0x4f6c7
movl $0x10, %edi
callq 0xd580
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x470(%rbp)
leaq 0x25b11(%rip), %rsi     # 0x7514c
callq 0xd3b0
jmp 0x4f642
movq -0x470(%rbp), %rdi
movq 0x5d940(%rip), %rsi     # 0xacf90
movq 0x5d909(%rip), %rdx     # 0xacf60
callq 0xd970
jmp 0x4faa0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4f693
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0xdac0
leaq -0x1f1(%rbp), %rdi
callq 0xe180
jmp 0x4f89a
movq -0x470(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
callq 0xdc70
jmp 0x4f89a
cmpq $0x0, -0x1d0(%rbp)
jne 0x4f731
leaq -0x218(%rbp), %rdi
movq %rdi, -0x478(%rbp)
callq 0xd510
movq -0x478(%rbp), %rdx
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x52d00
jmp 0x4f6fd
leaq -0x218(%rbp), %rdi
callq 0xdac0
jmp 0x4f866
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x218(%rbp), %rdi
callq 0xdac0
jmp 0x4f89a
movq -0x10(%rbp), %rdi
movq -0x1d0(%rbp), %rdx
leaq -0x90(%rbp), %rsi
callq 0x53440
jmp 0x4f74a
leaq -0x90(%rbp), %rdi
callq 0x534d0
movq %rax, -0x230(%rbp)
movq %rdx, -0x228(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x534b0
movq %rax, -0x220(%rbp)
leaq -0x1a0(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0x4e6b0
movq -0x480(%rbp), %rdi
movq %rax, %rsi
movq -0x1d0(%rbp), %rax
addq %rax, %rsi
callq 0x53770
jmp 0x4f7a5
movq -0x220(%rbp), %rax
movq %rax, -0x498(%rbp)
movq -0x1d0(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x490(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x53850
movq %rax, -0x240(%rbp)
movq -0x1d0(%rbp), %rsi
leaq -0x240(%rbp), %rdi
callq 0x53880
movq -0x498(%rbp), %rdi
movq -0x490(%rbp), %rsi
movq %rax, -0x238(%rbp)
movq -0x238(%rbp), %rdx
callq 0x53800
movq %rax, -0x488(%rbp)
jmp 0x4f814
movq -0x488(%rbp), %rax
movq %rax, -0x248(%rbp)
movq -0x1d0(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x535f0
jmp 0x4f837
movq -0x10(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movl $0x2, %edx
callq 0x53440
jmp 0x4f84e
leaq -0x90(%rbp), %rdi
movl $0x2, %esi
callq 0x535f0
jmp 0x4f861
jmp 0x4f4fd
movq -0x408(%rbp), %rdi
addq $0x20, %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x536d0
leaq -0x1c0(%rbp), %rdi
callq 0xdac0
leaq -0x1a0(%rbp), %rdi
callq 0x18ac0
jmp 0x4f9fc
leaq -0x1c0(%rbp), %rdi
callq 0xdac0
leaq -0x1a0(%rbp), %rdi
callq 0x18ac0
jmp 0x4fa28
leaq -0x3c0(%rbp), %rdi
callq 0xdd60
jmp 0x4f8c5
leaq 0x25898(%rip), %rsi     # 0x75164
leaq -0x3c0(%rbp), %rdi
callq 0xd860
movq %rax, -0x4a0(%rbp)
jmp 0x4f8e1
leaq -0xe8(%rbp), %rdi
callq 0x538c0
movq %rax, -0x4a8(%rbp)
jmp 0x4f8f6
movq -0x4a8(%rbp), %rsi
movq -0x4a0(%rbp), %rdi
callq 0xd480
movq %rax, -0x4b0(%rbp)
jmp 0x4f912
movq -0x4b0(%rbp), %rdi
leaq 0x25869(%rip), %rsi     # 0x75189
callq 0xd860
jmp 0x4f927
movb $0x1, -0x3e1(%rbp)
movl $0x10, %edi
callq 0xd580
movq %rax, -0x4b8(%rbp)
leaq -0x3e0(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0xe0c0
jmp 0x4f954
movq -0x4b8(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
callq 0xd3e0
jmp 0x4f969
movq -0x4b8(%rbp), %rdi
movb $0x0, -0x3e1(%rbp)
movq 0x5d612(%rip), %rsi     # 0xacf90
movq 0x5d5db(%rip), %rdx     # 0xacf60
callq 0xd970
jmp 0x4faa0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4f9ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x4f9d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x3e0(%rbp), %rdi
callq 0xdac0
testb $0x1, -0x3e1(%rbp)
jne 0x4f9e0
jmp 0x4f9ec
movq -0x4b8(%rbp), %rdi
callq 0xdc70
jmp 0x4f9ee
leaq -0x3c0(%rbp), %rdi
callq 0xdcb0
jmp 0x4fa28
jmp 0x4f9fe
movb $0x1, -0xa5(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x53900
leaq -0xc0(%rbp), %rdi
callq 0x31f40
testb $0x1, -0xa5(%rbp)
jne 0x4fa4e
jmp 0x4fa42
leaq -0xe8(%rbp), %rdi
callq 0x53900
leaq -0xc0(%rbp), %rdi
callq 0x31f40
jmp 0x4fa73
movq -0x408(%rbp), %rdi
callq 0x11110
leaq -0x90(%rbp), %rdi
callq 0x53920
leaq -0x30(%rbp), %rdi
callq 0xdac0
movq -0x400(%rbp), %rax
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
movq -0x408(%rbp), %rdi
callq 0x11110
leaq -0x90(%rbp), %rdi
callq 0x53920
leaq -0x30(%rbp), %rdi
callq 0xdac0
movq -0xa0(%rbp), %rdi
callq 0xd990