Golang 原生实现 HTTPS POST json 请求

https 证书

使用 openssl 来生成私人证书

# 生成客户端私钥 (生成CA私钥)
openssl genrsa -out ca.key 2048 
# 生成CA证书
openssl req -x509 -new -nodes -key ca.key -subj "/CN=tonybai.com" -days 5000 -out ca.crt

# 生成服务端私钥
openssl genrsa -out server.key 2048
# 生成证书请求文件
openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
# 根据CA的私钥和上面的证书请求文件生成服务端证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000

https server

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
)

type RequestBody struct {
	Arr []string `json:"arr"`
}

func postHandler(w http.ResponseWriter, r *http.Request)  {
	defer r.Body.Close()

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Fatal("read request error")
	}

	fmt.Println("response Body:", string(body))
	var req RequestBody
	if err := json.Unmarshal(body, &req); err != nil {
		log.Fatal("unmarshal request error")
	}
	fmt.Println(req.Arr)

	retJson,_ := json.Marshal(req.Arr)
	io.WriteString(w, string(retJson))
}

func indexHandler(w http.ResponseWriter, r *http.Request)  {
	fmt.Println("indexHandler")
	fmt.Fprintf(w, "welcome https")
}

func main()  {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/post", postHandler)
	http.ListenAndServeTLS(":8080", "server.crt", "server.key", nil)
}

https client

package main

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)


func httpsPost(addr string, json []byte, contentType string)  {
	// CertPool 代表一个证书集合/证书池。
	// 创建一个 CertPool
	pool := x509.NewCertPool()
	caCertPath := "ca.crt"
	// 调用 ca.crt 文件
	caCrt, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	// 解析证书
	pool.AppendCertsFromPEM(caCrt)
	tr := &http.Transport{
		// 把从服务器传过来的非叶子证书,添加到中间证书的池中,使用设置的根证书和中间证书对叶子证书进行验证。
		TLSClientConfig: &tls.Config{RootCAs: pool},
		// 客户端跳过对证书的校验
		//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Post(addr, contentType, bytes.NewBuffer(json))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	fmt.Println("response Status:", resp.Status)
	fmt.Println("response Headers:", resp.Header)
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	fmt.Println("response Body:", string(body))
}

type requestBody struct {
	Arr []string `json:"arr"`
}

func main()  {
	request := &requestBody{Arr: []string{"123", "345", "23456"}}
	addr := "https://localhost:8080/post"
	marshal, err := json.Marshal(request)
	if err != nil {
		log.Fatalf("marshal error %v", request)
	}
	contentType := "application/json"

	httpsPost(addr, marshal, contentType)
}

参考文章:golang 的http/https server与client

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值