go 进阶 https与http2

2023-11-10

一. 复习 https 与 http2

https 是什么

  1. 什么是HTTPS: 安全的超文本传输协议,可以看为HTTP的加强安全版本,HTTPS 是基于 HTTP 的,也是用 TCP 作为底层协议,并额外使用 SSL/TLS 协议用作加密和安全认证,可以理解成HTTPS = HTTP + SSL/TLS。默认端口号是 443
  2. 什么是SSL/TLS协议: SSL 指安全套接字协议,核心要素是非对称加密(非对称加密采用公钥,私钥,在通信时,通过公钥加密,通过私钥解密)

优点: 算法公开,加密和解密使用不同的钥匙,私钥不需要通过网络进行传输,安全性很高。
缺点: 计算量比较大,加密和解密速度相比对称加密慢很多

https 原理是什么

  1. HTTPS 协议就是基于 SSL 的 HTTP 协议,HTTPS 使用与 HTTP 不同的端口(HTTP80 ,HTTPS443)提供了身份验证与加密通信方法,被广泛用于互联网上安全敏感的通信
  1. 客户端发送HTTPS请求,请求 SSL 连接
  2. 采用 HTTPS 协议的服务器必须先申请CA (Certification Authority)证书,颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存不可泄漏,公钥则是附带在证书的信息中,可以公开的,证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被篡改。
  3. 服务器接收到请求后将自身份信息以证书形式发回给客户端,证书包含了网站地址,加密公钥,以及证书的颁发机构等信息
  4. 客户端接收到响应的证书信息进行校验, 如果证书不是可信机构颁布,或者证书中的域名与实际域名不一致,或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
  5. 如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥A,然后客户端还会生成一个随机码 KEY,并使用公钥A将其加密。
  6. 客户端把加密后的随机码 KEY 发送给服务器,作为后面对称加密的密钥。
  7. 服务器在收到随机码 KEY 之后会使用私钥B将其解密,经过以上这些步骤,客户端和服务器终于建立了安全连接,解决了对称加密的密钥泄露问题,接下来就可以进行通信了

http 与https的区别

  1. https是http协议的安全版本,采用SSL/TLS协议进行加密传输
  2. http默认使用80端口, https默认使用443端口
  3. 建立连接层面: https因为多了一次TSL加解密的握手校验,没有http性能高
  4. 在资源消耗与处理上由于多了加解密,比http要慢
  5. http运行在TCP协议上,https运行在SSL协议上,而SSL实际也是运行在TCP协议上的

http2 与http1.x区别

  1. 以前默认使用http1.x进行通信,后续可能要升级为http2,与http1.x不同是
  1. http1.x 基于文本进行解析,文本的表现形式有多样性,需要考虑多种场景必,http2基于二进制格式解析只认 0 和 1 的组合,实现方便且健壮
  2. http2支持多路复用,即连接共享,多个请求可以同时在一个连接上并行执行(一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面), 而http1.1的长连是串行化执行多个请求,而且并发请求的数量比http1.1大了好几个数量级。
  3. 首部压缩: http1.1不支持header数据压缩,http2.0使用 HPACK 算法对 header 的数据进行压缩,数据体积小,传输快
  4. 服务器推送: 在客户端请求之前发送数据的机制,在 http2中,服务器可以对客户端的一个请求发送多个响应
  1. 注意点使用http2必须启用https(浏览器强制要求)

二. golang https http2 基础示例

  1. 创建一个假的证书与私钥
  1. 创建ca私钥: “openssl genrsa -out ca.key 2048”
  2. 创建ca证书: “openssl req -x509 -new -nodes -key ca.key -subj “/CN=example1.com” -days 5000 -out ca.crt”
  3. 创建服务器私钥(默认由CA签发): openssl genrsa -out server.key 2048
  4. 基于服务器私钥创建服务器证书前面请求(简称csr, example1.com代表你的域名): openssl req -new -key server.key -subj “/CN=example1.com” -out server.csr
  5. 基于上面生成的两个文件加上ca证书生成服务器证书(days代表有效期): openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
  1. 例如此处执行完毕创建了相关证书,其中server.crt是服务器证书,server.key是服务器秘钥
    在这里插入图片描述
  2. 编写读取证书文件代码,也就是上方的testdata.go中
package testdata

import (
	"path/filepath"
	"runtime"
)

// basepath is the root directory of this package.
var basepath string

func init() {
	_, currentFile, _, _ := runtime.Caller(0)
	basepath = filepath.Dir(currentFile)
}

// Path returns the absolute path the given relative file or directory path,
// relative to the google.golang.org/grpc/testdata directory in the user's GOPATH.
// If rel is already absolute, it is returned unmodified.
func Path(rel string) string {
	if filepath.IsAbs(rel) {
		return rel
	}

	return filepath.Join(basepath, rel)
}
  1. 编写服务接口
import (
	"fmt"
	"github.com/e421083458/gateway_demo/demo/proxy/reverse_proxy_https/testdata"
	"golang.org/x/net/http2"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

//1.编写启动服务上下文结构体
type RealServer struct {
	Addr string
}

//2.编写启动服务Run方法
func (r *RealServer) Run() {
	log.Println("Starting httpserver at " + r.Addr)
	//1.创建路由器
	mux := http.NewServeMux()
	//2.注册路由
	mux.HandleFunc("/", r.HelloHandler)
	mux.HandleFunc("/base/error", r.ErrorHandler)
	//3.封装server
	server := &http.Server{
		Addr:         "127.0.0.1:3003",
		WriteTimeout: time.Second * 3,
		Handler:      mux,
	}

	//4.监听地址启动服务
	go func() {
		//4.1重点:配置http升级为http2
		http2.ConfigureServer(server, &http2.Server{})
		//4.2读取服务器证书
		serverCrt := testdata.Path("server.crt")
		//4.3读取服务器私钥
		serverKey := testdata.Path("server.key")

		//4.4调用http.Server的ListenAndServeTLS()方法,传入证书与私钥,设置当前服务支持https
		log.Fatal(server.ListenAndServeTLS(serverCrt, serverKey))
	}()
}

//3.编写路由接口
func (r *RealServer) HelloHandler(w http.ResponseWriter, req *http.Request) {
	upath := fmt.Sprintf("http://%s%s\n", r.Addr, req.URL.Path)
	io.WriteString(w, upath)
}

func (r *RealServer) ErrorHandler(w http.ResponseWriter, req *http.Request) {
	upath := "error handler"
	w.WriteHeader(500)
	io.WriteString(w, upath)
}

//4.main方法启动服务
func main() {
	rs1 := &RealServer{Addr: "127.0.0.1:3003"}
	//启动服务业务函数执行
	rs1.Run()
	//监听关闭信号
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
}

httputil.ReverseProxy 代理到https

  1. 封装httputil.ReverseProxy时,设置支持https,然后通过httputil.ReverseProxy将请求代理到目标服务器
import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"github.com/e421083458/gateway_demo/demo/proxy/reverse_proxy_https/testdata"
	"golang.org/x/net/http2"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"
)

// 1.创建连接池(在连接池中设置ca证书)
var transport = &http.Transport{
	DialContext: (&net.Dialer{
		Timeout:   30 * time.Second, //连接超时
		KeepAlive: 30 * time.Second, //长连接超时时间
	}).DialContext,
	//是否开启tls验证如果开启,下方就要设置ca证书(如果不需要tls可以注释掉,并且也不需要ca证书)
	TLSClientConfig:       &tls.Config{InsecureSkipVerify: true},
	TLSClientConfig: func() *tls.Config {
		//读取ca证书
		caCertPath := testdata.Path("ca.crt")
		caCrt, _ := ioutil.ReadFile(caCertPath)
		pool := x509.NewCertPool()
		pool.AppendCertsFromPEM(caCrt)
		return &tls.Config{RootCAs: pool}
	}(),
	MaxIdleConns:          100,              //最大空闲连接
	IdleConnTimeout:       90 * time.Second, //空闲超时时间
	TLSHandshakeTimeout:   10 * time.Second, //tls握手超时时间
	ExpectContinueTimeout: 1 * time.Second,  //100-continue 超时时间
}

// 获取httputil.ReverseProxy,通过httputil.ReverseProxy进行代理,将请求转发到目标服务
func NewMultipleHostsReverseProxy(targets []*url.URL) *httputil.ReverseProxy {
	//请求协调者
	director := func(req *http.Request) {
		//目标地址
		targetIndex := rand.Intn(len(targets))
		target := targets[targetIndex]
		targetQuery := target.RawQuery
		fmt.Println("target.Scheme")
		fmt.Println(target.Scheme)
		req.URL.Scheme = target.Scheme
		req.URL.Host = target.Host
		req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
		if targetQuery == "" || req.URL.RawQuery == "" {
			req.URL.RawQuery = targetQuery + req.URL.RawQuery
		} else {
			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
		}
		if _, ok := req.Header["User-Agent"]; !ok {
			req.Header.Set("User-Agent", "user-agent")
		}
	}
	//调用http2.ConfigureTransport()配置http升级为http2,传递设置了ca证书的连接池
	http2.ConfigureTransport(transport)
	return &httputil.ReverseProxy{Director: director, Transport: transport}
}

func singleJoiningSlash(a, b string) string {
	aslash := strings.HasSuffix(a, "/")
	bslash := strings.HasPrefix(b, "/")
	switch {
	case aslash && bslash:
		return a + b[1:]
	case !aslash && !bslash:
		return a + "/" + b
	}
	return a + b
}
  1. main方法启动服务,注意也要设置支持http2
import (
	"github.com/e421083458/gateway_demo/demo/proxy/reverse_proxy_https/testdata"
	"golang.org/x/net/http2"
	"log"
	"net/http"
	"net/url"
	"time"
)

var addr = "example1.com:3002"

func main() {
	//1.目标服务地址
	rs1 := "https://example1.com:3003"
	url1, err1 := url.Parse(rs1)
	if err1 != nil {
		log.Println(err1)
	}
	urls := []*url.URL{url1}

	//2.获取代理httputil.ReverseProxy
	proxy := NewMultipleHostsReverseProxy(urls)
	log.Println("Starting httpserver at " + addr)

	//2.创建路由器
	mux := http.NewServeMux()

	//4.注册路由,通过httputil.ReverseProxy进行代理
	mux.Handle("/", proxy)
	//5.设置server
	server := &http.Server{
		Addr:         addr,
		WriteTimeout: time.Second * 3, //设置3秒的写超时
		Handler:      mux,
	}
	//6.设置支持http2
	http2.ConfigureServer(server, &http2.Server{})
	//7.读取证书,秘钥,监听指定端口开启服务
	log.Fatal(server.ListenAndServeTLS(testdata.Path("server.crt"), testdata.Path("server.key")))
	log.Fatal(server.ListenAndServe())
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go 进阶 https与http2 的相关文章

随机推荐

  • 【Maven】Maven slf4j-api 出现 NoClassDefFoundError:org/slf4j/event/LoggingEvent

    1 背景 程序偶然报错这个 然后我查找了一下 发现这个包是1 7 7版本的 然后我想知道那个版本加入了这个东东 于是去查了一下 可以发现 在1 7 14版本之前都没有和这个包 1 7 14之后就全都有了 换个版本就好了
  • 【速度收藏】20个常用的Python技巧,太赞啦

    Python的可读性和简单性是其广受欢迎的两大原因 本文介绍20个常用的Python技巧来提高代码的可读性 并能帮助你节省大量时间 下面的技巧将在你的日常编码练习中非常实用 1 字符串反转 使用Python切片反转字符串 Reversing
  • 02-express安装apidoc生成接口文档

    02 express安装apidoc生成接口文档 1 安装 npm i apidoc 2 在项目根目录下创建 apidoc json name news是项目接口文档 version 0 1 0 description 新闻接口文档 tit
  • SpringCloud之Feign传递Json参数(个人使用)

    SpringCloud之Feign传递Json参数 个人使用 Client端 启动类 SpringBootApplication EnableDiscoveryClient EnableFeignClientspublic class Fe
  • 条款11:优先选用删除函数,而非private 未定义函数

    使用场景 比如在自定义类中 为了阻止其他程序员使用 拷贝构造 等函数 我们常用的用法 将该函数定义为private 不去定义只是声明 或者delete 区别 区别一 delete 可以修饰任何函数 private 只能修饰类 类对象 的成员
  • myeclipse java错误提示_myeclipse常见错误集锦 及解决方案

    1 An internal error occurred during Add Deployment Container with path org eclipse jdt launching JRE CONTAINER org eclip
  • vcxsrv连linux黑屏,通过 VcXsrv 在 WSL2 上使用图形化界面(xfce4)

    当然网络上已经有很多相关教程了 但是对于我的情况那些方法都不完全正确以至于我不能使用图形化界面 所以如果你查了很多方法也不能使用的话可以看看这篇 这是我的系统参数 开门见山 启动 VcXsrv 在 Windows 上下载 VcXsrv 并安
  • 词向量实践(gensim)

    词向量训练步骤 分词并去停用词 词频过滤 训练 项目完整地址 https github com cyandn practice tree master Word2Vec gensim中Word2Vec参数解释 主要参数介绍如下 senten
  • 基于Matlab的变压器铁芯截面优化设计

    基于Matlab的变压器铁芯截面优化设计 前言 优化思路 Matlab程序运行结果 结果分析 代码 前言 变压器是电力系统中非常重要的设备 在变压器设计过程中 给定的铁心直径条件下 铁心截面积越大 填充率越高 变压器经济指标越好 因此铁心截
  • WIN10 编译ffmpeg(包含ffplay)

    1 安装MSYS2 Win10 搭建MSYS2环境 cloud yq的博客 CSDN博客 2 编译SDL SDL是编译生成ffplay的基础 不需要生成ffplay可不编译SDL 1 下载地址 https www libsdl org do
  • Mall谷粒商城(基础篇的开发)

    项目简介 Mall商城项目致力于打造一个完整的大型分布式架构的电商平台 采用先阶段流行的前后端分离模式编写 Mall商城是一套电商项目 包括前台的商城系统以及后台管理系统 基于SpringCloud SpringCloud Alibaba
  • 基于51单片机的HX711模块

    一 项目介绍 基于51单片机的HX711称重计 最大称重量为5kg 并且在LCD1602上显示数值 可设置称重物品单价 称重精度可由按键key调节 误差可达0 传感器在某宝上买的 需要可以找我拿连接 二 HX711简介 HX711是一款专为
  • Database returned an invalid datetime value. Are time zone definitions for your database installed?

    Django gt python manage py runserver时报错 Database returned an invalid datetime value Are time zone definitions for your d
  • GCC编译选项参数介绍

    gcc和g 分别是gnu的c和c 编译器 下面是整理的常用编译选项参数 1 x 设定文件所使用的语言 使文件后缀名无效 如下 执行完后生成test o gcc c x c test jpg 2 c 只编译生成目标文件即 o 只编译不链接生成
  • Spring Boot通过lombok提供的Slf4j省略日志的创建操作

    上文 Spring Boot将声明日志步骤抽离出来做一个复用类中 我们写了个创建日志的公开类 但这么简单的东西 自然有人会将它写好 lombok已经 提供出了这个工具 首先 我们需要在 pom xml 中加上这样一段代码
  • NB-IOT/Lora/Zigbee/WIFI/蓝牙无线组网方式的对比

    NB IOT Lora Zigbee WIFI 蓝牙无线组网方式的对比 LoRa LoRa 长 距离 是由Semtech公司开发的一种技术 典型工作频率在美国是915MHz 在欧洲是868MHz 在亚洲是433MHz LoRa的物理层 PH
  • 互联网摸鱼日报(2023-09-12)

    互联网摸鱼日报 2023 09 12 36氪新闻 东方树叶 被中年男人买疯了 马斯克重申 特斯拉将取消 实体后视镜 一封钓鱼电邮背后的AI攻防战 苹果iPhone 15系列预测分析 哪些靠谱 该选哪个版本 纯电版丰田埃尔法 难以重现燃油版的
  • PMOS 型的 LDO

    在前面讲 NMOS LDO 的时候 我们注意到 NMOS 由于它的源极和门级之间的导通门限 使 简单构成的 NMOS LDO 它输入和输出之间的压差不可能很小 必须大于这个导通门限 如果 我们引入一个单个的偏置电压对某些应用又是一个负担 因
  • Ag-grid表格 原生javascript的简单使用

    ag grid是支持多种前端框架的企业级表格框架 它能实现的功能也颇多 有兴趣的可以上他的官网api看下ag Grid官网 我这里简单写一下基础的数据初始化生成表格 1 首先引入js文件 我这里用原生的方式 并没有使用vue之类的框架的方法
  • go 进阶 https与http2

    目录 一 复习 https 与 http2 https 是什么 https 原理是什么 http 与https的区别 http2 与http1 x区别 二 golang https http2 基础示例 httputil ReversePr