读《图解HTTP》

博客 动态
0 189
羽尘
羽尘 2023-05-07 01:54:50
悬赏:0 积分 收藏

读《图解HTTP》

最近读了一本书《图解HTTP》,读完后在大体上对HTTP协议有了更深层次的了解。以下是我以前不懂的问题,通过阅读此书后,这些问题都有了答案:

问题:

  • URI和URL的区别?

  • cookie到底是什么?有什么用?为什么要有?

  • 为什么下载时可以随时停止,随时继续下载?

  • 什么是内容协商机制?

  • Http协议中响应头的vary字段到底是什么意思?

  • 最近读了一本书《图解HTTP》,读完后在大体上对HTTP协议有了更深层次的了解。以下是我以前不懂的问题,通过阅读此书后,这些问题都有了答案:

    问题:

    • URI和URL的区别?
    • cookie到底是什么?有什么用?为什么要有?
    • 为什么下载时可以随时停止,随时继续下载?
    • 什么是内容协商机制?
    • Http协议中响应头的vary字段到底是什么意思?
    • Cookie的path属性和domain属性究竟是什么?
    • 为什么要有HTTPS?它与HTTP的区别在哪?
    • 什么是SSL和TSL?
    • HTTPS的混合加密机制+证书是怎样的?
    • 什么是WebSocket?为什么要有WebSocket?
    • 什么是XSS攻击、CSRF攻击?

    以下是我对问题的理解以及总结上了其他人的理解。


    问题:URI和URL的区别?

    首先要明确一点,在网络上的所有资源都需要被定位,且它们都会有名称。这样才能按需获取这些资源。

    URI就是这些资源的名称。而URL就是这些资源的位置。但有时候资源的名称中如果包含了位置,那么此时URI就和URL一样了。

    因此可以看出URL是URI的子集,当URI中包含了资源位置,那URI就等同于URL。


    问题:cookie到底是什么?有什么用?为什么要有?

    HTTP协议是无状态协议,也就是说协议不会去保存用户的状态。那么在这个情况下假设Web网站是需要登陆的,而进行页面跳转之后,用户的状态也就消失了。需要重新登陆一次,去获取用户状态。即进行一次页面跳转,就要登陆一次。这样是很繁琐的。

    要解决这种问题,就是把用户状态进行保存,而用户状态保存到Web服务器也是不现实的,因为当出现很多个用户状态时会对Web服务器造成存储上的负担。所以用户状态必须保存到客户端上。因为客户端和服务器的关系是一对多。每个客户端只需要保存一个份用户状态,这样就能提高Web服务器的存储性能。

    所以有了Cookie。使用Cookie,可以把用户状态存储到客户端上,客户端每次向服务器发送请求时都会带上Cookie,因此在服务器上只需要对这个Cookie的内容进行校验即可。

    Cookie通常会搭配Session一起使用,可以维持客户端与服务器之间的通信。只需要把SessionID通过Cookie发送给客户端,然后客户端每次请求服务器时,都通过Cookie把SessionID发给服务器,服务器对SeesionId进行校验,这样就能维持客户端和服务器之间的通信了。


    问题:为什么下载时可以随时停止,随时继续下载?

    首先,资源在服务器上是以字节来进行存储的。本质上一份资源就是多个0和1的组合。因此下载资源也就是复制这一份0和1的组合。

    所以下载时停止了,那么也就是往客户端的磁盘上写这个01组合的动作被停止了。如果此时想要继续下载,就必须得知道这个01组合写到哪了,客户端需要从哪开始继续写01组合,也就是说客户端必须要告诉服务器一个范围。从这个范围开始继续把资源复制给客户端。

    因此有了range字段,客户端在发送请求时,往请求头上设置range字段,就能设置这个范围。


    问题:什么是内容协商机制?

    在单机情况下,一份资源通常只会有一个版本。但是对于一个多语言应用程序,可能需要为每种语言版本单独创建一个文件,这些文件可能会被分别存储在单机中的不同位置上,这样在使用时可以根据用户选择的语言版本来读取相应的文件。因此,可以说在单机情况下,一份多语言资源可能会有多个语言版本。

    而在分布式系统中,同一份资源的不同版本可能存储在不同的服务器上,由不同的服务器提供服务。这些服务器之间可以通过负载均衡或者其他技术来实现对用户请求的处理。因此,不同国家的用户请求的资源版本可能来自不同的服务器。

    无论在单机情况下还是分布式系统中都存在一个问题: 客户端怎么决定要使用哪一个版本的资源呢?

    HTTP的内容协商机制很好的解决了这问题。内容协商机制是指:某一资源,服务器有多个版本,客户端告知服务器自己的偏好,服务器根据偏好选择合适的版本响应客户端的请求。

    在内容协商机制中有以下三种方法来决定使用哪个版本资源:

    • 客户端驱动协商(让客户端来选择): 客户端发起请求,服务器发送资源的可选项列表,客户端作出选择后再发送第二次请求。
    • 服务器驱动协商(让服务器来选择): 客户端发送请求时把需要哪个版本的资源通过请求头发送给服务器,让服务器来决定使用哪个版本的资源。
    • 透明协商(让中间代理来选择): 使用某个中间设备(通常是缓存代理)来代表客户端进行协商,可以说是客户端驱动协商的变种。

    问题:Http协议中响应头的vary字段到底是什么意思?

    假设整个请求过程是这样的:客户端 -> 代理服务器(具备缓存功能) ->web服务器。

    第一个支持gzip压缩的客户端向中间代理服务器发送请求,代理服务器转发该请求,向web服务器拉取内容,拿到内容后代理服务器缓存该内容(由于请求首部有Accept-Encoding: gzip 所以内容会被压缩)。

    第二个不支持gzip压缩的客户端也向中间代理服务器发送同一个请求,代理服务器发现该请求已经被缓存了,于是就把压缩后的内容响应给该客户端。悲剧了,因为该客户端根本不支持gzip压缩,也就没法解压。

    这种问题出现在透明协商机制中。问题的根源就在于代理把同一份资源响应给了不同的客户端,而客户端对份资源是有不同版本的要求的。

    为了解决这个问题,于是有了vary字段,vary字段用于列出一个响应字段列表,告诉缓存服务器遇到同一个 URL 对应着不同版本文档的情况时,如何缓存和筛选合适的版本。

    有了vary字段之后,代理缓存可以为通过单个URL访问的文档保存不同的副本。如果服务器把它们的决策过程传给缓存,这些代理就能代表服务器与客户端进行协商。缓存同时也是进行内容转码的好地方,因为部署在缓存里的通用转码器能对任意服务器,而不仅仅是一台服务器传来的内容进行转码。

    更加详细的介绍可以看这篇文章:https://codeleading.com/article/90534722641/


    问题:Cookie的path属性和domain属性究竟是什么?

    cookie一定会随着客户端发送的请求而到达服务器。而服务器上可能会出现多个域名的情况(服务器有多个域名的情况通常是因为同一个应用程序需要提供不同的服务或接口)。那么就有个问题: cookie一定要被服务器的所有域名识别吗?我想让某些域名不能识别这个cookie那怎么办?

    于是有了domain属性,domain属性用于用于指定哪些域名可以接受该Cookie。具体来说,如果设置了该属性,则只有在该属性值所指定的域名及其子域名下发送请求时,浏览器才会将该Cookie发送给服务器。

    举个例子,假设我们有一个名为“example.com”的域名,并且在其上设置了一个Cookie,domain属性值为“example.com”。此时,无论是在"ohj.example.com"子域名下,还是在“blog.example.com”子域名下,当浏览器发送请求时,都会将该Cookie附加在请求头中发送给服务器。但如果发送请求的域名为“test.com”,则浏览器不会发送该Cookie。

    需要注意的是,domain属性的值必须是当前域名或其子域名,否则浏览器不会发送该Cookie。同时,该属性值不能包含协议名和端口号。

    现在Cookie发送到服务器的指定域名了,但是又有一个问题: 这个域名上的所有路径都要使用这个cookie吗?某些路径不想使用怎么办?
    于是有了path属性,使用path属性可以指定Cookie可以被哪些路径使用。

    举个例子,cookie的path属性的值为/head,那么路径为/head/ohj/、/head/xxx/都能使用到这个cookie,而/abc/test/路径都不能使用到这个cookie。

    即cookie只会发往path属性指定的路径。只有path属性的路径与请求URL路径一致时,cookie才会发送给服务器。

    总结: domain属性用于控制cookie能够发送给哪些域名,path属性用于控制cookie在服务器上哪些路径可以访问。


    问题:为什么要有HTTPS?它与HTTP的区别在哪?

    首先,HTTP协议是存在安全隐患的,HTTP传输内容时,都是明文传输,存在被窃听风险。而HTTP的内容也有可能被修改。

    于是有了HTTPS,HTTP+加密+认证+完整性保护=HTTPS。因此使用HTTPS能够防止窃听和篡改的风险。


    问题:什么是SSL和TSL?

    SSL(安全套接层)和TSL(传输层安全协议)是用于保护网络通信安全的协议,TLS是SSL的继任者。它们的作用是在应用层和传输层之间提供一层安全协议,保护通信过程中的机密性、完整性和可靠性。


    问题:HTTPS的混合加密机制+证书是怎样的?

    先了解一下共享密钥加密和公开密钥加密。

    共享密钥加密: 使用一对完全一样的公钥来对数据进行加密解密,因此称为共享密钥加密。假设有个服务器A,服务器A用公钥加密内容,然后发送给服务器B,服务器B用另一把相同的公钥进行解密。

    公开密钥加密: 使用一个非对称的公钥来对数据进行加密解密,一个密钥叫公开密钥,用于到处分享;一个密钥叫私有密钥,用于解密数据,不会到处分享。假设有个服务A,它先把公开密钥发给服务器B,然后服务器B用公开密钥加密内容,然后发送给服务器A,服务器A用私有密钥进行解密。

    在HTTPS协议中使用的是混合密钥加密,也就是把共享密钥加密和公开密钥加密结合结合在一起。

    • 公开密钥加密通常只用于在建立连接时对客户端和服务器之间的通信进行加密。(也就是用公开密钥加密来确保共享密钥能够安全传输到客户端。)
    • 共享密钥对后续的请求和响应进行加密和解密,这种方式也被称为对称密钥加密。

    到此,有个问题:客户端怎么知道这个公开密钥就是服务器发来的呢?

    为了解决这个问题,必须依赖第三方机构,于是有了证书。使用证书,可以确保这个公开密钥就是服务器发来的。

    在我的理解中使用HTTPS的客户端和服务器之间是这样从连接-通信的:

    1. 服务器先把自己的公开密钥在数字证书认证机构中登记,然后获取公钥证书。
    2. 服务器把认证过的公开密钥和证书发给客户端
    3. 客户端使用浏览器内置的数据证书认证机构的公开密钥对证书进行认证,认证通过后证明确实是服务器的公开密钥。
    4. 客户端用这个公开密钥对客户端生成的共享密钥进行加密,然后发送给服务器。
    5. 服务器用自己的私有密钥进行解密,得到客户端发送的共享密钥。
    6. 之后服务器和客户端的通信就只用共享密钥进行加密。

    问题:什么是WebSocket?为什么要有WebSocket?

    在HTTP协议中有以下缺点:

    • 一次连接只能发送一个请求。
    • 请求只能从客户端开始。客户端不可以接受除响应意外的指令,也就是服务器不能主动发送响应到客户端。
    • 每次请求都会传输完整的请求头,且请求头都没有压缩过,请求头信息越多延迟越大。

    为了弥补HTTP的缺点,于是有了WebSocket。WebSocket是一种在单个TCP连接上提供全双工通信的协议,通过这种协议,Web应用程序可以建立与服务器的持久性连接,实现实时通信和数据传输。

    WebSocket协议是在HTTP协议的基础上进行升级得到的。在初始连接建立时,客户端会发送一份HTTP协议的请求,该请求中包含升级为WebSocket协议的要求。如果服务器同意升级,则接下来的通信将采用WebSocket协议进行,这时候HTTP协议就不再使用了。因此,WebSocket协议也被称为HTTP协议的升级版或扩展版。


    问题:什么是XSS攻击、CSRF攻击?

    XSS(跨站脚本攻击):攻击者通过注入恶意脚本代码到受害者访问的网页上,从而获取受害者的敏感信息或者执行恶意操作的一种攻击方式。XSS攻击分为存储型、反射型和DOM型三种形式。 XSS攻击的共同点为:将一些隐私数据像 cookie、session 发送给攻击者,将受害者重定向到一个由攻击者控制的网站,在受害者的机器上进行一些恶意操作。

    CSRF(跨站请求伪造):攻击者通过伪造合法的请求来欺骗用户执行操作的一种攻击方式。攻击者可以利用用户已经登录的身份,向服务器发送请求来执行一些恶意操作。例如,攻击者可以通过伪造提交表单的请求来更改受害者的账户信息。CSRF攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。

  • Cookie的path属性和domain属性究竟是什么?

  • 为什么要有HTTPS?它与HTTP的区别在哪?

  • 什么是SSL和TSL?

  • HTTPS的混合加密机制+证书是怎样的?

  • 什么是WebSocket?为什么要有WebSocket?

  • 什么是XSS攻击、CSRF攻击?

以下是我对问题的理解以及总结上了其他人的理解。


问题:URI和URL的区别?

首先要明确一点,在网络上的所有资源都需要被定位,且它们都会有名称。这样才能按需获取这些资源。

URI就是这些资源的名称。而URL就是这些资源的位置。但有时候资源的名称中如果包含了位置,那么此时URI就和URL一样了。

因此可以看出URL是URI的子集,当URI中包含了资源位置,那URI就等同于URL。


问题:cookie到底是什么?有什么用?为什么要有?

HTTP协议是无状态协议,也就是说协议不会去保存用户的状态。那么在这个情况下假设Web网站是需要登陆的,而进行页面跳转之后,用户的状态也就消失了。需要重新登陆一次,去获取用户状态。即进行一次页面跳转,就要登陆一次。这样是很繁琐的。

要解决这种问题,就是把用户状态进行保存,而用户状态保存到Web服务器也是不现实的,因为当出现很多个用户状态时会对Web服务器造成存储上的负担。所以用户状态必须保存到客户端上。因为客户端和服务器的关系是一对多。每个客户端只需要保存一个份用户状态,这样就能提高Web服务器的存储性能。

所以有了Cookie。使用Cookie,可以把用户状态存储到客户端上,客户端每次向服务器发送请求时都会带上Cookie,因此在服务器上只需要对这个Cookie的内容进行校验即可。

Cookie通常会搭配Session一起使用,可以维持客户端与服务器之间的通信。只需要把SessionID通过Cookie发送给客户端,然后客户端每次请求服务器时,都通过Cookie把SessionID发给服务器,服务器对SeesionId进行校验,这样就能维持客户端和服务器之间的通信了。


问题:为什么下载时可以随时停止,随时继续下载?

首先,资源在服务器上是以字节来进行存储的。本质上一份资源就是多个0和1的组合。因此下载资源也就是复制这一份0和1的组合。

所以下载时停止了,那么也就是往客户端的磁盘上写这个01组合的动作被停止了。如果此时想要继续下载,就必须得知道这个01组合写到哪了,客户端需要从哪开始继续写01组合,也就是说客户端必须要告诉服务器一个范围。从这个范围开始继续把资源复制给客户端。

因此有了range字段,客户端在发送请求时,往请求头上设置range字段,就能设置这个范围。


问题:什么是内容协商机制?

在单机情况下,一份资源通常只会有一个版本。但是对于一个多语言应用程序,可能需要为每种语言版本单独创建一个文件,这些文件可能会被分别存储在单机中的不同位置上,这样在使用时可以根据用户选择的语言版本来读取相应的文件。因此,可以说在单机情况下,一份多语言资源可能会有多个语言版本。

而在分布式系统中,同一份资源的不同版本可能存储在不同的服务器上,由不同的服务器提供服务。这些服务器之间可以通过负载均衡或者其他技术来实现对用户请求的处理。因此,不同国家的用户请求的资源版本可能来自不同的服务器。

无论在单机情况下还是分布式系统中都存在一个问题: 客户端怎么决定要使用哪一个版本的资源呢?

HTTP的内容协商机制很好的解决了这问题。内容协商机制是指:某一资源,服务器有多个版本,客户端告知服务器自己的偏好,服务器根据偏好选择合适的版本响应客户端的请求。

在内容协商机制中有以下三种方法来决定使用哪个版本资源:

  • 客户端驱动协商(让客户端来选择): 客户端发起请求,服务器发送资源的可选项列表,客户端作出选择后再发送第二次请求。
  • 服务器驱动协商(让服务器来选择): 客户端发送请求时把需要哪个版本的资源通过请求头发送给服务器,让服务器来决定使用哪个版本的资源。
  • 透明协商(让中间代理来选择): 使用某个中间设备(通常是缓存代理)来代表客户端进行协商,可以说是客户端驱动协商的变种。

问题:Http协议中响应头的vary字段到底是什么意思?

假设整个请求过程是这样的:客户端 -> 代理服务器(具备缓存功能) ->web服务器。

第一个支持gzip压缩的客户端向中间代理服务器发送请求,代理服务器转发该请求,向web服务器拉取内容,拿到内容后代理服务器缓存该内容(由于请求首部有Accept-Encoding: gzip 所以内容会被压缩)。

第二个不支持gzip压缩的客户端也向中间代理服务器发送同一个请求,代理服务器发现该请求已经被缓存了,于是就把压缩后的内容响应给该客户端。悲剧了,因为该客户端根本不支持gzip压缩,也就没法解压。

这种问题出现在透明协商机制中。问题的根源就在于代理把同一份资源响应给了不同的客户端,而客户端对份资源是有不同版本的要求的。

为了解决这个问题,于是有了vary字段,vary字段用于列出一个响应字段列表,告诉缓存服务器遇到同一个 URL 对应着不同版本文档的情况时,如何缓存和筛选合适的版本。

有了vary字段之后,代理缓存可以为通过单个URL访问的文档保存不同的副本。如果服务器把它们的决策过程传给缓存,这些代理就能代表服务器与客户端进行协商。缓存同时也是进行内容转码的好地方,因为部署在缓存里的通用转码器能对任意服务器,而不仅仅是一台服务器传来的内容进行转码。


问题:Cookie的path属性和domain属性究竟是什么?

cookie一定会随着客户端发送的请求而到达服务器。而服务器上可能会出现多个域名的情况(服务器有多个域名的情况通常是因为同一个应用程序需要提供不同的服务或接口)。那么就有个问题: cookie一定要被服务器的所有域名识别吗?我想让某些域名不能识别这个cookie那怎么办?

于是有了domain属性,domain属性用于用于指定哪些域名可以接受该Cookie。具体来说,如果设置了该属性,则只有在该属性值所指定的域名及其子域名下发送请求时,浏览器才会将该Cookie发送给服务器。

举个例子,假设我们有一个名为“example.com”的域名,并且在其上设置了一个Cookie,domain属性值为“example.com”。此时,无论是在"ohj.example.com"子域名下,还是在“blog.example.com”子域名下,当浏览器发送请求时,都会将该Cookie附加在请求头中发送给服务器。但如果发送请求的域名为“test.com”,则浏览器不会发送该Cookie。

需要注意的是,domain属性的值必须是当前域名或其子域名,否则浏览器不会发送该Cookie。同时,该属性值不能包含协议名和端口号。

现在Cookie发送到服务器的指定域名了,但是又有一个问题: 这个域名上的所有路径都要使用这个cookie吗?某些路径不想使用怎么办?
于是有了path属性,使用path属性可以指定Cookie可以被哪些路径使用。

举个例子,cookie的path属性的值为/head,那么路径为/head/ohj/、/head/xxx/都能使用到这个cookie,而/abc/test/路径都不能使用到这个cookie。

即cookie只会发往path属性指定的路径。只有path属性的路径与请求URL路径一致时,cookie才会发送给服务器。

总结: domain属性用于控制cookie能够发送给哪些域名,path属性用于控制cookie在服务器上哪些路径可以访问。


问题:为什么要有HTTPS?它与HTTP的区别在哪?

首先,HTTP协议是存在安全隐患的,HTTP传输内容时,都是明文传输,存在被窃听风险。而HTTP的内容也有可能被修改。

于是有了HTTPS,HTTP+加密+认证+完整性保护=HTTPS。因此使用HTTPS能够防止窃听和篡改的风险。


问题:什么是SSL和TSL?

SSL(安全套接层)和TSL(传输层安全协议)是用于保护网络通信安全的协议,TLS是SSL的继任者。它们的作用是在应用层和传输层之间提供一层安全协议,保护通信过程中的机密性、完整性和可靠性。


问题:HTTPS的混合加密机制+证书是怎样的?

先了解一下共享密钥加密和公开密钥加密。

共享密钥加密: 使用一对完全一样的公钥来对数据进行加密解密,因此称为共享密钥加密。假设有个服务器A,服务器A用公钥加密内容,然后发送给服务器B,服务器B用另一把相同的公钥进行解密。

公开密钥加密: 使用一个非对称的公钥来对数据进行加密解密,一个密钥叫公开密钥,用于到处分享;一个密钥叫私有密钥,用于解密数据,不会到处分享。假设有个服务A,它先把公开密钥发给服务器B,然后服务器B用公开密钥加密内容,然后发送给服务器A,服务器A用私有密钥进行解密。

在HTTPS协议中使用的是混合密钥加密,也就是把共享密钥加密和公开密钥加密结合结合在一起。

  • 公开密钥加密通常只用于在建立连接时对客户端和服务器之间的通信进行加密。(也就是用公开密钥加密来确保共享密钥能够安全传输到客户端。)
  • 共享密钥对后续的请求和响应进行加密和解密,这种方式也被称为对称密钥加密。

到此,有个问题:客户端怎么知道这个公开密钥就是服务器发来的呢?

为了解决这个问题,必须依赖第三方机构,于是有了证书。使用证书,可以确保这个公开密钥就是服务器发来的。

在我的理解中使用HTTPS的客户端和服务器之间是这样从连接-通信的:

  1. 服务器先把自己的公开密钥在数字证书认证机构中登记,然后获取公钥证书。
  2. 服务器把认证过的公开密钥和证书发给客户端
  3. 客户端使用浏览器内置的数据证书认证机构的公开密钥对证书进行认证,认证通过后证明确实是服务器的公开密钥。
  4. 客户端用这个公开密钥对客户端生成的共享密钥进行加密,然后发送给服务器。
  5. 服务器用自己的私有密钥进行解密,得到客户端发送的共享密钥。
  6. 之后服务器和客户端的通信就只用共享密钥进行加密。

问题:什么是WebSocket?为什么要有WebSocket?

在HTTP协议中有以下缺点:

  • 一次连接只能发送一个请求。
  • 请求只能从客户端开始。客户端不可以接受除响应意外的指令,也就是服务器不能主动发送响应到客户端。
  • 每次请求都会传输完整的请求头,且请求头都没有压缩过,请求头信息越多延迟越大。

为了弥补HTTP的缺点,于是有了WebSocket。WebSocket是一种在单个TCP连接上提供全双工通信的协议,通过这种协议,Web应用程序可以建立与服务器的持久性连接,实现实时通信和数据传输。

WebSocket协议是在HTTP协议的基础上进行升级得到的。在初始连接建立时,客户端会发送一份HTTP协议的请求,该请求中包含升级为WebSocket协议的要求。如果服务器同意升级,则接下来的通信将采用WebSocket协议进行,这时候HTTP协议就不再使用了。因此,WebSocket协议也被称为HTTP协议的升级版或扩展版。


问题:什么是XSS攻击、CSRF攻击?

XSS(跨站脚本攻击):攻击者通过注入恶意脚本代码到受害者访问的网页上,从而获取受害者的敏感信息或者执行恶意操作的一种攻击方式。XSS攻击分为存储型、反射型和DOM型三种形式。 XSS攻击的共同点为:将一些隐私数据像 cookie、session 发送给攻击者,将受害者重定向到一个由攻击者控制的网站,在受害者的机器上进行一些恶意操作。

CSRF(跨站请求伪造):攻击者通过伪造合法的请求来欺骗用户执行操作的一种攻击方式。攻击者可以利用用户已经登录的身份,向服务器发送请求来执行一些恶意操作。例如,攻击者可以通过伪造提交表单的请求来更改受害者的账户信息。CSRF攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。

posted @ 2023-05-07 01:07  Hipop  阅读(0)  评论(0编辑  收藏  举报
回帖
    羽尘

    羽尘 (王者 段位)

    2233 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员