-
Notifications
You must be signed in to change notification settings - Fork 0
/
response_writer.go
137 lines (116 loc) · 2.88 KB
/
response_writer.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//This software is licensed under the MIT License.
//You can get more info in license file.
package smile
import (
"bufio"
"compress/gzip"
"io"
"net"
"net/http"
)
const (
defaultDataSize = 0
defaultStatus = 200
)
//ResponseWriter 定义一个writer接口
//该接口可用于http、weibsocket的响应操作
type ResponseWriter interface {
http.ResponseWriter
http.Hijacker
http.Flusher
DataSize() int
Status() int
WriteString(string) (int, error)
Done()
}
//实现一个ResoponsWriter接口
type responseWriter struct {
http.ResponseWriter
io.Writer
gz bool //是否开启gz
status int //响应状态
size int //响应字节长度
written bool
}
//初始化http.ResponseWriter 响应状态 响应数据长度
func (w *responseWriter) Init(writer http.ResponseWriter) {
w.size = defaultDataSize
w.status = defaultStatus
w.ResponseWriter = writer
w.written = false
}
//开启gz开关
//注册一个新的 *gzip.Writer
//对于本次请求响应将进行gzip压缩
func (w *responseWriter) GzOn(gz *gzip.Writer) {
w.Writer = gz
w.gz = true
}
//获取响应数据字节长度
func (w *responseWriter) DataSize() int {
return w.size
}
//获取响应状态
func (w *responseWriter) Status() int {
return w.status
}
//写入响应状态到header
func (w *responseWriter) WriteHeader(code int) {
if code != w.status && code > 0 {
w.status = code
}
}
//判断是否已经设置过响应状态
func (w *responseWriter) isWritten() bool {
return w.written
}
//如果在响应头没有设置的情况下
//立即写入状态至响应头
//并将writer的数据重置
func (w *responseWriter) WriteHeaderAtOnce() {
if !w.isWritten() {
w.written = true
w.ResponseWriter.WriteHeader(w.status)
}
}
func (w *responseWriter) Gz() bool {
return w.gz
}
//响应结构的写方法
//如果本次请求为gzip压缩
//则使用注册为*gzip.Writer的io.writer进行写操作
//否则是用http.ResponseWriter进行写操作
func (w *responseWriter) Write(data []byte) (n int, err error) {
w.WriteHeaderAtOnce()
if w.gz {
n, err = w.Writer.Write(data)
} else {
n, err = w.ResponseWriter.Write(data)
}
w.size += n
return
}
//Done 向请求中写入空字节 以结束请求
//用来执行跳转 或者单纯的header设置
func (w *responseWriter) Done() {
w.size = 0
_,_ = w.Write([]byte(""))
}
//直接写入字符串
func (w *responseWriter) WriteString(data string) (n int, err error) {
n,_= w.Write([]byte(data))
w.size += n
return
}
//继承http.Hijacker的Hijack()方法
func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return w.ResponseWriter.(http.Hijacker).Hijack()
}
//继承http.flusher的Flush()方法
func (w *responseWriter) Flush() {
w.ResponseWriter.(http.Flusher).Flush()
}
//继承http.CloseNotifier的CloseNotify()方法
func (w *responseWriter) CloseNotify() <-chan bool {
return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
}