浅析negroni-gzip 过滤器的源码
来源:互联网 发布:向日葵软件下载 编辑:程序博客网 时间:2024/06/02 03:16
源码来源:negroni-gzip
gzip能对数据进行压缩,从而使服务端向客户端传输数据的速度加快。以下对源码的分析是基于源码注释加上自己在谷歌上搜索入header和Sec-WebSocket-Key等知识后的理解,由于时间原因没有深入使用过gzip,很可能存在错误请指正~
// 以下的压缩常量来自于compress/gzip 包const ( encodingGzip = "gzip" // 编码方式为gzip // request或response的header headerAcceptEncoding = "Accept-Encoding" // 指定浏览器可以支持的web服务器返回内容压缩编码类型 headerContentEncoding = "Content-Encoding" //web服务器支持的返回内容压缩编码类型 headerContentLength = "Content-Length" // 响应体的长度 headerContentType = "Content-Type" // 返回内容的MIME类型 headerVary = "Vary" headerSecWebSocketKey = "Sec-WebSocket-Key" // 压缩级别 BestCompression = gzip.BestCompression BestSpeed = gzip.BestSpeed DefaultCompression = gzip.DefaultCompression NoCompression = gzip.NoCompression)// gzipResponseWriter 包含 negroni.ResponseWritertype gzipResponseWriter struct { w *gzip.Writer negroni.ResponseWriter wroteHeader bool}// 检查并设置response的header,并把wroteHeader 设为true,func (grw *gzipResponseWriter) WriteHeader(code int) { headers := grw.ResponseWriter.Header() if headers.Get(headerContentEncoding) == "" { headers.Set(headerContentEncoding, encodingGzip) headers.Add(headerVary, headerAcceptEncoding) } else { grw.w.Reset(ioutil.Discard) grw.w = nil } grw.ResponseWriter.WriteHeader(code)// 设置状态码 grw.wroteHeader = true}// 把byte数据写入 gzip.Writer并设置Content-Typefunc (grw *gzipResponseWriter) Write(b []byte) (int, error) { if !grw.wroteHeader {// 判断是否已经设置过了response的header grw.WriteHeader(http.StatusOK) // 默认返回码200 } if grw.w == nil { return grw.ResponseWriter.Write(b) } // 设置Content-Type if len(grw.Header().Get(headerContentType)) == 0 { grw.Header().Set(headerContentType, http.DetectContentType(b)) } return grw.w.Write(b)}// handler结构体包含ServeHTTP方法,sync.Pool用来缓存对象type handler struct { pool sync.Pool}// 根据压缩level来进行,返回一个handler去处理ServeHTTP中的gzip压缩func Gzip(level int) *handler { h := &handler{} h.pool.New = func() interface{} { gz, err := gzip.NewWriterLevel(ioutil.Discard, level) if err != nil { panic(err) } return gz } return h}// ServeHTTP以包括http.ResponseWriterfunc (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // 判断客户端的AcceptEncoding,如果不接受gzip的编码格式则跳过压缩 if !strings.Contains(r.Header.Get(headerAcceptEncoding), encodingGzip) { next(w, r) return } // 如果客户端是发送Sec-WebSocket-Key过来也无需压缩 if len(r.Header.Get(headerSecWebSocketKey)) > 0 { next(w, r) return } gz := h.pool.Get().(*gzip.Writer)// 从pool中获取Writer defer h.pool.Put(gz)// 使用完后放回pool池等待重新被利用 gz.Reset(w)// 用ResponseWriter完成Reset // 新建一个包含negroni.ResponseWriter和Write的gzipResponseWriter对象,并把wroteHeader初始化为false nrw := negroni.NewResponseWriter(w) grw := gzipResponseWriter{gz, nrw, false} // gzipResponseWriter取代原来的中间件去应用下一个handlerFunc next(&grw, r) // 删除header的ContentLength grw.Header().Del(headerContentLength) gz.Close()}
阅读全文
0 0
- 浅析negroni-gzip 过滤器的源码
- gzip过滤器源码分析
- Golang中gzip过滤器的源码分析与解释
- Go的Negroni库
- 简单阅读golang的net/http包和Negroni的源码
- golang学习之negroni/gizp源码分析
- 过滤器实现文件的gzip压缩
- java过滤器实现Gzip压缩实例源码教程
- GZIP过滤器-Java
- 获取GZip加密的网页源码
- 简单阅读Gzip中间件的源码
- ArrayList的源码浅析
- RecyclerView 的源码浅析
- OSChina 的全局过滤器源码
- negroni包和mux包的一点理解
- 全站GZIP压缩过滤器
- 源码过滤器
- Gzip Zlib PNG 压缩算法 Gzip源码详解 - jiurl的专栏 - CSDNBlog
- SDUT-3401
- scott表和hr表
- 常见的Java面试题
- bug:cv2.error: /io/opencv/modules/imgproc/src/imgwarp.cpp:3492: error: (-215) ssize.width > 0 && ssi
- 试验二
- 浅析negroni-gzip 过滤器的源码
- 2017我的前端心得体会
- sharepoint 2016 使用powershell导入列表命令发生改变
- Spring Boot 基础
- 使用Swiper库实现从右向左排列的列表块
- android6.0下SETTING_VERSION无法绑定变量
- 230. Kth Smallest Element in a BST
- 数据流中产生随机样本
- C++学习笔记--临时对象