前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang实现http2.0服务端,客户端完整案例

golang实现http2.0服务端,客户端完整案例

作者头像
公众号-利志分享
发布2022-04-25 09:41:05
4.7K0
发布2022-04-25 09:41:05
举报
文章被收录于专栏:利志分享

为了学习golang的client源码执行流程,所以笔者通过golang实现http2的服务端和客户端,然后通过单步调试学习源码。下面我们看下整个golang实现http2的服务步骤。

1 生成公钥私钥文件

代码语言:javascript
复制
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 365 -out certificate.pem

private.pem:服务端私钥

certificate.pem:证书文件

2 实现server端代码如下

代码语言:javascript
复制
package main

import (
    "fmt"
    "golang.org/x/net/http2"
    "golang.org/x/net/http2/h2c"
    "log"
    "net/http"
    "os"
)

func main() {
    path, _ := os.Getwd()
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello world")
        fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
    })
    h2s := &http2.Server{
        // ...
    }
    h1s := &http.Server{
        Addr:    ":8080",
        Handler: h2c.NewHandler(handler, h2s),
    }
    log.Fatal(h1s.ListenAndServeTLS(path+"\\certificate.pem", path+"\\private.pem"))
}

3 实现客户端代码如下

代码语言:javascript
复制
package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "golang.org/x/net/http2"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "time"
)

var url = "https://localhost:8080"

func main() {
    request2()
}

func request2() {
    path, _ := os.Getwd()
    client := &http.Client{
        Timeout: 100 * time.Millisecond,
    }
    //读取证书文件,正式环境无读取证书文件,因为本地测试是无法认证证书
    caCert, err := ioutil.ReadFile(path + "\\http_connect\\certificate.pem")
    if err != nil {
        log.Fatalf("Reading server certificate: %s", err)
        return
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    //tls协议配置,InsecureSkipVerify认证证书是否跳过
    tlsConfig := &tls.Config{
        RootCAs: caCertPool,
        //设置安全跳跃认证
        InsecureSkipVerify: true,
    }
    client.Transport = &http2.Transport{
        TLSClientConfig: tlsConfig,
    }
    resp, err := client.Get(url)
    if err != nil {
        fmt.Printf("Failed get: err:%s \n", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("Failed reading response body: %s\n", err)
        return
    }
    fmt.Printf("Get request2 response %d: %s %s\n", resp.StatusCode, resp.Proto, string(body))
}

//http1请求
func request1() {
    //http1
    _, err := http.Get(url)
    fmt.Println(err)
}

//http11请求
func request11() {
    path, _ := os.Getwd()
    client := &http.Client{}
    //证书文件
    caCert, err := ioutil.ReadFile(path + "\\certificate.pem")
    if err != nil {
        log.Fatalf("Reading server certificate: %s", err)
        return
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    // Create TLS configuration with the certificate of the server
    tlsConfig := &tls.Config{
        RootCAs: caCertPool,
        //设置安全跳跃认证
        InsecureSkipVerify: true,
    }
    client.Transport = &http.Transport{
        TLSClientConfig: tlsConfig,
    }
    resp, err := client.Get(url)
    if err != nil {
        log.Fatalf("Failed get: %s", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalf("Failed reading response body: %s", err)
        return
    }
    fmt.Printf("Got response %d: %s %s\n", resp.StatusCode, resp.Proto, string(body))
}

问题总结:

报错:

代码语言:javascript
复制
 x509: certificate is not valid for any names, but wanted to match localhost

是http2请求安全认证不过,通过设置如下参数来实现:

代码语言:javascript
复制
//设置安全跳跃认证
InsecureSkipVerify: true,
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 利志分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档