static bool retrieve_value_for_header_from_handle(JSContext *cx, HandleObject self,
                                                  HandleValue name, MutableHandleValue value) {
  Mode mode = detail::mode(self);
  MOZ_ASSERT(mode != Mode::Standalone);
  uint32_t handle = detail::handle(self);

  size_t name_len;
  RootedString name_str(cx, name.toString());
  UniqueChars name_chars = encode(cx, name_str, &name_len);

  RootedString val_str(cx);
  OwnedHostCallBuffer buffer;

  MULTI_VALUE_HOSTCALL(
      {
        int result;
        if (mode == Headers::Mode::ProxyToRequest) {
          RequestHandle request = {handle};
          result = xqd_req_header_values_get(request, name_chars.get(), name_len, buffer.get(),
                                             HEADER_MAX_LEN, cursor, &ending_cursor, &nwritten);
        } else {
          ResponseHandle response = {handle};
          result = xqd_resp_header_values_get(response, name_chars.get(), name_len, buffer.get(),
                                              HEADER_MAX_LEN, cursor, &ending_cursor, &nwritten);
        }

        if (!HANDLE_RESULT(cx, result))
          return false;
      },
      {
        size_t offset = 0;
        for (size_t i = 0; i < nwritten; i++) {
          if (buffer.get()[i] == '\0') {
            val_str = JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(buffer.get() + offset, i - offset));
            if (!val_str)
              return false;

            value.setString(val_str);

            if (!append_header_value_to_map(cx, self, name, value))
              return false;

            offset = i + 1;
          }
        }
      })

  return true;
}
static bool retrieve_value_for_header_from_handle(JSContext *cx, HandleObject self,
                                                  HandleValue name, MutableHandleValue value) {
  Mode mode = detail::mode(self);
  MOZ_ASSERT(mode != Mode::Standalone);
  uint32_t handle = detail::handle(self);

  size_t name_len;
  RootedString name_str(cx, name.toString());
  UniqueChars name_chars = encode(cx, name_str, &name_len);

  RootedString val_str(cx);
  OwnedHostCallBuffer buffer;

  MULTI_VALUE_HOSTCALL(
      {
        int result;
        if (mode == Headers::Mode::ProxyToRequest) {
          RequestHandle request = {handle};
          result = xqd_req_header_values_get(request, name_chars.get(), name_len, buffer.get(),
                                             HEADER_MAX_LEN, cursor, &ending_cursor, &nwritten);
        } else {
          ResponseHandle response = {handle};
          result = xqd_resp_header_values_get(response, name_chars.get(), name_len, buffer.get(),
                                              HEADER_MAX_LEN, cursor, &ending_cursor, &nwritten);
        }

        if (!HANDLE_RESULT(cx, result))
          return false;
      },
      {
        size_t offset = 0;
        for (size_t i = 0; i < nwritten; i++) {
          if (buffer.get()[i] == '\0') {
            val_str = JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(buffer.get() + offset, i - offset));
            if (!val_str)
              return false;

            value.setString(val_str);

            if (!append_header_value_to_map(cx, self, name, value))
              return false;

            offset = i + 1;
          }
        }
      })

  return true;
}