UniqueChars normalize_header_name(JSContext *cx, MutableHandleValue name_val, size_t *name_len,
                                  const char *fun_name) {
  RootedString name_str(cx, JS::ToString(cx, name_val));
  if (!name_str)
    return nullptr;

  size_t len;
  UniqueChars name = encode(cx, name_str, &len);
  if (!name)
    return nullptr;

  if (len == 0) {
    JS_ReportErrorASCII(cx, "%s: Header name can't be empty", fun_name);
    return nullptr;
  }

  bool changed = false;

  char *name_chars = name.get();
  for (size_t i = 0; i < len; i++) {
    unsigned char ch = name_chars[i];
    if (ch > 127 || !VALID_NAME_CHARS[ch]) {
      JS_ReportErrorUTF8(cx, "%s: Invalid header name '%s'", fun_name, name_chars);
      return nullptr;
    }

    if (ch >= 'A' && ch <= 'Z') {
      name_chars[i] = ch - 'A' + 'a';
      changed = true;
    }
  }

  if (changed) {
    name_str = JS_NewStringCopyN(cx, name_chars, len);
    if (!name_str)
      return nullptr;
  }

  name_val.setString(name_str);
  *name_len = len;
  return name;
}
UniqueChars normalize_header_name(JSContext *cx, MutableHandleValue name_val, size_t *name_len,
                                  const char *fun_name) {
  RootedString name_str(cx, JS::ToString(cx, name_val));
  if (!name_str)
    return nullptr;

  size_t len;
  UniqueChars name = encode(cx, name_str, &len);
  if (!name)
    return nullptr;

  if (len == 0) {
    JS_ReportErrorASCII(cx, "%s: Header name can't be empty", fun_name);
    return nullptr;
  }

  bool changed = false;

  char *name_chars = name.get();
  for (size_t i = 0; i < len; i++) {
    unsigned char ch = name_chars[i];
    if (ch > 127 || !VALID_NAME_CHARS[ch]) {
      JS_ReportErrorUTF8(cx, "%s: Invalid header name '%s'", fun_name, name_chars);
      return nullptr;
    }

    if (ch >= 'A' && ch <= 'Z') {
      name_chars[i] = ch - 'A' + 'a';
      changed = true;
    }
  }

  if (changed) {
    name_str = JS_NewStringCopyN(cx, name_chars, len);
    if (!name_str)
      return nullptr;
  }

  name_val.setString(name_str);
  *name_len = len;
  return name;
}