http那些事

栏目: 后端 · 前端 · 发布时间: 8年前

内容简介:http那些事

简介

超文本传输协议,这决定了协议传输的内容。

如果你想了解一个http协议,就用一门语言基于socket包写一个特定的响应,然后基于浏览器访问它。

http1.1

基于node.js socket写一个简单的http server

require('net').createServer(function(sock) {
    sock.on('data', function(data) {
        sock.write('HTTP/1.1 200 OK\r\n');
        sock.write('\r\n');
        sock.write('hello world!');
        sock.destroy();
    });
}).listen(9090, '127.0.0.1');

scala版本

object SocketServer {
    def main(args: Array[String]): Unit = {
        try {
            val listener = new ServerSocket(8080);
            val socket = listener.accept()
            val data = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world!"
            socket.getOutputStream.write(data.getBytes())
            socket.close()
            listener.close()
        }
        catch {
            case e: IOException =>
                System.err.println("Could not listen on port: 80.");
                System.exit(-1)
        }
    }
}

long polling

http long-polling(推送),服务端故意不响应(一段时间),也不断连接。参见 面试时如何优雅的谈论HTTP/1.0/1.1/2.0

Content-Encoding

http协议中有 Content-Encoding(内容编码)。Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。内容编码通常是选择性的,例如 jpg / png 这类文件一般不开启,因为图片格式已经是高度压缩过的。

内容编码针对的只是传输正文。在 HTTP/1 中,头部始终是以 ASCII 文本传输,没有经过任何压缩,这个问题在 HTTP/2 中得以解决。

Transfer-Encoding

参见 HTTP 协议中的 Transfer-Encoding

Transfer-Encoding 用来改变报文格式。这涉及到一个通信协议的重要问题:如何定义协议数据的边界

  1. 发送完就断连接(非持久连接)
  2. 协议头部设定content-length
  3. 以特殊字符结尾

content-length有几个问题:

  • 发送数据时,对某些场景,计算数据长度本身是一个比较耗时的事情,同时会占用一定的memory。
  • 接收数据时,从协议头拿到数据长度,接收不够这个长度的数据,就不能解码后交给上层处理。

Transfer-Encoding 当下只有一个可选值:分块编码(chunked)。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。

require('net').createServer(function(sock) {
    sock.on('data', function(data) {
        sock.write('HTTP/1.1 200 OK\r\n');
        sock.write('Transfer-Encoding: chunked\r\n');
        sock.write('\r\n');

        sock.write('b\r\n');
        sock.write('01234567890\r\n');

        sock.write('5\r\n');
        sock.write('12345\r\n');

        sock.write('0\r\n');
        sock.write('\r\n');
    });
}).listen(9090, '127.0.0.1');

server push

服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确地请求。

http2

HTTP/2协议–特性扫盲篇

复用

复用是http2许多特性的起点,因为一个域名只可以使用一个连接,所以在连接之上提出stream的概念,一个stream一般代表一个业务。一个stream可以收发多次请求响应,每次是一个消息(消息的定义是语义上的),一个消息包括多个帧(比如header frame和data frame)。

反过来说, http作为双工通信,必须是一个“相互对应的”request和response才完整。

  1. http1.0 一个请求一个新连接,我发出的是reqeust,我收到的是response,连接关闭,response接收完毕,对应关系自然建立。但因为发送的时候不能接受数据,(服务端未收到请求,自然不知道如何响应),基本是单工通信。
  2. http1.1 多个请求复用连接,但要求server必须按照request的顺序返回response,对应关系也可以建立起来。

很明显,理想状态应该是

  1. client 按需发request,server按处理能力返回response,通过额外的手段将两者关联起来(一般通过一个id)
  2. 不必非得整收整发。此处与上文的分块传输类似,http2做的更加彻底,一个是分块可以是二进制。再则,http1.1分块只是解决了边界问题,http2则应该是在分块(frame)的粒度进行数据编解码。

至于http2的代码展示,因为在浏览器执行url前,还有一次协议协商过程(浏览器最初以http1.1协议发起请求,和server协商一致后转用http2),不好模拟,所以作罢。参见 HTTP/2协议–特性扫盲篇

https

来自《http权威指南》

对web服务器发起请求时,我们需要一种方式来告知web服务器去执行http的安全协议版本,这是通过url中设定http或https来实现的。

  1. 如果是http,客户端就会打开一条到服务器80端口的连接
  2. 如果是https,客户端就会打开一条到服务器443端口的连接,一旦建立连接,client和server就会初始化ssl layer,对加密参数进行沟通,并交换密钥。ssl握手完成之后, ssl layer初始化完成了。 剩下的就是,browser将数据从http layer发到tcp layer之前,要经过ssl layer加密。

以上所述就是小编给大家介绍的《http那些事》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Computer Age Statistical Inference

Computer Age Statistical Inference

Bradley Efron、Trevor Hastie / Cambridge University Press / 2016-7-21 / USD 74.99

The twenty-first century has seen a breathtaking expansion of statistical methodology, both in scope and in influence. 'Big data', 'data science', and 'machine learning' have become familiar terms in ......一起来看看 《Computer Age Statistical Inference》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具