// 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. rails应用ajax之二:使用rails自身支持

    考虑另一种情况: 1. 页面上半部分显示当前的所有用户,页面下半部分是输入新用户的界面: 2. 每当输入新用户时,页面上半部分会动态更新新加用户的内容: 我们还是用ajax实现,不过这次用rails内 ...

  2. 不容忽视的js面试题

    1.全局变量和局部变量(变量提升和连等赋值问题) (function() { var a = b = 5; })(); console.log(a); console.log(b); 上面代码运行结果 ...

  3. JVM组成

    java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时 ...

  4. DDD学习笔记1——分层架构

    新旧架构对比图: DDD中的基础设施层包括数据持久化(ORM数据访问),IoC容器实现,AOP实现(安全,日志记录,缓存等) Repository的接口通常放在领域层,具体实现在基础设施层 旧架构的业 ...

  5. JS基础:闭包和作用域链

    简介 一个定义在函数内部的函数与包含它的外部函数构成了闭包,内部函数可以访问外部函数的变量,这些变量将一直保存在内存中,直到无法再引用这个内部函数. 例如: var a = 0; function o ...

  6. gdb命令中attach使用

    [测试程序] 我们先看看我们的测试程序: /* in eg1.c */ int wib(int no1, int no2) {         int result, diff;         di ...

  7. Mac下通过brew安装指定版本的nodejs

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "PingFang SC Semibold"; color: #2c303 ...

  8. React+ANTD项目使用后的一些关于生命周期比较实用的心得

    1. constructor() constructor(props){ super(props) this.state=({ }) } 一定先写super  可以接收从父组件传来的值 父组件往子组件 ...

  9. 关于loadrunner使用web_add_header添加HTTP信息头(比如Content-Type,token等)和使用

    关于loadrunner使用web_add_header添加HTTP信息头(比如Content-Type,token等)和使用 1.web_add_header添加HTTP信息头(比如Content- ...

  10. C#System.Text.RegularExpressions.Regex使用(二) .

    (6)特殊字符的匹配 string x = "//"; Regex r1 = new Regex("^////$"); Console.WriteLine(&q ...