// Copyright 2013 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// copied from https://github.com/gorilla/handlers/blob/master/compress.go

package http_api

import (
    "compress/flate"
    "compress/gzip"
    "io"
    "net/http"
    "strings"
)

type compressResponseWriter struct {
    io.Writer
    http.ResponseWriter
    http.Hijacker
}

func (w *compressResponseWriter) Header() http.Header {
    return w.ResponseWriter.Header()
}

func (w *compressResponseWriter) WriteHeader(c int) {
    w.ResponseWriter.Header().Del("Content-Length")
    w.ResponseWriter.WriteHeader(c)
}

func (w *compressResponseWriter) Write(b []byte) (int, error) {
    h := w.ResponseWriter.Header()
    if h.Get("Content-Type") == "" {
        h.Set("Content-Type", http.DetectContentType(b))
    }
    h.Del("Content-Length")
    return w.Writer.Write(b)
}

// CompressHandler gzip compresses HTTP responses for clients that support it
// via the 'Accept-Encoding' header.
func CompressHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    L:
        for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") {
            switch strings.TrimSpace(enc) {
            case "gzip":
                w.Header().Set("Content-Encoding", "gzip")
                w.Header().Add("Vary", "Accept-Encoding")

                gw := gzip.NewWriter(w)
                defer gw.Close()

                h, hok := w.(http.Hijacker)
                if !hok { /* w is not Hijacker... oh well... */
                    h = nil
                }

                w = &compressResponseWriter{
                    Writer:         gw,
                    ResponseWriter: w,
                    Hijacker:       h,
                }

                break L
            case "deflate":
                w.Header().Set("Content-Encoding", "deflate")
                w.Header().Add("Vary", "Accept-Encoding")

                fw, _ := flate.NewWriter(w, flate.DefaultCompression)
                defer fw.Close()

                h, hok := w.(http.Hijacker)
                if !hok { /* w is not Hijacker... oh well... */
                    h = nil
                }

                w = &compressResponseWriter{
                    Writer:         fw,
                    ResponseWriter: w,
                    Hijacker:       h,
                }

                break L
            }
        }

        h.ServeHTTP(w, r)
    })
}

compress.go的更多相关文章

  1. 压缩和解压文件:tar gzip bzip2 compress(转)

    tar[必要参数][选择参数][文件] 压缩:tar -czvf filename.tar.gz targetfile解压:tar -zxvf filename.tar.gz参数说明: -c 建立新的 ...

  2. apache.commons.compress 压缩,解压

    最近在一个前辈的指引下,开始研究apache.commons.都是网上找的,而且不会中文乱码,而且还可以在压缩包里面加一层文件夹 package my.test; import java.io.Buf ...

  3. Linux下的压缩和解压缩命令——compress/uncompress

    compress命令 compress命令使用"Lempress-Ziv"编码压缩数据文件.compress是个历史悠久的压缩程序,文件经它压缩后,其名称后面会多出".Z ...

  4. AIX 文件 打包 与 压缩 tar gzip compress 的使用

    今天在Aix用tar -cvf 备份,打成tar包,占有硬盘空间过大,没有压缩比, 尝试使用tar -zcvf  linux系统下可以用-z 命令 (z 用gzip来压缩/解压缩文件,加上该选项后可以 ...

  5. impdp导入报错ORA-14460: only one COMPRESS or NOCOMPRESS clause may be specified

    迁移环境 源:Solaris 10 + Oracle 11.2.0.3 目标:Solaris 10 + Oracle 11.2.0.1 导出命令: expdp user/pwd directory=j ...

  6. [CareerCup] 1.5 Compress String 压缩字符串

    1.5 Implement a method to perform basic string compression using the counts of repeated characters. ...

  7. Compress a Folder/Directory via Perl5

    Compress a Folder/Directory via Perl5 tested in Windows, Mac OS X, Ubuntu16.04 #!/usr/bin/perl #压缩指定 ...

  8. PLSQL_批量压缩表Table Compress(案例)

    2015-04-01 Created By BaoXinjian

  9. compress 表设置及索引设置

    -- 查看表大小 from user_segments where segment_name='TableName'; -- 查看表大小 size_m -- 2000.6796875 2211.695 ...

  10. Compress、tar、gzip、zcat、bzip2、bzcat、打包解压命令行

    讲解内容: Linux环境中,压缩文件案的扩展名大多是*.tar,*.tar.gz,*.tgz,*.gz,*.Z,*.bz2. *.z             compress程序亚索的文件: *.g ...

随机推荐

  1. 修改input属性placeholder的样式

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. JS (全局作用域)

    一.全局函数作用域(把变量的声明和函数的声明放在前面) 作用域(scope):一条数据可以在哪个范围中使用. 通常来说,一段程序代码中所用到的数据并不总是有效/可用的,而限定这个数据的可用性的代码范围 ...

  3. Tihinkphp3.2整合最新版阿里大鱼进行短信验证码发送

    阿里大鱼最新下载地址:阿里大鱼SDK下载 或者从官网进行下载:阿里大鱼SDK官网下载 下载完成后,将压缩包内的api_sdk文件夹放到ThinkPHP\Library\Vendor目录下,修改文件名为 ...

  4. pt-align

    pt-align的功能很简单,将其它工具的输出按列对其. 用法: pt-align [FILES] 如果没有指定文件,则默认读取标准输入的内容. 如,常用的vmstat的输出,阅读体验就不够人性化. ...

  5. Angularjs Post传值后台收不到的原因

    如果你给AngularJS的post方法的data参数创一个key-value对象,那传给后台服务的就是JSON字符串,而正常的POST解析是需要像get?后面的那种&name=value这样 ...

  6. jsoup 使用总结2--高级用法之 :gt(n)

    jsoup 使用总结2--高级用法之 :gt(n) 大部分时候,我们使用jsoup解析网页的时候,都是直接找到某一类元素,或者按某种selector查询:具体使用方法可以参考jsoup官网文档 部分h ...

  7. cbp2make使用

    codeblock中的cbp2make插件能自动生成makefile文件,这里介绍一下从安装到使用到的过程. 首先下载cbp2make,下载的包后缀名是.tar.gz.Linux里双击该下载文件,解压 ...

  8. CSS样式渐变代码,兼容IE8

    background: -webkit-linear-gradient(top,#ffffff,#f5f5f5); background: -moz-linear-gradient(top,#ffff ...

  9. Java 核心卷学习笔记(一)

    Java基程序设计结构 1.注释 三种注释方式: // 注释单行 /* 内容 */ 注释单行 /** * 内容 */

  10. 1 Numpy-科学计算

    在Python中,使用list可以保存一组值,可以作为数组使用,但是比较浪费内存和时间.类似的array模块,不支持多维,也没有各种函数运算,因此也极其不方便. 为解决这一问题,Python提供了Nu ...