golang 用golang处理Github webhooks

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 用golang处理Github webhooks相关的知识,希望对你有一定的参考价值。

// Now available in package form at https://github.com/rjz/githubhook

package handler

// https://developer.github.com/webhooks/
import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

// Replace with your hook's secret
const secret = "shhhhh!!"

func signBody(secret, body []byte) []byte {
	computed := hmac.New(sha1.New, secret)
	computed.Write(body)
	return []byte(computed.Sum(nil))
}

func verifySignature(secret []byte, signature string, body []byte) bool {

	const signaturePrefix = "sha1="
	const signatureLength = 45 // len(SignaturePrefix) + len(hex(sha1))

	if len(signature) != signatureLength || !strings.HasPrefix(signature, signaturePrefix) {
		return false
	}

	actual := make([]byte, 20)
	hex.Decode(actual, []byte(signature[5:]))

	return hmac.Equal(signBody(secret, body), actual)
}

type HookContext struct {
	Signature string
	Event     string
	Id        string
	Payload   []byte
}

func ParseHook(secret []byte, req *http.Request) (*HookContext, error) {
	hc := HookContext{}

	if hc.Signature = req.Header.Get("x-hub-signature"); len(hc.Signature) == 0 {
		return nil, errors.New("No signature!")
	}

	if hc.Event = req.Header.Get("x-github-event"); len(hc.Event) == 0 {
		return nil, errors.New("No event!")
	}

	if hc.Id = req.Header.Get("x-github-delivery"); len(hc.Id) == 0 {
		return nil, errors.New("No event Id!")
	}

	body, err := ioutil.ReadAll(req.Body)

	if err != nil {
		return nil, err
	}

	if !verifySignature(secret, hc.Signature, body) {
		return nil, errors.New("Invalid signature")
	}

	hc.Payload = body

	return &hc, nil
}

func Handler(w http.ResponseWriter, r *http.Request) {

	hc, err := ParseHook([]byte(secret), r)

	w.Header().Set("Content-type", "application/json")

	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		log.Printf("Failed processing hook! ('%s')", err)
		io.WriteString(w, "{}")
		return
	}

	log.Printf("Received %s", hc.Event)

  // parse `hc.Payload` or do additional processing here

	w.WriteHeader(http.StatusOK)
	io.WriteString(w, "{}")
	return
}

golang UTF8转中文字符

参考技术A

golang 读取文件的时候( ReadFile func(filename string) ([]byte, error) ),返回的是utf-8格式的[]byte,对于中文字符来讲,无法将[]byte直接转化为string。所以需要手动将 UIF-8 转换成 GBK

GitHub上的项目 https://github.com/axgle/mahonia 可以解决编码转换的问题。

win下和linux下.txt文件的格式不同,因为DOS下的编辑器和Linux编辑器对文件行末的回车符处理不一致
mahonia解析win下的文本文件,所以要把win下的文本文件放到linux服务器环境中。

以上是关于golang 用golang处理Github webhooks的主要内容,如果未能解决你的问题,请参考以下文章

golang处理json

Go 每日一库之 go-carbon,优雅的golang日期时间处理库

json库在golang中的使用

用golang 实现一个代理池

Golang操作mysqlx库处理MySQL数据库

golang rbac框架