当你在浏览器中输入Google.com并且按下回车之后发生了什么?

阅读目录

原文出处:Alex译文出处:

本文试图回答一个古老的面试问题:当你在浏览器中输入Google.com并且按下回车之后发生了什么?

不过我们不再局限于平常的回答,而是想办法回答地尽可能具体,不遗漏任何细节。

这将是一个协作的过程,所以深入挖掘吧,并且帮助我们一起完善它。仍然有大量的细节等待着你来添加,欢迎向我们发送Pull Requset!

这些内容使用Creative Commons Zero协议发布。

回车键按下

为了从头开始,我们选择键盘上的回车键被按到最低处作为起点。在这个时刻,一个专用于回车键的电流回路被直接或者通过电容器闭合了,使得少量的电流进入了键盘的逻辑电路系统。这个系统会扫描每个键的状态,对于按键开关的电位弹跳变化进行噪音消除(debounce),并将其转化为键盘码值。在这里,回车的码值是13。键盘控制器在得到码值之后,将其编码,用于之后的传输。现在这个传输过程几乎都是通过通用串行总线(USB)或者蓝牙(Bluetooth)来进行的,以前是通过PS/2或者ADB连接进行。

USB键盘:

虚拟键盘(触屏设备):

产生中断[非USB键盘]

键盘在它的中断请求线(IRQ)上发送信号,信号会被中断控制器映射到一个中断向量,实际上就是一个整型数 。CPU使用中断描述符表(IDT)把中断向量映射到对应函数,这些函数被称为中断处理器,它们由操作系统内核提供。当一个中断到达时,CPU根据IDT和中断向量索引到对应的中端处理器,然后操作系统内核出场了。

(Windows)一个WM_KEYDOWN消息被发往应用程序

HID把键盘按下的事件传送给KBDHID.sys驱动,把HID的信号转换成一个扫描码(Scancode),这里回车的扫描码是VK_RETURN(0x0d)。KBDHID.sys驱动和KBDCLASS.sys(键盘类驱动,keyboard class driver)进行交互,这个驱动负责安全地处理所有键盘和小键盘的输入事件。之后它又去调用Win32K.sys,在这之前有可能把消息传递给安装的第三方键盘过滤器。这些都是发生在内核模式。

Win32K.sys通过GetForegroundWindow()API函数找到当前哪个窗口是活跃的。这个API函数提供了当前浏览器的地址栏的句柄。Windows系统的”message pump”机制调用SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam)函数,lParam是一个用来指示这个按键的更多信息的掩码,这些信息包括按键重复次数(这里是0),实际扫描码(可能依赖于OEM厂商,不过通常不会是VK_RETURN),功能键(alt, shift, ctrl)是否被按下(在这里没有),以及一些其他状态。

Windows的SendMessageAPI直接将消息添加到特定窗口句柄hWnd的消息队列中,之后赋给hWnd的主要消息处理函数WindowProc将会被调用,用于处理队列中的消息。

当前活跃的句柄hWnd实际上是一个edit control控件,这种情况下,WindowProc有一个用于处理WM_KEYDOWN消息的处理器,这段代码会查看SendMessage传入的第三个参数wParam,因为这个参数是VK_RETURN,于是它知道用户按下了回车键。

(Mac OS X)一个KeyDownNSEvent被发往应用程序

中断信号引发了I/O Kit Kext键盘驱动的中断处理事件,驱动把信号翻译成键码值,然后传给OS X的WindowServer进程。然后,WindowServer将这个事件通过Mach端口分发给合适的(活跃的,或者正在监听的)应用程序,这个信号会被放到应用程序的消息队列里。队列中的消息可以被拥有足够高权限的线程使用mach_ipc_dispatch函数读取到。这个过程通常是由NSApplication主事件循环产生并且处理的,通过NSEventType为KeyDown的NSEvent。

(GNU/Linux)Xorg 服务器监听键码值

当使用图形化的 X Server 时,X Server会按照特定的规则把键码值再一次映射,映射成扫描码。当这个映射过程完成之后, X Server 把这个按键字符发送给窗口管理器(DWM,metacity, i3等等),窗口管理器再把字符发送给当前窗口。当前窗口使用有关图形API把文字打印在输入框内。

解析URL浏览器通过URL能够知道下面的信息:Protocol”http”使用HTTP协议Resource”/”请求的资源是主页(index)输入的是URL还是搜索的关键字?

当协议或主机名不合法时,浏览器会将地址栏中输入的文字传给默认的搜索引擎。大部分情况下,在把文字传递给搜索引擎的时候,URL会带有特定的一串字符,用来告诉搜索引擎这次搜索来自这个特定浏览器。

检查HSTS列表···浏览器检查自带的“预加载HSTS(HTTP严格传输安全)”列表,这个列表里包含了那些请求浏览器只使用HTTPS进行连接的网站如果网站在这个列表里,浏览器会使用HTTPS而不是HTTP协议,否则,最初的请求会使用HTTP协议发送注意,一个网站哪怕不在HSTS列表里,也可以要求浏览器对自己使用HSTS政策进行访问。浏览器向网站发出第一个HTTP请求之后,网站会返回浏览器一个响应,请求浏览器只使用HTTPS发送请求。然而,就是这第一个HTTP请求,却可能会使用户收到downgrade attack的威胁,这也是为什么现代浏览器都预置了HSTS列表。转换非ASCII的Unicode字符浏览器检查输入是否含有不是a-z,A-Z,0-9,-或者.的字符这里主机名是google.com,所以没有非ASCII的字符,如果有的话,浏览器会对主机名部分使用Punycode编码DNS查询···ARP

要想发送ARP广播,我们需要有一个目标IP地址,同时还需要知道用于发送ARP广播的接口的Mac地址。

首先查询ARP缓存,如果缓存命中,我们返回结果:目标IP = MAC

如果缓存没有命中:

ARP Request:

Sender MAC: interface:mac:address:hereSender IP: interface.ip.goes.hereTarget MAC: FF:FF:FF:FF:FF:FF (Broadcast)Target IP: target.ip.goes.here

根据连接主机和路由器的硬件类型不同,可以分为以下几种情况:

直连:

如果我们和路由器是直接连接的,路由器会返回一个ARP Reply(见下面)。

集线器:

如果我们连接到一个集线器,集线器会把ARP请求向所有其它端口广播,如果路由器也“连接”在其中,它会返回一个ARP Reply。

交换机:

ARP Reply:

1

2

3

4

Sender MAC: target:mac:address:here

Sender IP: target.ip.goes.here

Target MAC: interface:mac:address:here

Target IP: interface.ip.goes.here

天不负;卧薪尝胆,三千越甲可吞吴。

当你在浏览器中输入Google.com并且按下回车之后发生了什么?

相关文章:

你感兴趣的文章:

标签云: