0%

【windows技术】go的http服务器响应实现

go实现服务器响应客户端操作

利用go实现服务器响应客户端各种操作

前期调研

在go开发官方文档https://pkg.go.dev/net/http发现了针对http服务器响应和对http客户端对服务器请求的说明,本文参考此说明开始编写。

go服务器响应

ListenAndServe starts an HTTP server with a given address and handler. The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux:

1
2
3
4
5
6
7
http.Handle("/foo", fooHandler)

http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})

log.Fatal(http.ListenAndServe(":8080", nil))

开发文档意思是在http服务器添加handle来响应客户端不同请求操作即可,事例函数中有两个参数需要注意:

ResponseWriter 是处理器用来创建 HTTP 响应的接口,其源码结构如下所示:

1
2
3
4
5
6
7
8
type ResponseWriter interface {
// 用于设置/获取所有响应头信息
Header() Header
// 用于写入数据到响应实体
Write([]byte) (int, error)
// 用于设置响应状态码
WriteHeader(statusCode int)
}

Request是用来解析请求头和请求体,其源码结构如下:

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
type Request struct {
//指定请求内容例如DELETE,POST,GET
Method string
//指定要请求的 URI(对于服务器请求)或要访问的 URL(用于客户请求
URL *url.URL
//服务器协议版本
Proto string // "HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
//包含服务端收到或者由客户端发送的 HTTP 请求头
Header Header

Body io.ReadCloser

GetBody func() (io.ReadCloser, error)

ContentLength int64

TransferEncoding []string

Close bool

Host string

Form url.Values

PostForm url.Values

MultipartForm *multipart.Form

Trailer Header

RemoteAddr string

RequestURI string

TLS *tls.ConnectionState

Cancel <-chan struct{}

Response *Response

ctx context.Context
}

这边主要使用的就是request结构体前几个对象就可以实现了,具体的其他对象详细说明可以看下request.go源码

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

package main

import (
"net/http"
"fmt"
"os"
)

func main() {
mux := http.NewServeMux()
fs := http.FileServer(http.Dir("/home/mecry/tmp/"))
mux.Handle("/", delete("/home/mecry/tmp/", fs))
http.ListenAndServe("localhost:8888", mux)
}

func delete (dirprefix string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "DELETE" {
path := dirprefix+r.URL.String()
fmt.Println("delete path:", path)
os.Remove(path)
return
}
next.ServeHTTP(w, r)
})
}