更多Go内容请见: https://blog.csdn.net/weixin_39777626/article/details/85066750
net/http标准库
组成部分
构建服务器
Go Web服务器
最简单的Web服务器
package main
import (
"net/http"
)
func main() {
http.ListenAndServe("",nil)
}
附加配置的Web服务器
package main
import (
"net/http"
)
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
Handler: nil,
}
server.ListenAndServe()
}
HTTPS提供服务
- cert.pem:SSL证书
- key.pem:私钥
- SSL:(Secure Socket
Layer,安全套接字层)通过公钥基础设施为通信双方提供数据加密和身份验证的协议,后更名为TLS(Transport Layer
Security,传输层安全协议) - HTTPS:在SSL之连接上层进行HTTP通信
通过HTTPS提供服务
package main
import (
"net/http"
)
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
Handler: nil,
}
server.ListenAndServeTLS("cert.pem", "key.pem")
}
生成个人使用的SSL证书以及服务器私钥
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"time"
)
func main() {
max:=new(big.Int).Lsh(big.NewInt(1),128)
serialNumber,_:=rand.Int(rand.Reader,max)
subject:=pkix.Name{
Organization: []string{"Manning Publications Co,"},
OrganizationalUnit: []string{"Books"},
CommonName: "Go Web Programming",
}
template:=x509.Certificate{
SerialNumber: serialNumber, //证书序列号
Subject: subject, //证书标题
//证书有效期:一年
NotBefore: time.Now(),
NotAfter: time.Now().Add(365*24*time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, //X.509证书用于服务器验证操作
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, //证书只能在127.0.0.1上运行
}
//生成RSA私钥
pk,_:=rsa.GenerateKey(rand.Reader,2048)
//创建出经过DER编码格式化的字节切片
derBytes,_:=x509.CreateCertificate(rand.Reader,&template,&template,&pk.PublicKey,pk)
//将证书编码到cert.pem文件里
certOut,_:=os.Create("cert.pem")
pem.Encode(certOut,&pem.Block{Type:"CERTIFICATE",Bytes:derBytes})
certOut.Close()
//将密钥编码并保存到key.pem文件里
keyOut,_:=os.Create("key.pem")
pem.Encode(keyOut,&pem.Block{Type:"RSA PIRVATE KEY",Bytes:x509.MarshalPKCS1PrivateKey(pk)})
keyOut.Close()
}
处理器和处理函数
处理请求
DefaulltServeMux
package main
import (
"fmt"
"net/http"
)
type MyHandleer struct{}
func (h *MyHandleer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
}
func main() {
handler := MyHandleer{}
server := http.Server{
Addr: "127.0.0.1:8080",
Handler: &handler,
}
server.ListenAndServe()
}
使用多个处理器
package main
import (
"fmt"
"net/http"
)
type HelloHandleer struct{}
func (h *HelloHandleer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
type WorldHandleer struct{}
func (h *WorldHandleer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "World!")
}
func main() {
hello := HelloHandleer{}
world := WorldHandleer{}
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.Handle("/hello", &hello)
http.Handle("/world", &world)
server.ListenAndServe()
}
处理器函数
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func world(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "World!")
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", hello)
http.HandleFunc("/world", world)
server.ListenAndServe()
}
串联多个处理器和处理器函数
串联两个二处理器函数
package main
import (
"fmt"
"net/http"
"reflect"
"runtime"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func log(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
name := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
fmt.Println("Handler function called - " + name)
h(w, r)
}
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", log(hello))
server.ListenAndServe()
}
串联多个处理器
package main
import (
"fmt"
"net/http"
)
type HelloHandleer struct{}
func (h HelloHandleer) ServeHTTP (w http.ResponseWriter,r *http.Request){
fmt.Fprintf(w, "Hello!")
}
func log(h http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc (func(w http.ResponseWriter, r *http.Request){
fmt.Printf("Handler called - %T\n",h)
h.ServeHTTP (w,r)
})
}
func protect(h http.Handler) http.Handler{
return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){
h.ServeHTTP (w,r)
})
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
hello:=HelloHandleer{}
http.Handle("/hello",protect(log(hello)))
server.ListenAndServe()
}
ServeMux和DefaultServeMux
ServeMux | DefaultServeMux | |
---|---|---|
实质 | HTTP请求多路复用器 | ServeMux的一个实例 |
功能 | 接收HTTP请求并根据请求中的URL将请求重定向到正确的处理器 | 引入net/http标准库的程序都可以使用这个实例 |
使用其他多路复用器
注意:编译前,先安装git,然后在终端执行以下命令,以安装HttpRouter库
go get github.com/julienschmidt/httprouter
使用HttpRouter实现的服务器
package main
import (
"fmt"
"net/http"
"github.com/julienschmidt/httprouter"
)
func hello(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
fmt.Fprintf(w, "hello,%s!\n", p.ByName("name"))
}
func main() {
mux := httprouter.New()
mux.GET("/hello/:name", hello)
server := http.Server{
Addr: "127.0.0.1:8080",
Handler: mux,
}
server.ListenAndServe()
}
更多Go内容请见: https://blog.csdn.net/weixin_39777626/article/details/85066750