首页 > 其他分享 >http 中使用 gzip 输出内容时,如何预先压缩前一半页面?

http 中使用 gzip 输出内容时,如何预先压缩前一半页面?

时间:2023-10-10 15:11:14浏览次数:31  
标签:github http buf ctx gzip byte com 页面

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


背景是这样:要输出一个很大的动态页面,不开 gzip 压缩会使得流量很大;开了 gzip 压缩又会导致 cpu 升高。
这个页面的前半部分一般不会变化,变化的是后半部分。

因此,能不能把页面的前半部分预先压缩好,输出的时候只压缩后半部分?

目前已经实现了,具体如下:
1.我修改了github.com/klauspost/compress这个项目,增加了WriteGzipedData()这样的方法,即数据流中的某个片段是已经压缩好的内容,便不会消耗 cpu 进行压缩。
可以获取这部分代码:go get github.com/ahfuzhang/[email protected]
2.在自己项目的 go.mod 中,增加 replace:

replace (
	github.com/klauspost/compress => github.com/ahfuzhang/compress v1.17.1
)

require (
	github.com/klauspost/compress v1.16.3
    github.com/valyala/bytebufferpool v1.0.0
	github.com/valyala/fasthttp v1.50.0
)

3.http服务的代码如下:

package main

import (
	"bytes"
	_ "embed"
	"fmt"
	"gzip_part/stringsutil"
	"log"
	"os"

	"github.com/klauspost/compress/gzip"
	"github.com/valyala/bytebufferpool"
	"github.com/valyala/fasthttp"
)

//go:embed raw.html
var html string

//go:embed raw.js
var js string

func getGziped(b []byte) []byte {  // 用于预先压缩某个片段
	buf := bytebufferpool.Get()
	buf.Reset()
	w, _ := gzip.NewWriterLevel(buf, gzip.BestCompression)
	w.Write(nil)
	w.Flush()
	headLen := buf.Len()
	w.Write(b)
	w.Flush()
	out := make([]byte, buf.Len()-headLen)
	copy(out, buf.B[headLen:])
	w.Close()
	bytebufferpool.Put(buf)
	return out
}

func testGzipedHttp() {
    topHalf := getGziped([]byte(html))  // cache 页面的前一半
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		ctx.Response.Header.Add("Content-Type", "text/plain")
		ctx.Response.Header.Add("Content-Encoding", "gzip")

		switch string(ctx.Request.URI().RequestURI()) {
		case "/1":   // direct output
			w, _ := gzip.NewWriterLevel(ctx, gzip.BestCompression)
			w.Write([]byte(html))
			w.Write([]byte(js))
			w.Close()
		case "/2":
			w, _ := gzip.NewWriterLevel(ctx, gzip.BestCompression)
			w.WriteGzipedData([]byte(html), topHalf)
			w.Write([]byte(js))
			w.Close()
		}
	}

	s := &fasthttp.Server{
		Handler: requestHandler,
	}
	if err := s.ListenAndServe(":8080"); err != nil {
		log.Fatalf("error in ListenAndServe: %v", err)
	}
}

func main() {
	testGzipedHttp()
}

测试如下:

curl -G "http://127.0.0.1:8080/1" -v --compressed

curl -G "http://127.0.0.1:8080/2" -v --compressed

两个页面都正常。

标签:github,http,buf,ctx,gzip,byte,com,页面
From: https://www.cnblogs.com/ahfuzhang/p/17754731.html

相关文章

  • C++ libwebsockets搭建WebSocket服务端及Http客户端、服务端
    https://blog.csdn.net/fantasysolo/article/details/88908948  概念WebRTCWebRTC,名称源自网页即时通信(英语:WebReal-TimeCommunication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联......
  • ng访问静态页面403
     开发小哥反馈访问测试静态页面403;百思不得起姐,遂查看静态文件权限 修改完了加777权限,还是403,因为ng放在k8s里面,所以要重新da镜像, 据新镜像更新一下前端ng里面的pod的镜像。......
  • curl测试HTTP请求各阶段时间
    #使用CURL检测Clinet侧发起的HTTP请求各阶段时间,命令参考:curl-o/dev/null-s-wcurl-o/dev/null-s-wtime_namelookup:"\t"%{time_namelookup}"\n"time_connect:"\t\t"%{time_connect}"\n"time_appconnect:"\t"%{time_appconn......
  • 新手如何快速上手HTTP爬虫IP?
    对于刚接触HTTP爬虫IP的新手来说,可能会感到有些困惑。但是,实际上HTTP爬虫IP并不复杂,只要掌握了基本的操作步骤,就可以轻松使用。本文将为新手们提供一个快速上手HTTP爬虫IP的入门指南,帮助您迅速了解HTTP爬虫IP的基本概念和操作方法。第一步:了解HTTP爬虫IP的基本概念HTTP爬虫IP是一种......
  • HTTP和HTTPS区别
    HTTP(HyperTextTransferProtocol)和HTTPS(HTTPSecure)都是用于在计算机之间传输数据的协议.但是,HTTPS在传输数据时使用了安全套接层(SSL)或者传输层安全(TLS)协议来加密数据,以防止第三方拦截或窃取数据。主要区别如下:1.安全性:HTTPS在传输过程中使用了加密技术,而HTTP......
  • 一个页面从输入URL到页面加载显示完成的过程
    当用户在浏览器中输入URL并按下回车时,浏览器会向服务器发送HTTP请求,请求指定的资源。服务器收到请求后,会根据请求的URL返回对应的资源,这通常是一个HTML文件。浏览器收到服务器返回的HTML文件后,会开始解析HTML代码,并在浏览器中构建DOM(DocumentObjcetModal)树。在解析过程中,浏......
  • 【Https异常】This request has been blocked; the content must be served over HTTP
    参考:https://www.cnblogs.com/756623607-zhang/p/11790283.html一、问题出现场景项目从http升级到https后,jsp页面存在发送http请求的情况下就会出现该异常。因为HTTPS是HTTPoverSecureSocketLayer,以安全为目标的HTTP通道,所以在HTTPS承载的页面上不允许出现http请求......
  • Unity使用https请求握手失败的处理方案
    Unity使用https请求握手失败的处理方案HandshakefailedUNITYTLS_INTERNALS解决方案varhandler=newHttpClientHandler();//需要加这句handler.ClientCertificateOptions=ClientCertificateOption.Manual;//需要加这句using(HttpCli......
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance(xsi:schemaLocation详解)
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"中xsi的意思是:本xml文件中要用到某些来自xsi代表的“http://www.w3.org/2001/XMLSchema-instance”这个命名空间的元素 比如用来引入无命名空间schema文件的noNamespaceSchemaLocation="XXX";以及引入自带命名空间的sch......
  • httpclient上传图片(multipart/form-data)
    stringboundary=string.Format("----WebKitFormBoundary{0}",DateTime.Now.Ticks.ToString("x"));MultipartFormDataContentcontent=newMultipartFormDataContent(boundary);content.Headers.ContentType=Me......