// 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. ELF 文件 动态连接 - 延迟绑定(PLT)

    PLT 全称:Procedure Linkage Table ,直译:过程连接表 由于在动态连接中,程序的模块之间包含了大量的函数引用,所以在程序开始执行前,动态链接会耗费较多的时间用于模块之间函数引 ...

  2. IT轮子系列(四)——使用Jquery+formdata对象 上传 文件

    前言 在MVC 中文件的上传,一般都采用控件: <h2>IT轮子四——文件上传</h2> <div> <input type="file" ...

  3. 深入浅出Java concurrent

    看   :http://www.blogjava.net/xylz/archive/2010/07/08/325587.html

  4. 关闭ipv6的方法

    公司研发反应,几台机器开了一些端口,但是访问一直不通. 检查后发现,发现服务开启的是ipv6的端口,所有首先想到的办法就是关闭ipv6. 关闭ipv6的方法有两种: 第一个是在内核配置文件修改配置(p ...

  5. Linux下高并发socket最大连接数

    http://soft.chinabyte.com/os/285/12349285.shtml (转载时原文内容做个修改) 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是 ...

  6. 模仿天猫实战【SSM】——总结

    第一篇文章链接:模仿天猫实战[SSM版]--项目起步 第二篇文章链接:模仿天猫实战[SSM版]--后台开发 总结:项目从4-27号开始写,到今天5-7号才算真正的完工,有许多粗糙的地方,但总算完成了, ...

  7. WebApi PUT、DELETE请求时出现405 - 不允许用于访问此页的 HTTP 谓词。

    开发时,新建WebApi项目需要用到Restful规范,此时请求有POST\PUT\DELETE\GET等请求 此时需要在web.config中加入 <system.webServer> ...

  8. springboot~为Money类型添加最大值和最小值的注解校验

    在spring框架里,为我们集成了很多校验注解,直接在字段上添加对应的注解即可,这些注解基本都是简单保留类型的,即int,long,float,double,String等,而如果你自己封装了新的类, ...

  9. SpringMVC SessionAttributes 简述

    使用SpringMVC时,我们会发现网络上有关SessionAttributes注解的内容非常少,更多的人甚至推荐你继续用HttpServletRequest中的session管理方法来控制Sessi ...

  10. 关于Spring的HibernateTemplate的findByExample方法使用时的一点注意。

    此前我们已经介绍了HibernateTemplate的使用配置方法,但是对其使用没有仔细说明.因为最近比较忙,我先不去介绍,而是重点说明一下容易引起问题的findByExample方法. 我尝试反编译 ...