HTTP协议header中Content-Disposition中⽂⽂件名乱码
从跟踪代码来看,content-disposition存放的是http response的raw header。直到在HttpContentDisposition类的filename_成员才会存放转换了的编码。
这个转换编码的猜测流程:asc,utf,有指定编码,按指定;否则按系统的字符集。
参考:
blog.csdn/lc11535/article/details/100013653
⽐如:“中⽂” 字符得编码:
Unicode中为:4E2D 6587
GBK(gb2312 gb18030)中为:D6D0 CEC4
这是在内存中存放形式。chrome内部统⼀⽤Unicode在内存存放,所以会有⼀张gbk到unicode得对照表,将“中”的 gbk D6D0 转换为 unicode的4E2D。
当需要把“中⽂”这两字保存到⽂件,或者⽹络传输时,直接保存需要两个字节,这样会浪费保存英⽂的存
储空间,因为英⽂只需要⼀个字节。所以这时就有个编码的需求。⼀般都是⽤utf8。英⽂直接还是⽤⼀个字节;中⽂就要⽤3个字节。utf8,utf16,utf32都是对unicode的编码存储。
“中⽂”的utf8存成⽂件为:
⽽“中⽂”的GBK存储时,直接就是按编码存储。
gb2312:
规定:⼀个⼩于127的字符的意义与原来相同,但两个⼤于127的字符连在⼀起时,就表⽰⼀个汉字,前⾯的⼀个字节(他称之为⾼字节)从0xA1⽤到0xF7,后⾯⼀个字节(低字节)从0xA1到0xFE,这样我们就可以组合出⼤约7000多个简体汉字了
gbk:只要⾼位是1开始,即⼤于127;不再管地位。这样增加了2万汉字。
GB18030:加⼊了少数民族的字。
Unicode出现:所有字符都占两位
wchar_t * p = L"Hello!" ;//占10个字节
没有⼀种简单的算术⽅法可以把⽂本内容从UNICODE编码和另⼀种编码进⾏转换,这种转换必须通过查表来进⾏。如unicode 到gbk。具体的符号对应表,可以查询,或者专门的。
UNICODE("Universal Multiple-Octet Coded Character Set",简称 UCS, 俗称 "UNICODE"。)是⽤两个字节来表⽰为⼀个字符,组合出65535不同的字符,这⼤概已经可以覆盖世界上所有⽂化的符号。
如果还不够也没有关系,ISO已经准备了UCS-4⽅案,说简单了就是四个字节来表⽰⼀个字符,这样我们就可以组合出21亿个不同的字符出来(最⾼位有其他⽤途)。
⾯向⽹络传输规范出现:UTF(UCS Transfer Format)顾名思义,UTF8就是每次8个位传输数据,⽽UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,⽽是要过⼀些算法和规则来转换。重复⼀遍,这⾥的关系是,UTF-8是Unicode的实现⽅式之⼀。
INTEL低位先发送"FEFF",否则⾼位,utf的⽂件头都有这个标志。
打开⽂件时 EF BB BF,表⽰UTF-8
Unicode UTF-8
0000 - 007F0xxxxxxx
0080 - 07FF110xxxxx 10xxxxxx
0800 - FFFF1110xxxx 10xxxxxx 10xxxxxx
记事本的编码默认是ANSI, 如果你在ANSI的编码输⼊汉字,那么他实际就是GB系列的编码⽅式,在这种编码下,"联通"的内码是:
  c1 1100 0001
  aa 1010 1010
  cd 1100 1101
  a8 1010 1000
windows的记事本保存时选择编码格式:
⾥⾯有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8。
1)ANSI是默认的编码⽅式。对于英⽂⽂件是ASCII编码,对于简体中⽂⽂件是GB2312编码(只针对Windows简体中⽂版,如果是繁体中⽂版会采⽤Big5码)。
2)Unicode编码指的是UCS-2编码⽅式,即直接⽤两个字节存⼊字符的Unicode码。这个选项⽤的little endian格式。
3)Unicode big endian编码与上⼀个选项相对应。我在下⼀节会解释little endian和big endian的涵义。
4)UTF-8编码,也就是上⼀节谈到的编码⽅法。
选择完”编码⽅式“后,点击”保存“按钮,⽂件的编码⽅式就⽴刻转换好了。
Unicode码可以采⽤UCS-2格式直接存储。以汉字”严“为例,Unicode码是4E25,需要⽤两个字节存储,⼀个字节是4E,另⼀个字节是25。存储的时候,4E在前,25在后,就是Big endian⽅式;25在前,4E在后,就是Little endian⽅式。
Unicode规范中定义,每⼀个⽂件的最前⾯分别加⼊⼀个表⽰编码顺序的字符,这个字符的名字叫做”零宽度⾮换⾏空格“(ZERO WIDTH NO-BREAK SPACE),⽤FEFF表⽰。这正好是两个字节,⽽且FF⽐FE⼤1。
如果⼀个⽂本⽂件的头两个字节是FE FF,就表⽰该⽂件采⽤⼤头⽅式;如果头两个字节是FF FE,就表⽰该⽂件采⽤⼩头⽅式。
这两个古怪的名称来⾃英国作家斯威夫特的《格列佛游记》。在该书中,⼩⼈国⾥爆发了内战,战争起因是⼈们争论,
吃鸡蛋时究竟是从⼤头(Big-Endian)敲开还是从⼩头(Little-Endian)敲开。为了这件事情,前后爆发了六次战争,
⼀个皇帝送了命,另⼀个皇帝丢了王位。
因此,第⼀个字节在前,就是”⼤头⽅式“(Big endian),第⼆个字节在前就是”⼩头⽅式“(Little endian)。
实例:
打开”记事本“程序,新建⼀个⽂本⽂件,内容就是⼀个”严“字,依次采⽤ANSI,Unicode,Unicode big endian 和 UTF-8编码⽅式保存。
然后,⽤⽂本编辑软件UltraEdit中的”⼗六进制功能“,观察该⽂件的内部编码⽅式。
1)ANSI:⽂件的编码就是两个字节“D1 CF”,这正是“严”的GB2312编码,这也暗⽰GB2312是采⽤⼤头⽅式存储的。
2)Unicode:编码是四个字节“FF FE 25 4E”,其中“FF FE”表明是⼩头⽅式存储,真正的编码是4E25。
3)Unicode big endian:编码是四个字节“FE FF 4E 25”,其中“FE FF”表明是⼤头⽅式存储。
4)UTF-8:编码是六个字节“EF BB BF E4 B8 A5”,
前三个字节“EF BB BF”表⽰这是UTF-8编码,
后三个“E4B8A5”就是“严”的具体编码,它的存储顺序与编码顺序是⼀致的。
Unicode和utf16是⼀⼀对应的。他俩都是2个字节。只是传输英⽂会浪费⼀倍空间。
打开⽂件 FE FF 表⽰UTF-16.
"汉"对应的unicode是6C49
UTF-16表⽰的话就是01101100  01001001(共16 bit,两个字节).UTF-16不需要⽤啥字符来做标志,所以两字节也就是2的16次能表⽰65536个字符.
⽽UTF-8由于⾥⾯有额外的标志信息,所有⼀个字节只能表⽰2的7次⽅128个字符,两个字节只能表⽰2的11次⽅2048个字符.⽽三个字节能表⽰2的16次⽅,65536个字符.
由于"汉"的编码27721⼤于2048了所有两个字节还不够,只能⽤三个字节来表⽰.
所有要⽤1110xxxx 10xxxxxx 10xxxxxx这种格式.把27721对应的⼆进制从左到右(little endia 从右到左)填充XXX符号.
Unicode版本2
前⾯说的都是unicode的第⼀个版本.但65536显然不算太多的数字,⽤它来表⽰常⽤的字符是没⼀点问题.⾜够了,但如果加上很多特殊的就也不够了.于是从1996年开始⼜来了第⼆个版本.⽤四个字节表⽰所有字符.这样就出现了UTF-8,UTF16,UTF-32.原理和之前肯定是完全⼀样的,UTF-32就是把所有的字符都⽤32bit也就是4个字节来表⽰.然后UTF-
8,UTF-16就视情况⽽定了.UTF-8可以选择1⾄8个字节中的任⼀个来表⽰.⽽UTF-16只能是选两字节或四字节..由于unicode版本2的原理完全是⼀样的,就不多说了.
前⾯说了要知道具体是哪种编码⽅式,需要判断⽂本开头的标志,下⾯是所有编码对应的开头标志
EF BB BF    UTF-8
FE FF     UTF-16/UCS-2, little endian
FF FE     UTF-16/UCS-2, big endian
FF FE 00 00  UTF-32/UCS-4, little endian.
00 00 FE FF  UTF-32/UCS-4, big-endian.
其中的UCS就是前⾯说的ISO制定的标准,和Unicode是完全⼀样的,只不过名字不⼀样.ucs-2对应utf-16,ucs-4对应UTF-32.UTF-8是没有对应的UCS
UTF-16 并不是⼀个完美的选择,它存在⼏个⽅⾯的问题:
1. UTF-16 能表⽰的字符数有 6 万多,看起来很多,但是实际上⽬前 Unicode 5.0 收录的字符已经达到 99024 个字符,早已超过 UTF-16 的存储范围;这直接导致 UTF-16 地
位颇为尴尬——如果谁还在想着只要使⽤ UTF-16 就可以⾼枕⽆忧的话,恐怕要失望了
2. UTF-16 存在⼤⼩端字节序问题,这个问题在进⾏信息交换时特别突出——如果字节序未协商好,将导致乱码;如果协商好,但是双⽅⼀个采⽤⼤端⼀个采⽤⼩端,则必然
有⼀⽅要进⾏⼤⼩端转换,性能损失不可避免(⼤⼩端问题其实不像看起来那么简单,有时会涉及硬件、操作系统、上层软件多个层次,可能会进⾏多次转换)
3. 另外,容错性低有时候也是⼀⼤问题——局部的字节错误,特别是丢失或增加可能导致所有后续字符全部错乱,错乱后要想恢复,可能很简单,也可能会⾮常困难。(这⼀
点在⽇常⽣活⾥⼤家感觉似乎⽆关紧要,但是在很多特殊环境下却是巨⼤的缺陷)
⽬前⽀撑我们继续使⽤ UTF-16 的理由主要是考虑到它是双字节的,在计算字符串长度、执⾏索引操作时速度很快。当然这些优点 UTF-32 都具有,但很多⼈毕竟还是觉得 UTF-32 太占空间了。
反过来 UTF-8 也不完美,也存在⼀些问题:
1. ⽂化上的不平衡——对于欧美地区⼀些以英语为母语的国家 UTF-8 简直是太棒了,因为它和 ASCII ⼀样,⼀个字符只占⼀个字节,没有任何额外的存储负担;但是对于中
⽇韩等国家来说,UTF-8 实在是太冗余,⼀个字符竟然要占⽤ 3 个字节,存储和传输的效率不但没有提升,反⽽下降了。所以欧美⼈民常常毫不犹豫的采⽤ UTF-8,⽽我们却⽼是要犹豫⼀会⼉
2. 变长字节表⽰带来的效率问题——⼤家对 UTF-8 疑虑重重的⼀个问题就是在于其因为是变长字节表⽰,因此⽆论是计算字符数,还是执⾏索引操作效率都不⾼。为了解决
这个问题,常常会考虑把 UTF-8 先转换为 UTF-16 或者 UTF-32 后再操作,操作完毕后再转换回去。⽽这显然是⼀种性能负担。
当然,UTF-8 的优点也不能忘了:
1. 字符空间⾜够⼤,未来 Unicode 新标准收录更多字符,UTF-8 也能妥妥的兼容,因此不会再出现 UTF-16 那样的尴尬
2. 不存在⼤⼩端字节序问题,信息交换时⾮常便捷
3. 容错性⾼,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界很容易检测出来,这是⼀个巨⼤的优点(正是为了实现这⼀点,咱们中
⽇韩⼈民不得不忍受 3 字节 1 个字符的苦⽇⼦)
那么到底该如何选择呢?
因为⽆论是 UTF-8 和 UTF-16/32 都各有优缺点,因此选择的时候应当⽴⾜于实际的应⽤场景。例如在我的习惯中,存储在磁盘上或进⾏⽹络交换时都会采⽤ UTF-8,⽽在程序内部进⾏处理时则转换为 UTF-16/32。对于⼤多数简单的程序来说,这样做既可以保证信息交换时容易实现相互兼容,同时在内部处理时会⽐较简单,性能也还算不错。(基本上只要你的程序不是 I/O 密集型的都可以这么⼲,当然这只是我粗浅的认识范围内的经验,很可能会被⽆情的反驳)
稍微再展开那么⼀点点……
在⼀些特殊的领域,字符编码的选择会成为⼀个很关键的问题。特别是⼀些⾼性能⽹络处理程序⾥更是如此。这时采⽤⼀些特殊的设计技巧,可以缓解性能和字符集选择之间的⽭盾。例如对于内容检测/过滤系统,需要⾯对任何可能的字符编码,这时如果还采⽤把各种不同的编码都转换为同⼀种编码后再处理的⽅案,那么性能下降将会很显著。⽽如果采⽤多字符编码⽀持的有限状态机⽅案,则既能够⽆需转换编码,同时⼜能够以极⾼的性能进⾏处理。当然如何从规则列表⽣成有限状态机,如何使得有限状态机⽀持多编码,以及这将带来哪些限制,已经⼜成了另外的问题了。
转换编码:
/** 中⽂字符串转UTF-8与GBK码⽰例
*/
public static void tttt() throws Exception {
String old = "⼿机银⾏";
//中⽂转换成UTF-8编码(16进制字符串)
StringBuffer utf8Str = new StringBuffer();
byte[] utf8Decode = Bytes("utf-8");
for (byte b : utf8Decode) {
utf8Str.HexString(b & 0xFF));
}
//      String()=====e6898be69cbae993b6e8a18c
//      System.out.println("UTF-8字符串e6898be69cbae993b6e8a18c转换成中⽂值======" + new String(utf8Decode, "utf-8"));//-------⼿机银⾏
//中⽂转换成GBK码(16进制字符串)
StringBuffer gbkStr = new StringBuffer();
byte[] gbkDecode = Bytes("gbk");
for (byte b : gbkDecode) {
gbkStr.HexString(b & 0xFF));
}
//      String()=====cad6bbfad2f8d0d0
//      System.out.println("GBK字符串cad6bbfad2f8d0d0转换成中⽂值======" + new String(gbkDecode, "gbk"));//----------⼿机银⾏
//16进制字符串转换成中⽂
byte[] bb = String());
bb = HexString2Bytes("CAD6BBFAD2F8D0D0000000000000000000000000");
byte[] cc = hexToByte("CAD6BBFAD2F8D0D0000000000000000000000000", 20);
String aa = new String(bb, "gbk");
System.out.println("aa====" + aa);
}
/**
* 把16进制字符串转换成字节数组
* @param hexstr
* @return
*/
public static byte[] HexString2Bytes(String hexstr) {
byte[] b = new byte[hexstr.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hexstr.charAt(j++);
char c1 = hexstr.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
}
private static int parse(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
处理content-disposition http header⾥⾯。
chrome内部使⽤utf8来处理。
if (!base::IsStringASCII(encoded_word)) {
// Try UTF-8, referrer_charset and the native OS default charset in turn.
if (base::IsStringUTF8(encoded_word)) {
*output = encoded_word;//utf8直接返回
} else {
base::string16 utf16_output;
//对应未知编码,先转成utf16,在转成utf8输出。字符集charset没有设置,就⽤系统当前默认的。windows为GBK。windows10可以⾃⼰把默认字符集改为UTF8。if (!pty() &&
ConvertToUTF16(encoded_word, referrer_charset.c_str(),
&utf16_output)) {
*output = base::UTF16ToUTF8(utf16_output);
} else {
*output = base::WideToUTF8(base::SysNativeMBToWide(encoded_word));
}
}
*parse_result_flags |= HttpContentDisposition::HAS_NON_ASCII_STRINGS;
electron层:
d:\dev\electron7\src\electron\shell\browser\api\atom_api_
std::string DownloadItem::GetFilename() const {
return base::UTF16ToUTF8(
net::GenerateFileName(GetURL(), GetContentDisposition(), std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(), "download")
.LossyDisplayName());
}
std::string DownloadItem::GetContentDisposition() const {乱码文字生成
return download_item_->GetContentDisposition();
}
还是把上⾯的分析disposition跑了⼀遍,最终到net模块的:
base::string16 GetSuggestedFilenameImpl(
const GURL& url,
const std::string& content_disposition,
const std::string& referrer_charset,
const std::string& suggested_name,
const std::string& mime_type,
const std::string& default_name,
bool should_replace_extension,
ReplaceIllegalCharactersFunction replace_illegal_characters_function) {
// TODO: this function to be updated to match the httpbis recommendations.
// Talk to abarth for the latest news.
// We don't translate this fallback string, "download". If localization is
// needed, the caller should provide localized fallback in |default_name|.
static const base::FilePath::CharType kFinalFallbackName[] =
FILE_PATH_LITERAL("download");
std::string filename;  // In UTF-8
bool overwrite_extension = false;
bool is_name_from_content_disposition = false;
// Try to extract a filename from content-disposition first.
if (!pty()) {
HttpContentDisposition header(content_disposition, referrer_charset);
filename = header.filename();
if (!pty())
is_name_from_content_disposition = true;
}
// Then try to use the suggested name.
if (pty() && !pty())
filename = suggested_name;
// Now try extracting the filename from the URL.  GetFileNameFromURL() only
// looks at the last component of the URL and doesn't return the hostname as a
// failover.
if (pty())
filename = GetFileNameFromURL(url, referrer_charset, &overwrite_extension);
// Finally try the URL hostname, but only if there's no default specified in
// |default_name|.  Some schemes (e.g.: file:, about:, data:) do not have a
// host name.
if (pty() && pty() && url.is_valid() &&
!
url.host().empty()) {
// TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451)
filename = url.host();
}
bool replace_trailing = false;
base::FilePath::StringType result_str, default_name_str;
#if defined(OS_WIN)
replace_trailing = true;
result_str = base::UTF8ToUTF16(filename);
default_name_str = base::UTF8ToUTF16(default_name);
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
result_str = filename;
default_name_str = default_name;
#else
#error Unsupported platform
#endif
SanitizeGeneratedFileName(&result_str, replace_trailing);
if (result_str.find_last_not_of(FILE_PATH_LITERAL("-_")) ==
base::FilePath::StringType::npos) {
result_str = !default_pty()
default_name_str
: base::FilePath::StringType(kFinalFallbackName);
overwrite_extension = false;
}
replace_illegal_characters_function(&result_str, '_');
base::FilePath result(result_str);
overwrite_extension |= should_replace_extension;
// extension should not appended to filename derived from
// content-disposition, if it does not have one.
// Hence mimetype and overwrite_extension values are not used.
if (is_name_from_content_disposition)
GenerateSafeFileName("", false, &result);
else
GenerateSafeFileName(mime_type, overwrite_extension, &result);
base::string16 result16;
if (!FilePathToString16(result, &result16)) {
result = base::FilePath(default_name_str);
if (!FilePathToString16(result, &result16)) {
result = base::FilePath(kFinalFallbackName);
FilePathToString16(result, &result16);
}
}
return result16;
}
base::FilePath GenerateFileNameImpl(
const GURL& url,
const std::string& content_disposition,
const std::string& referrer_charset,
const std::string& suggested_name,
const std::string& mime_type,
const std::string& default_file_name,
bool should_replace_extension,
ReplaceIllegalCharactersFunction replace_illegal_characters_function) {
base::string16 file_name = GetSuggestedFilenameImpl(
url, content_disposition, referrer_charset, suggested_name, mime_type,
default_file_name, should_replace_extension,
replace_illegal_characters_function);
#if defined(OS_WIN)
base::FilePath generated_name(file_name);
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
base::FilePath generated_name(
base::SysWideToNativeMB(base::UTF16ToWide(file_name)));
#endif
DCHECK(!pty());
return generated_name;
}
http⽹页跳转时调⽤:
1,
2
3
4,这⾥把原始编码做转换,会调⽤ HttpContentDisposition::HttpContentDisposition的parse函数,调⽤到bool DecodeWord(const std::string& encoded_word
5,开始远程调⽤:
6posttask到
7,转到delegate_->StartDownloadItem
8,新的download⾛:
GetNextId(base::BindOnce(&DownloadManagerImpl::CreateNewDownloadItemToStart,
weak_factory_.GetWeakPtr(), std::move(info),
on_started, std::move(callback)));
9,再到
download::DownloadItemImpl* download = CreateActiveItem(id, *info);
10,这⾥还是没转码的值:
从跟踪代码来看,content-disposition存放的是http response的raw header。
在HttpContentDisposition类的filename_成员才会存放转换了的编码。
js⾥⾯全部是utf8编码,导致gbk的响应头⽆法输出
[17240:0923/170223.551:(210)] Check failed: IsStringUTF8(string_value_).
Backtrace:
base::debug::CollectStackTrace [0x00007FFC111911E0+48] (D:\dev\electron7\src\base\debug\stack_:284)
base::debug::StackTrace::StackTrace [0x00007FFC11191180+80] (D:\dev\electron7\src\base\debug\:206)
base::debug::StackTrace::StackTrace [0x00007FFC11183B58+40] (D:\dev\electron7\src\base\debug\:203)
logging::LogMessage::~LogMessage [0x00007FFC11203D2F+143] (D:\dev\electron7\src\:629)
base::Value::Value [0x00007FFC114714E2+290] (D:\dev\electron7\src\:211)
base::Value::Value [0x00007FFC114719AE+62] (D:\dev\electron7\src\:206)
std::_Default_allocator_traits<std::allocator<base::Value> >::construct<base::Value,std::basic_string<char,std::char_traits<char>,std::allocator<char> > &> [0x00007FF61263DD08+88] (C:\Program Files (x86)\Microsoft Visual Studio\2019\        std::vector<base::Value,std::allocator<base::Value> >::_Emplace_reallocate<std::basic_string<char,std::char_traits<char>,std::allocator<char> > &> [0x00007FF61263DBB2+386] (C:\Program Files (x86)\Microsoft Visual Studio\2019\Com        std::vect
or<base::Value,std::allocator<base::Value> >::emplace_back<std::basic_string<char,std::char_traits<char>,std::allocator<char> > &> [0x00007FF61263D930+128] (C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\ electron::api::`anonymous namespace'::HttpResponseHeadersToV8 [0x00007FF61263D3B8+392] (D:\dev\electron7\src\electron\shell\browser\api\atom_api_web_:115)
electron::api::`anonymous namespace'::ToDictionary [0x00007FF61263C880+1280] (D:\dev\electron7\src\electron\shell\browser\api\atom_api_web_:138)
electron::api::`anonymous namespace'::FillDetails<extensions::WebRequestInfo *,network::ResourceRequest> [0x00007FF61263A7E7+55] (D:\dev\electron7\src\electron\shell\browser\api\atom_api_web_:180)
electron::api::WebRequestNS::HandleSimpleEvent<network::ResourceRequest> [0x00007FF61262B581+305] (D:\dev\electron7\src\electron\shell\browser\api\atom_api_web_:414) electron::api::WebRequestNS::OnResponseStarted [0x00007FF61262B430+112] (D:\dev\electron7\src\electron\shell\browser\api\atom_api_web_:316)
electron::ProxyingURLLoaderFactory::InProgressRequest::ContinueToResponseStarted [0x00007FF612709917+1079] (D:\dev\electron7\src\electron\shell\browser\net\proxying_url_:512) electron::ProxyingURLLoaderFactory::InProgressRequest::OnReceiveResponse [0x00007FF612709349+265] (D:\dev\electron7\src\electron\shell\browser\net\proxying_url_:208)
network::mojom::URLLoaderClientStubDispatch::Accept [0x00007FF612BE9A24+980] (D:\dev\electron7\src\out\Testing\gen\services\network\public\mojom\:1191)
network::mojom::URLLoaderClientStub<mojo::RawPtrImplRefTraits<network::mojom::URLLoaderClient> >::Accept [0x00007FF6127111F2+98] (D:\dev\electron7\src\out\Testing\gen\services\network\public\mojom\jom.h:296)        mojo::InterfaceEndpointClient::HandleValidatedMessage [0x00007FFC343B8EEF+1935] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\interface_:554)
mojo::InterfaceEndpointClient::HandleIncomingMessageThunk::Accept [0x00007FFC343B8751+33] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\interface_:140)
mojo::FilterChain::Accept [0x00007FFC343B73C9+393] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\:40)
mojo::InterfaceEndpointClient::HandleIncomingMessage [0x00007FFC343BBCD5+213] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\interface_:357)
mojo::internal::MultiplexRouter::ProcessIncomingMessage [0x00007FFC343CE6F2+1666] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\:876)
mojo::internal::MultiplexRouter::Accept [0x00007FFC343CDC41+673] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\:598)
mojo::FilterChain::Accept [0x00007FFC343B73C9+393] (D:\dev\electron7\src\mojo\public\cpp\bindings\lib\:40)
mojo::Connector::DispatchMessageW [0x00007FFC3439F6F4+1396] (D:\dev\electron7\src\mojo\public\cpp\bindings\:513)
mojo::Connector::ReadAllAvailableMessages [0x00007FFC343A0D53+675] (D:\dev\electron7\src\mojo\public\cpp\bindings\:589)
mojo::Connector::OnHandleReadyInternal [0x00007FFC343A088A+378] (D:\dev\electron7\src\mojo\public\cpp\bindings\:424)
mojo::Connector::OnWatcherHandleReady [0x00007FFC343A06FB+27] (D:\dev\electron7\src\mojo\public\cpp\bindings\:384)
base::internal::FunctorTraits<void (mojo::Connector::*)(unsigned int),void>::Invoke<void (mojo::Connector::*)(unsigned int),mojo::Connector *,unsigned int> [0x00007FFC343A90B5+69] (D:\dev\electron7\src\base\bind_internal.h:499)
base::internal::InvokeHelper<0,void>::MakeItSo<void (mojo::Connector::*const &)(unsigned int),mojo::Connector *,unsigned int> [0x00007FFC343A8FFD+77] (D:\dev\electron7\src\base\bind_internal.h:599)
base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int),base::internal::UnretainedWrapper<mojo::Connector> >,void (unsigned int)>::RunImpl<void (mojo::Connector::*const &)(unsigned int),const std::tuple<        base::internal::Invoker<base::internal::BindState<void (mojo::Connector::*)(unsigned int),base::internal::UnretainedWrapper<mojo::Connector> >,void (unsigned int)>::Run [0x00007FFC34
3A8E85+101] (D:\dev\electron7\src\base\bind_interna        base::RepeatingCallback<void (unsigned int)>::Run [0x00007FFC34397DA8+104] (D:\dev\electron7\src\base\callback.h:132)
mojo::SimpleWatcher::DiscardReadyState [0x00007FFC343A36B0+32] (D:\dev\electron7\src\mojo\public\cpp\system\simple_watcher.h:195)
base::internal::FunctorTraits<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),void>::Invoke<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned i        base::internal::InvokeHelper<0,void>::MakeItSo<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),const base::RepeatingCallback<void (unsigned int)> &,unsigned int,c        base::internal::Invoker<base::internal::BindState<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)> >,void (unsigned int, const mo        base::internal::Invoker<base::internal::BindState<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)> >,void (unsigned int, const mo        base::RepeatingCallback<void (unsigned int, const
mojo::HandleSignalsState &)>::Run [0x00007FFC34A9C281+129] (D:\dev\electron7\src\base\callback.h:132)
mojo::SimpleWatcher::OnHandleReady [0x00007FFC34A9BE11+753] (D:\dev\electron7\src\mojo\public\cpp\system\:293)
base::internal::FunctorTraits<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),void>::Invoke<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::Simp        base::internal::InvokeHelper<1,void>::MakeItSo<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState> [0x00007FFC34A9CC9        base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunImpl<void        base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunOnce [0x        base::OnceCallback<void ()>::Run [0x00007
FFC111726B1+97] (D:\dev\electron7\src\base\callback.h:99)
base::TaskAnnotator::RunTask [0x00007FFC11341335+1605] (D:\dev\electron7\src\base\task\common\:144)
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl [0x00007FFC113794AC+1804] (D:\dev\electron7\src\base\task\sequence_manager\thread_controller_with_message_:366)
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork [0x00007FFC11378B2F+191] (D:\dev\electron7\src\base\task\sequence_manager\thread_controller_with_message_:221)
base::MessagePumpForUI::DoRunLoop [0x00007FFC11220449+457] (D:\dev\electron7\src\base\message_loop\message_:217)
base::MessagePumpWin::Run [0x00007FFC1121EBA4+292] (D:\dev\electron7\src\base\message_loop\message_:76)
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run [0x00007FFC1137
A87E+910] (D:\dev\electron7\src\base\task\sequence_manager\thread_controller_with_message_:467)
base::RunLoop::Run [0x00007FFC112DE335+901] (D:\dev\electron7\src\base\:156)
content::BrowserMainLoop::MainMessageLoopRun [0x00007FFBFEC4AADD+157] (D:\dev\electron7\src\content\browser\browser_:1511)
content::BrowserMainLoop::RunMainMessageLoopParts [0x00007FFBFEC4A8D0+528] (D:\dev\electron7\src\content\browser\browser_:1031)
content::BrowserMainRunnerImpl::Run [0x00007FFBFEC500DF+335] (D:\dev\electron7\src\content\browser\browser_main_:149)
content::BrowserMain [0x00007FFBFEC4357C+284] (D:\dev\electron7\src\content\browser\:47)
content::RunBrowserProcessMain [0x00007FFC0145D468+168] (D:\dev\electron7\src\content\app\content_main_:556)
content::ContentMainRunnerImpl::RunServiceManager [0x00007FFC0145EC76+1334] (D:\dev\electron7\src\content\app\content_main_:963)
content::ContentMainRunnerImpl::Run [0x00007FFC0145E656+614] (D:\dev\electron7\src\content\app\content_main_:871)
content::ContentServiceManagerMainDelegate::RunEmbedderProcess [0x00007FFC01459BA7+55] (D:\dev\electron7\src\content\app\content_service_manager_:52)
service_manager::Main [0x00007FFBDA202323+1731] (D:\dev\electron7\src\services\service_manager\:423)
content::ContentMain [0x00007FFC0145D32F+95] (D:\dev\electron7\src\content\app\:20)
wWinMain [0x00007FF6123C20BC+1244] (D:\dev\electron7\src\electron\shell\app\:168)
invoke_main [0x00007FF6150A6B42+50] (d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:123)
__scrt_common_main_seh [0x00007FF6150A6C7E+302] (d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
__scrt_common_main [0x00007FF6150A6CFE+14] (d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331)
wWinMainCRTStartup [0x00007FF6150A6D19+9] (d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp:17)
BaseThreadInitThunk [0x00007FFC4B4C7BD4+20]
RtlUserThreadStart [0x00007FFC4C86CE51+33]
Task trace:
Backtrace:
mojo::SimpleWatcher::Context::Notify [0x00007FFC34A9C590+528] (D:\dev\electron7\src\mojo\public\cpp\system\:120)
IPC message handler context: 0x51C3F41F

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。