社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
目录
不详细解释了,直接上代码吧。
这里我用了time函数,日志记录的时候可以打印时间。
go语言中,函数名首字母大写代表着这个函数可以在其他的包中使用,当然我这里都用的是package main,不涉及引入包。
package main
import (
"crypto/rand"
"crypto/tls"
"fmt"
"log"
"net/http"
"time"
)
//CurrentTime 当前时间,2018-12-22 14:41:21.4728403
func CurrentTime() string {
t := time.Now()
//fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 这是个奇葩,必须是这个时间点, 据说是go诞生之日, 记忆方法:6-1-2-3-4-5
cur := fmt.Sprintf("%s.%8d", time.Now().Format("2006-01-02 15:04:05"), t.Nanosecond())
return cur
}
//Logger 日志记录
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%st%st%st%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}
//cert.pem, key.unencrypted.pem
func inittls(cfg *tls.Config) {
crt, err := tls.LoadX509KeyPair("./cert/cert.pem", "./cert/key.unencrypted.pem")
if err != nil {
log.Fatalln(err.Error())
}
cfg.Time = time.Now
cfg.Rand = rand.Reader
cfg.Certificates = []tls.Certificate{crt}
}
func main() {
router := NewRouter()
sslconfig := &tls.Config{}
inittls(sslconfig)
srv := &http.Server{
Addr: ":8443",
Handler: router,
TLSConfig: sslconfig,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
}
log.Fatal(srv.ListenAndServeTLS("./cert/cert.pem", "./cert/key.unencrypted.pem"))
}
本来是想用p12证书的,但是因为go不支持,所以转成了pem证书。
可以参考https://blog.csdn.net/linsanhua/article/details/17333315,找个Linux机器操作下就可以了,很简单。
inittls是对tls的初始化,这个一定要有,不然你从客户端发过来的消息可能接收有问题,如图:
这个是我当时遇到的,加了tls的初始化就没有了。
当然如果你直接从网页上操作的话,可能就没有这个问题了。
这里设置的监听端口是8443,当然你也可以写成127.0.0.1:8443,这样也可以。
NewRouter,这个是做路由注册的,如果不注册的话,你的消息是处理不了的。
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
//Route 定义路由信息
type Route struct {
Name string
Method string
URI string
HandlerFunc http.HandlerFunc
}
//Routes 路由接口定义
type Routes []Route
var routes = Routes{
Route{
"RESTFulServerDeleteUser",
"DELETE",
"/v2/vapps/instances/{users}/vm/{username}",
RESTFulServerDeleteUser,
},
Route{
"RESTFulServerTokenLoginPorc",
"POST",
"/v3/auth/tokens",
RESTFulServerTokenLoginPorc,
},
Route{
"RESTFulServerTokenLogoutProc",
"DELETE",
"/v3/auth/tokens/{username}",
RESTFulServerTokenLogoutProc,
},
}
func resultFAIL(errcode int, reason string) []byte {
strBody := fmt.Sprintf("{"error":{"code":%d,"message":"%s"}}", errcode, reason)
fmt.Println("errorcode:", errcode, "nreason:", reason)
return []byte(strBody)
}
//NewRouter 定义接口router
func NewRouter() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
for _, route := range routes {
var handler http.Handler
handler = route.HandlerFunc
handler = Logger(handler, route.Name)
router.
Methods(route.Method).
Path(route.URI).
Name(route.Name).
Handler(route.HandlerFunc)
}
return router
}
这里我就简单的注册了一个token的注销和登录的接口,作为示范。
resultFAIL是给handler提供的接口,返回值是[]byte,我的handler用的w.Write函数,所以这个比较方便一些。
package main
import (
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
)
//RESTFulServerDeleteUserDELETE /v2/vapps/instances/{users}/vm/{username}
func RESTFulServerDeleteUser(w http.ResponseWriter, r *http.Request) {
fmt.Println()
fmt.Println(time.Now())
fmt.Println(CurrentTime(), "REMOTE:t", r.RemoteAddr)
fmt.Println(CurrentTime(), "URL:t", r.URL)
fmt.Println(CurrentTime(), "HOST:t", r.Host)
fmt.Println(CurrentTime(), "METHOD:t", r.Method)
vars := mux.Vars(r)
users:= vars["users"]
username:= vars["username"]
w.Header().Set("content-type", "application/json")
w.Header().Set("charset", "UTF-8")
w.Header().Set("transaction-id", r.Header.Get("transaction-id"))
w.Write(DeleteUserProcess(users, username))
}
//RESTFulServerTokenLoginPorc POST /v3/auth/tokens
//申请token
func RESTFulServerTokenLoginPorc(w http.ResponseWriter, r *http.Request) {
fmt.Println()
fmt.Println(time.Now())
fmt.Println(CurrentTime(), "REMOTE:t", r.RemoteAddr)
fmt.Println(CurrentTime(), "URL:t", r.URL)
fmt.Println(CurrentTime(), "HOST:t", r.Host)
fmt.Println(CurrentTime(), "METHOD:t", r.Method)
w.Header().Set("content-type", "application/json")
w.Header().Set("charset", "UTF-8")
w.Header().Set("transaction-id", r.Header.Get("transaction-id"))
w.Header().Set("X-Subject-Token", "D30947360475E6721E1C82BEA673C915")
w.Write([]byte("{"result":"OK"}"))
}
//RESTFulServerTokenLogoutProc DELETE /v3/auth/tokens/{username}
//注销token
func RESTFulServerTokenLogoutProc(w http.ResponseWriter, r *http.Request) {
fmt.Println()
fmt.Println(time.Now())
fmt.Println(CurrentTime(), "REMOTE:t", r.RemoteAddr)
fmt.Println(CurrentTime(), "URL:t", r.URL)
fmt.Println(CurrentTime(), "HOST:t", r.Host)
fmt.Println(CurrentTime(), "METHOD:t", r.Method)
r.ParseForm() //解析参数
username := r.FormValue("username")
w.Header().Set("content-type", "application/json")
w.Header().Set("charset", "UTF-8")
w.Header().Set("transaction-id", r.Header.Get("transaction-id"))
//response.AddHeader("X-Auth-Token", request.HeaderParameter("X-Auth-Token"))
strBody := fmt.Sprintf("{"username":"%s"}", username)
w.Write([]byte(strBody))
}
这里放的是3个处理函数,这三个处理函数在routers.go中都有注册,收到对应的消息后,就会调用相应的函数进行处理。
RESTFulServerDeleteUser中还调用了一个子函数,这个可以自己去实现。这里就不贴代码了。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!