net-http

上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 获取form文件
file, err := c.FormFile("attachment")
if err != nil {
return nil, GenError(err)
}
now := time.Now()
// 检查目录
dir := fmt.Sprintf("upload/%d%d", now.Year(), now.Month())
if !utils.Exists(dir) {
err = os.MkdirAll(dir, os.ModePerm)
if err != nil {
return nil, GenError(err)
}
}
// 创建文件
path := fmt.Sprintf("%s/%d%s", dir, now.Unix()%(3600*24*30), file.Filename)
out, err := os.Create(path)
if err != nil {
return nil, GenError(err)
}
f, err := file.Open()
if err != nil {
return nil, GenError(err)
}
_, err = io.Copy(out, f)
if err != nil {
return nil, GenError(err)
}

下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
file, err := os.Open(attachment.Path)
if err != nil {
OnError(c, err)
return
}
defer file.Close()

// 读取文件头信息
fileHeader := make([]byte, 512)
file.Read(fileHeader)
fileContentType := http.DetectContentType(fileHeader)
fileStat, _ := file.Stat()
fileSize := strconv.FormatInt(fileStat.Size(), 10)

// 设置response header头,gin框架也可以用c.Header("","")
c.Writer.Header().Set("Content-Disposition", "attachment; filename="+attachment.Name)
c.Writer.Header().Set("Content-Type", fileContentType)
c.Writer.Header().Set("Content-Length", fileSize)

// 注意还原io读取指针
file.Seek(0, 0)
_, err = io.Copy(c.Writer, file)
if err != nil {
OnError(c, err)
return
}

通过默认的net/http服务

1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
http.HandleFunc("/", HelloWorld)
errpr := http.ListenAndServe(":8080", nil)
if errpr != nil {
log.Fatal("listen falded")
}
}

// 由于http.ResponseWriter只是一个接口,所以不需要引用传值
// 而http.Request是一个数据(结构类型),所以需要引用传值
func HelloWorld(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello world")
}

重写ServeHTTP方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type MyHandler struct {}
func main() {
mux := http.NewServeMux()
mux.Handle("/", &MyHandler{})
mux.HandleFunc("/home", Home)
err := http.ListenAndServe(":8080", mux)
if err != nil {
log.Fatal("listen falded")
}
}

func (this *MyHandler)ServeHTTP(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello world " + r.URL.Path)
}

func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "home " + r.URL.Path)
}

重写http.Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 定义全局变量
var mux map[string]func(http.ResponseWriter, *http.Request)
type MyHandler struct{}

func main() {
server := http.Server{
Addr: ":8080",
// 定义server的默认handler
Handler: &MyHandler{},
ReadTimeout: 2 * time.Second,
}
// 对全局变量赋值
mux = make(map[string]func(http.ResponseWriter, *http.Request))
mux["/home"] = Home
mux["/user"] = User
err := server.ListenAndServe()
if err != nil {
log.Fatal("listen faild")
}

}
// handler默认执行的方法
func (*MyHandler)ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 根据map转发路由
if v, ok := mux[r.URL.String()]; ok {
v(w, r)
return
}
io.WriteString(w, "hello world " + r.URL.Path)
}

func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "home " + r.URL.Path)
}

func User(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "user " + r.URL.Path)
}

原生中间件编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import (
"net/http"
"fmt"
)

type SingleMiddle struct {
handler http.Handler
allowHost []string
}

type myHandler struct{}

func main() {
var allowHosts []string
allowHosts = append(allowHosts, "localhost:8080")
MyHandler := &myHandler{}
singleHost := NewSingle(MyHandler, allowHosts)
http.ListenAndServe(":8080", singleHost)
}

// middleware
func NewSingle(handler http.Handler, allowHost []string) (*SingleMiddle) {
return &SingleMiddle{handler, allowHost}
}
// middleware
func (s *SingleMiddle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
isIn := false
fmt.Println(s.allowHost)
fmt.Println(host)
for _, allowH := range s.allowHost {
if allowH == host {
isIn = true
}
}
if isIn {
s.handler.ServeHTTP(w, r)
} else {
w.WriteHeader(403)
}
}
// custom handler
func (m *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("helle golang"))
}