github.com/zhongdalu/gf@v1.0.0/g/net/ghttp/ghttp_response.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 // 7 8 package ghttp 9 10 import ( 11 "bytes" 12 "fmt" 13 "net/http" 14 "strconv" 15 16 "github.com/zhongdalu/gf/g/encoding/gparser" 17 "github.com/zhongdalu/gf/g/os/gfile" 18 "github.com/zhongdalu/gf/g/util/gconv" 19 ) 20 21 // 服务端请求返回对象。 22 // 注意该对象并没有实现http.ResponseWriter接口,而是依靠ghttp.ResponseWriter实现。 23 type Response struct { 24 ResponseWriter 25 Server *Server // 所属Web Server 26 Writer *ResponseWriter // ResponseWriter的别名 27 request *Request // 关联的Request请求对象 28 } 29 30 // 创建一个ghttp.Response对象指针 31 func newResponse(s *Server, w http.ResponseWriter) *Response { 32 r := &Response{ 33 Server: s, 34 ResponseWriter: ResponseWriter{ 35 ResponseWriter: w, 36 buffer: bytes.NewBuffer(nil), 37 }, 38 } 39 r.Writer = &r.ResponseWriter 40 return r 41 } 42 43 // 返回信息,任何变量自动转换为bytes 44 func (r *Response) Write(content ...interface{}) { 45 if len(content) == 0 { 46 return 47 } 48 for _, v := range content { 49 switch value := v.(type) { 50 case []byte: 51 r.buffer.Write(value) 52 case string: 53 r.buffer.WriteString(value) 54 default: 55 r.buffer.WriteString(gconv.String(v)) 56 } 57 } 58 } 59 60 // 返回信息,支持自定义format格式 61 func (r *Response) Writef(format string, params ...interface{}) { 62 r.Write(fmt.Sprintf(format, params...)) 63 } 64 65 // 返回信息,末尾增加换行标识符"\n" 66 func (r *Response) Writeln(content ...interface{}) { 67 if len(content) == 0 { 68 r.Write("\n") 69 return 70 } 71 content = append(content, "\n") 72 r.Write(content...) 73 } 74 75 // 返回信息,末尾增加换行标识符"\n" 76 func (r *Response) Writefln(format string, params ...interface{}) { 77 r.Writeln(fmt.Sprintf(format, params...)) 78 } 79 80 // 返回JSON 81 func (r *Response) WriteJson(content interface{}) error { 82 if b, err := gparser.VarToJson(content); err != nil { 83 return err 84 } else { 85 r.Header().Set("Content-Type", "application/json") 86 r.Write(b) 87 } 88 return nil 89 } 90 91 // 返回JSONP 92 func (r *Response) WriteJsonP(content interface{}) error { 93 if b, err := gparser.VarToJson(content); err != nil { 94 return err 95 } else { 96 //r.Header().Set("Content-Type", "application/json") 97 if callback := r.request.Get("callback"); callback != "" { 98 buffer := []byte(callback) 99 buffer = append(buffer, byte('(')) 100 buffer = append(buffer, b...) 101 buffer = append(buffer, byte(')')) 102 r.Write(buffer) 103 } else { 104 r.Write(b) 105 } 106 } 107 return nil 108 } 109 110 // 返回XML 111 func (r *Response) WriteXml(content interface{}, rootTag ...string) error { 112 if b, err := gparser.VarToXml(content, rootTag...); err != nil { 113 return err 114 } else { 115 r.Header().Set("Content-Type", "application/xml") 116 r.Write(b) 117 } 118 return nil 119 } 120 121 // Deprecated, please use CORSDefault instead. 122 // 123 // (已废弃,请使用CORSDefault)允许AJAX跨域访问. 124 func (r *Response) SetAllowCrossDomainRequest(allowOrigin string, allowMethods string, maxAge ...int) { 125 age := 3628800 126 if len(maxAge) > 0 { 127 age = maxAge[0] 128 } 129 r.Header().Set("Access-Control-Allow-Origin", allowOrigin) 130 r.Header().Set("Access-Control-Allow-Methods", allowMethods) 131 r.Header().Set("Access-Control-Max-Age", strconv.Itoa(age)) 132 } 133 134 // 返回HTTP Code状态码 135 func (r *Response) WriteStatus(status int, content ...interface{}) { 136 if r.buffer.Len() == 0 { 137 // 状态码注册回调函数处理 138 if status != http.StatusOK { 139 if f := r.request.Server.getStatusHandler(status, r.request); f != nil { 140 r.Server.niceCallFunc(func() { 141 f(r.request) 142 }) 143 // 防止多次设置(http: multiple response.WriteHeader calls) 144 if r.Status == 0 { 145 r.WriteHeader(status) 146 } 147 return 148 } 149 } 150 if r.Header().Get("Content-Type") == "" { 151 r.Header().Set("Content-Type", "text/plain; charset=utf-8") 152 //r.Header().Set("X-Content-Type-Options", "nosniff") 153 } 154 if len(content) > 0 { 155 r.Write(content...) 156 } else { 157 r.Write(http.StatusText(status)) 158 } 159 } 160 r.WriteHeader(status) 161 } 162 163 // 静态文件处理 164 func (r *Response) ServeFile(path string) { 165 // 首先判断是否给定的path已经是一个绝对路径 166 path = gfile.RealPath(path) 167 if path == "" { 168 r.WriteStatus(http.StatusNotFound) 169 return 170 } 171 r.Server.serveFile(r.request, path) 172 } 173 174 // 静态文件下载处理 175 func (r *Response) ServeFileDownload(path string, name ...string) { 176 // 首先判断是否给定的path已经是一个绝对路径 177 path = gfile.RealPath(path) 178 if path == "" { 179 r.WriteStatus(http.StatusNotFound) 180 return 181 } 182 downloadName := "" 183 if len(name) > 0 { 184 downloadName = name[0] 185 } else { 186 downloadName = gfile.Basename(path) 187 } 188 r.Header().Set("Content-Type", "application/force-download") 189 r.Header().Set("Accept-Ranges", "bytes") 190 r.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s"`, downloadName)) 191 r.Server.serveFile(r.request, path) 192 } 193 194 // 返回location标识,引导客户端跳转。 195 // 注意这里要先把设置的cookie输出,否则会被忽略。 196 func (r *Response) RedirectTo(location string) { 197 r.Header().Set("Location", location) 198 r.WriteHeader(http.StatusFound) 199 r.request.Exit() 200 } 201 202 // 返回location标识,引导客户端跳转到来源页面 203 func (r *Response) RedirectBack() { 204 r.RedirectTo(r.request.GetReferer()) 205 } 206 207 // 获取当前缓冲区中的数据 208 func (r *Response) Buffer() []byte { 209 return r.buffer.Bytes() 210 } 211 212 // 获取当前缓冲区中的数据大小 213 func (r *Response) BufferLength() int { 214 return r.buffer.Len() 215 } 216 217 // 手动设置缓冲区内容 218 func (r *Response) SetBuffer(data []byte) { 219 r.buffer.Reset() 220 r.buffer.Write(data) 221 } 222 223 // 清空缓冲区内容 224 func (r *Response) ClearBuffer() { 225 r.buffer.Reset() 226 } 227 228 // Deprecated. 229 // 230 // 输出缓冲区数据到客户端. 231 func (r *Response) OutputBuffer() { 232 r.Header().Set("Server", r.Server.config.ServerAgent) 233 //r.handleGzip() 234 r.Writer.OutputBuffer() 235 } 236 237 // 输出缓冲区数据到客户端. 238 func (r *Response) Output() { 239 r.Header().Set("Server", r.Server.config.ServerAgent) 240 //r.handleGzip() 241 r.Writer.OutputBuffer() 242 }