HTTP与HTTPS协议

1.HTTP协议的诞生

在计算机的发展过程中,随着计算机网络与浏览器的诞生,我们需要将服务器的内容(html文件),通过某种形式传递给客户端的浏览器,然后浏览器将html文件进行解析,然后显示给用户浏览。所以HTTP协议就是用于在浏览器与服务器之间传输数据的一种协议。

2.HTTP协议的定义

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。

HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。

HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

3.一次完整的HTTP请求过程

当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么?

过程概览

  • 1.对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址
  • 2.根据这个IP,找到对应的服务器,发起TCP的三次握手
  • 3.建立TCP连接后发起HTTP请求
  • 4.服务器响应HTTP请求,浏览器得到html代码
  • 5.浏览器解析html代码,并请求html代码中的资源(如js、css图片等)(先得到html代码,才能去找这些资源)
  • 6.浏览器对页面进行渲染呈现给用户

4.HTTP的数据格式

4.1.http请求数据格式

http request
POST /index.html HTTP/1.1   请求方法 url 协议/版本号
Host: localhost  主机地址
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: www.baidu.com
Content-Length:25
Content-Type:application/x-www-form-urlencoded
请求空行 标志着请求头结束,请求正文(请求体)的开始
username=aa&password=1234

4.1.1.请求方法与作用

  • GET请求获取由Request-URI所标识的资源,请求参数在请求行中,GET请> 求中,对URL的长度有限制,比如:IE : 2803,Firefox:65536,Chrome:8182,Safari:80000,Opera:190000
  • POST请求服务器接收在请求中封装的数据,这就克服了GET方法中的信息无法保密和数据量太小的缺点
  • HEAD请求获取由Request-URI所标识的资源的响应消息报头
  • PUT请求服务器存储一个资源,并用Request-URI作为其标识符
  • DELETE请求服务器删除由Request-URI所标识的资源
  • TRACE请求服务器返回请求信息,主要用于测试或诊断
  • CONNECT保留将来使用
  • OPTIONS请求查询服务器的性能,或者查询与资源相关的选项和需求

4.1.2.请求头的解析

Transport 头域

  • Connect:表示是否需要持久连接
  • Host:请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的

Client 头域

  • Accept:浏览器可以接受的媒体类型(MIME类型)
  • Accept-Encoding:浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码)
  • Accept-Language:申明浏览器接受的语言,比如big5,gb2312,gbk
  • User-Agent:告诉服务器,客户端使用的操作系统和浏览器版本
  • Accept-Charset:浏览器申明自己接收的字符集,比如:gb2312,utf-8

Cookie/Login头域

  • Cookie:最重要的header, 将cookie的值发送给HTTP 服务器

Entity头域

  • Content-Length:发送给HTTP服务器数据的长度
  • Content-Type:发送信息至服务器时的内容编码类型,例如:Content-Type: application/x-www-form-urlencoded

Miscellaneous 头域

  • Referer: 提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我主页上链接到一个朋友那里, 他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问

Cache 头域

  • If-Modified-Since: 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中
  • If-None-Match: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag. 使用这样的机制将提高网站的性能
  • Pragma:防止页面被缓存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样
  • Cache-Control: 这个是非常重要的规则。 这个用来指定Response-Request遵循的缓存机制。各个指令含义如下
    Cache-Control:Public 可以被任何缓存所缓存
    Cache-Control:Private 内容只缓存到私有缓存中
    Cache-Control:no-cache 所有内容都不会被缓存

4.2.http响应数据格式

http response
HTTP/1.1 200 OK
Date: Sun, 17 Mar 2013 08:12:54 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
<html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>

4.2.1.http响应数据格式的解析

状态行,通常由3位数字组成,表示请求是否被理解或被满足

  • 1xx:指示信息——表示请求已经接受,继续处理
  • 2xx:成功——表示请求已经被成功接收、理解、接受。
  • 3xx:重定向——要完成请求必须进行更进一步的操作
  • 4xx:客户端错误——请求有语法错误或请求无法实现
  • 5xx:服务器端错误——服务器未能实现合法的请求

响应正文,也就是我们的html文件的内容

<html> 
  <head> 
    <title><title> 
  </head> 
  <body></body> 
</html>  

响应头信息

Cache头域

  • Date:生成消息的具体时间和日期,即当前的GMT时间,例如: Date: Sun, 17 Mar 2013 08:12:54 GMT
  • Expires:浏览器会在指定过期时间内使用本地缓存,指明应该在什么时候认为文档已经过期,从而不再缓存它,例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT
  • Vary: Vary: Accept-Encoding

Cookie/Login域

  • P3P: 用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题,例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
  • Set-Cookie:非常重要的header,用于把cookie 发送到客户端浏览器, 每一个写入cookie都会生成一个Set-Cookie,例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

Entity实体头域:实体内容的属性,包括实体信息类型,长度,压缩方法,最后一次修改时间,数据有效性等

  • ETag:和If-None-Match 配合使用
  • Last-Modified:用于指示资源的最后修改日期和时间
  • Content-Type:WEB服务器告诉浏览器自己响应的对象的类型和字符集,
  • Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示
  • Content-Encoding:文档的编码(Encode)方法。一般是压缩方式。WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。利用gzip压缩文档能够显著地减少HTML文档的下载时间
  • Content-Language: WEB服务器告诉浏览器自己响应的对象的语言者

Miscellaneous 头域

  • Server:指明HTTP服务器的软件信息,例如:Apache/2.2.8 (Win32)
  • X-Powered-By:表示网站是用什么技术开发的,例如: X-Powered-By: PHP/5.2.5

Transport头域

  • Connect:表示是否需要持久连接
  • Location:用于重定向一个新的位置, 包含新的URL地址

5.无状态连接

无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。

HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。

Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间

6.HTTP协议与七层网络模型

网络模型

7.HTTP协议的监听

在浏览器,我们使用chrome提供的工具,可以查看到http请求,以及某个具体请求传输的数据,以及服务端响应的内容,如下图所示


http_chrome.jpg

在服务器端,我们可以使用wireshark工具进行监听,如下所示


image.png

8.常用的HTTP服务器

  • httpd Apache
  • nginx
  • lightttpd

9.HTTP版本

HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。

HTTP/1.0
请求行必须在尾部添加协议版本字段(http/1.0);必须包含头消息

在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。

再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

HTTP/1.1
1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求;

客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接

HTTP/2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题(HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级);HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。

10.URI与URL的区别

URI
每一个人都有自己的名字,有了名字,你才能找到别人,别人也才能找到你,这是社会中人与人通信的基本要求。因此,在任何一种通讯网络里,用户也都有其独特的用户标识,比如固定网络里的固定电话号码、移动网络里的移动电话号码等等,这样才能区分出不同的用户并进行通信。而URI(Uniform Resource Identifier,统一资源标识符)就是在IMS网络中IMS用户的“名字”,也就是IMS用户的身份标识。

URL
URL是在网络上定位资源的最普遍使用的方式,它提供了一种通过描述其网络位置或主要访问机制来检索物理位置的表示的方法。URL中描述了协议,该URL用于检索资源和资源名称

URL

URI与URL的关系

uri and url

11.HTTPS

前面介绍了HTTP协议,该协议采用的是不加密传输方式,那么就会有一个致命的缺点,就是会容易出现信息的泄露、信息篡改。比如在一些关键系统上,数据的安全行、保密性要求高,那么使用HTTP协议来传输,就不能满足传输的要求,这时候就诞生了HTTPS。

https=http+ssl,顾名思义,https是在http的基础上加上了SSL保护壳,信息的加密过程就是在SSL中完成的

11.2.对称加密

对称加密算法

但是服务器会同时为多个客户进行服务,如果服务器仅仅使用同一个秘钥来进行对称加密,那么就是去了加密的意义了,所以服务器需要针对每个客户,使用不同的秘钥来进行加密,如下图所示


encode

在这里面,我们虽然针对每个客户都采用了不同的秘钥进行加密,但是服务器和客户端在传递秘钥时,使用的是明文传输,信息还是有可能泄露。

如何对协商过程进行加密

加密协商秘钥的过程

在密码学跟对称加密一起出现的,应用最广的加密机制“非对称加密”,如上图,特点是私钥加密后的密文,只要是公钥,都可以解密,但是反过来公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有的人。
基于上述的特点,我们可以得出如下结论:

  • 公钥是开放给所有人的,但私钥是需要保密的,存在于服务端
  • 服务器端server向client端(A、B.....)的信息传输是不安全的:因为所有人都可以获取公钥
  • 但client端(A、B.....)向server端的信息传输确实安全的:因为私钥只有server端存在

信息通信采用http是不安全的,存在信息劫持篡改的风险,https是加密传输,是安全的通信,对于https加密的过程,我们首先介绍的对称加密,采用对称加密进行通信存在秘钥协商过程的不安全性,因此我们采用了非对称加密算法解决了对协商过程的加密,因此https是集对称加密和非对称加密为一体的加密过程

如何安全的获得公钥

获取公钥

client获取公钥最最直接的方法是服务器端server将公钥发送给每一个client用户,但这个时候就出现了公钥被劫持的问题,如上图,client请求公钥,在请求返回的过程中被×××劫持,那么我们将采用劫持后的假秘钥进行通信,则后续的通讯过程都是采用假秘钥进行,数据库的风险仍然存在。在获取公钥的过程中,我们又引出了一个新的话题:如何安全的获取公钥,并确保公钥的获取是安全的, 那就需要用到终极武器了:SSL 证书(需要购买)和CA机构


ssl and ca

如上图所示,在第 ② 步时服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有证书的颁发机构、有效期、公钥、证书持有者、签名,通过第三方的校验保证了身份的合法,解决了公钥获取的安全性

以浏览器为例说明如下整个的校验过程:
(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比
(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充
(7)此时浏览器就可以读取证书中的公钥,用于后续加密了

11.3.HTTPS的优势

网站使用HTTPS的原因有很多:

  • HTTPS有助于在服务器和浏览器之间建立安全通信
  • 它可以保护网站免受篡改或窃听
  • 它可以保护用户免受中间人攻击
  • 各大主流浏览器纷纷要求网站从HTTP升级HTTPS访问
  • 它广泛地被银行、医疗、电子商务、社交媒体和政府等行业使用

11.4.SSL

Secure Socket Layer,为Netscape所研发,用以保障在Internet上数据传输的安全,利用数据加密(Encryption)技术,可确保数据在网络上的传输过程中不会被截取及窃听。一般通用的规格为40 bit的安全标准,美国则已推出128 bit的更高安全标准,但限制出境。只要3.0版本以上的I.E.或Netscape浏览器即可支持SSL。

当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

服务器认证阶段
1)客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器
4)服务器回复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器

用户认证阶段
在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证

SSL的会话状态
会话(Session)和连接(Connection)是SSL中两个重要的概念,在规范中定义如下

  • SSL连接:用于提供某种类型的服务数据的传输,是一种点对点的关系。一般来说,连接的维持时间比较短暂,并且每个连接一定与某一个会话相关联。
  • SSL会话:是指客户和服务器之间的一个关联关系。会话通过握手协议来创建。它定义了一组安全参数

一次会话过程通常会发起多个SSL连接来完成任务,例如一次网站的访问可能需要多个HTTP/SSL/TCP连接来下载其中的多个页面,这些连接共享会话定义的安全参数。这种共享方式可以避免为每个SSL连接单独进行安全参数的协商,而只需在会话建立时进行一次协商,提高了效率

每一个会话(或连接)都存在一组与之相对应的状态,会话(或连接)的状态表现为一组与其相关的参数集合,最主要的内容是与会话(或连接)相关的安全参数的集合,用会话(或连接)中的加密解密、认证等安全功能的实现。在SSL通信过程中,通信算法的状态通过SSL握手协议实现同步

根据SSL协议的约定,会话状态由以下参数来定义:

  • 会话标识符:是由服务器选择的任意字节序列,用于标识活动的会话或可恢复的会话状态
  • 对方的证书:会话对方的X.509v3证书。该参数可为空
  • 压缩算法:在加密之前用来压缩数据的算法
  • 加密规约(Cipher Spec):用于说明对大块数据进行加密采用的算法,以及计算MAC所采用的散列算法
  • 主密值:一个48字节长的秘密值,由客户和服务器共享
  • 可重新开始的标识:用于指示会话是否可以用于初始化新的连接

连接状态由以下参数来定义:

  • 服务器和客户器的随机数:是服务器和客户为每个连接选择的用于标识连接的字节序列
  • 服务器写MAC密值:服务器发送数据时,生成MAC使用的密钥,长度为128 bit
  • 客户写MAC密值,服务器发送数据时,用于数据加密的密钥,长度为128 bit
  • 客户写密钥:客户发送数据时,用于数据加密的密钥,长度为128 bit
  • 初始化向量:当使用CBC模式的分组密文算法是=时,需要为每个密钥维护初始化向量
  • 序列号:通信的每一端都为每个连接中的发送和接收报文维持着一个序列号

11.5.CA认证

证书颁发机构(CA, Certificate Authority)即颁发数字证书的机构。是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。

11.6.HTTPS常用服务器

  • Tomcat 5.x
  • Nginx
  • IIS
  • Apache 2.x
  • IBM HTTP SERVER 6.0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容