// 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. IoC和DI的基本概念的思维导图

    最近在学习Spring开发,IoC这个概念让我有点儿迷糊,控制反转这四个字是在是无法做到望文生义,于是乎就找了一些材料来学习,研究了半天,绘制了下面这幅思维导图.仅供参考!

  2. 怎么分别javascript写在<head>里还是<body>里面?

    怎么分别javascript写在<head>里还是<body>里面? 具体哪些语句写在<body>里,哪些语句写在<head>里 满意答案 BeginN ...

  3. postgresql to_char 问题

    select create_time from  xxx; select to_char(create_time,'yyyy-MM-dd HH24:mm:ss') as  create_time fr ...

  4. php中$_FILES应用实例

    允许用户从表单上传文件是非常有用的.先来看一段HTML表单代码 <html> <body> <form action="upload_file.php" ...

  5. 浅谈Java多线程的同步问题 【转】

    多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线 ...

  6. larave5.4自定义公共函数的创建

    原文地址:http://blog.csdn.net/qq_38125058/article/details/76862151 公共函数,简单来说就是在任何地方都可以直接使用这个函数.简单介绍两种实现方 ...

  7. 前端工程化(三)---Vue的开发模式

    从0开始,构建前后端分离应用 导航 前端工程化(一)---工程基础目录搭建 前端工程化(二)---webpack配置 前端工程化(三)---Vue的开发模式 前端工程化(四)---helloWord ...

  8. Scala学习笔记:重要语法特性

    1.变量声明 Scala 有两种变量, val 和 var  val的值声明后不可变,var可变 val msg: String = "Hello yet again, world!&quo ...

  9. 重写equals时,遵守的规定

      0 正确的equals方法 public class MyClass { // 主要属性1 private int primaryAttr1; // 主要属性2 private int prima ...

  10. mysqldump+系统计划任务定时备份MySql数据

    MYSQL 数据库备份有很多种(cp.tar.lvm2.mysqldump.xtarbackup)等等,具体使用哪一个还要看你的数据规模.下面给出一个表 #摘自<学会用各种姿态备份Mysql数据 ...