百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

HTTP gzip压缩(易语言gzip解码)

toyiye 2024-07-15 01:18 9 浏览 0 评论

一. HTTP gzip压缩,概述

  • request
    • header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据
  • response
    • body,同时加入以下header:Content-Encoding: gzip:表明body是gzip过的数据
    • Content-Length:117:表示body gzip压缩后的数据大小,便于客户端使用
    • Transfer-Encoding: chunked:分块传输编码

二. 如何使用gzip进行压缩

tomcat开启压缩(gzip)

tomcat server.xml

<Connector
		compression="on" # 表示开启压缩
		noCompressionUserAgents="gozilla, traviata"
		compressionMinSize="2048" # 表示会对大于2KB的文件进行压缩
		compressableMimeType="text/html,text/xml,text/css,text/javascript,image/gif,image/jpg" # 是指将进行压缩的文件类型
/>
  • 弊端
    对HTTP传输内容进行压缩是改良前端响应性能的可用方法之一,大型网站都在用。但是也有缺点,就是压缩过程占用cpu的资源,客户端浏览器解析也占据了一部分时间。但是随着硬件性能不断的提高,这些问题正在不断的弱化。

程序压缩/解压

GZIPInputStream(解压) / GZIPOutputStream(压缩)

  • netflix.zuul相关示例
# org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#writeResponse()
is = context.getResponseDataStream();
InputStream inputStream = is;
if (is != null) {
		if (context.sendZuulResponse()) {
		// if origin response is gzipped, and client has not requested gzip,
		// decompress stream
		// before sending to client
		// else, stream gzip directly to client
				if (context.getResponseGZipped() && !isGzipRequested) {
						// If origin tell it's GZipped but the content is ZERO bytes,
						// don't try to uncompress
						final Long len = context.getOriginContentLength();
						if (len == null || len > 0) {
								try {
												inputStream = new GZIPInputStream(is);
								}catch (java.util.zip.ZipException ex) {
										log.debug("gzip expected but not "+ "received assuming unencoded response "+ RequestContext.getCurrentContext()
												.getRequest().getRequestURL()
												.toString());
										inputStream = is;
								}
					}else {
								// Already done : inputStream = is;
				}
		}else if (context.getResponseGZipped() && isGzipRequested) {
				servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, "gzip");
		}
		writeResponse(inputStream, outStream);
		}
}

# com.netflix.zuul.http.HttpServletRequestWrapper.UnitTest#handlesGzipRequestBody
@Test
public void handlesGzipRequestBody() throws IOException {
		// creates string, gzips into byte array which will be mocked as InputStream of request
		final String body = "hello";
		final byte[] bodyBytes = body.getBytes();
		// in this case the compressed stream is actually larger - need to allocate enough space
		final ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(0);
		final GZIPOutputStream gzipOutStream = new GZIPOutputStream(byteOutStream);
		gzipOutStream.write(bodyBytes);
		gzipOutStream.finish();
		gzipOutStream.flush();
		body(byteOutStream.toByteArray());

		final HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request);
		assertEquals(body, IOUtils.toString(new GZIPInputStream(wrapper.getInputStream())));
}

示例: 网关主动对response进行压缩响应(可减少带宽) GZIPOutputStream

  • 简单实现示例.实际情况需考虑更新情况,如是否已经被压缩等
InputStream inputStream = okResponse.body().byteStream();
try {
// 网关主动对response进行压缩响应(可减少带宽)
		HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
		boolean isGatewayGZIP = Boolean.parseBoolean(request.getHeader("x-gateway-gzip"));
		if (!isGatewayGZIP) {
				isGatewayGZIP = Boolean.parseBoolean(request.getParameter("x-gateway-gzip"));
		}

if (isGatewayGZIP) {
		final ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(0);
		final GZIPOutputStream gzipOutStream = new GZIPOutputStream(byteOutStream);
		gzipOutStream.write(okResponse.body().bytes());
		gzipOutStream.finish();
		gzipOutStream.flush();
		inputStream = new ServletInputStreamWrapper(byteOutStream.toByteArray());
		httpHeaders.add(ZuulHeaders.CONTENT_ENCODING, "gzip");
}
} catch (Exception e) {
		logger.error("GatewayGZIP error:", e);
}

三.okhttp 压缩相关处理

okHttp 解压gzip,条件: Content-Encoding = gizp

  • okio.GzipSource
if (transparentGzip
&& "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))
&& HttpHeaders.hasBody(networkResponse)) {
	GzipSource responseBody = new GzipSource(networkResponse.body().source());
	Headers strippedHeaders = networkResponse.headers().newBuilder()
			.removeAll("Content-Encoding")
			.removeAll("Content-Length")
			.build();
	responseBuilder.headers(strippedHeaders);
	String contentType = networkResponse.header("Content-Type");
	responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
}

okhttp gzip压缩/解压 (示例)

//zip压缩
GzipSink gzipSink = new GzipSink(Okio.sink(file));
BufferedSink bufferedSink = Okio.buffer(gzipSink);
bufferedSink.writeUtf8("this is zip file");
bufferedSink.flush();
bufferedSink.close();

//读取zip
GzipSource gzipSource = new GzipSource(Okio.source(file));
BufferedSource bufferedSource = Okio.buffer(gzipSource);
String s = bufferedSource.readUtf8();

okhttp框架-如何对请求(request)数据进行GZIP压缩-GzipRequestInterceptor

OkHttpClient okHttpClient = new OkHttpClient.Builder() 
.addInterceptor(new GzipRequestInterceptor())//开启Gzip压缩
...
.build();
GzipRequestInterceptor
https://github.com/square/okhttp\\issues/350#issuecomment-123105641
class GzipRequestInterceptor implements Interceptor {
@Override 
public Response intercept(Chain chain) throws IOException {
	Request originalRequest = chain.request();
	if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
			return chain.proceed(originalRequest);
}

Request compressedRequest = originalRequest.newBuilder()
	.header("Content-Encoding", "gzip")
	.method(originalRequest.method(), forceContentLength(gzip(originalRequest.body())))
	.build();
	return chain.proceed(compressedRequest);
}

/** https://github.com/square/okhttp\\issues/350 */
private RequestBody forceContentLength(final RequestBody requestBody) throws IOException {
      final Buffer buffer = new Buffer();
      requestBody.writeTo(buffer);
      return new RequestBody() {
        @Override
        public MediaType contentType() {
              return requestBody.contentType();
        }

        @Override
        public long contentLength() {
              return buffer.size();
        }

      @Override
      public void writeTo(BufferedSink sink) throws IOException {
            sink.write(buffer.snapshot());
      }
};
}

private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
      @Override 
        public MediaType contentType() {
            return body.contentType();
      }

      @Override 
       public long contentLength() {
            return -1; // We don't know the compressed length in advance!
      }

      @Override 
       public void writeTo(BufferedSink sink) throws IOException {
            BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
            body.writeTo(gzipSink);
            gzipSink.close();
      }
};
}
}

okhttp框架-如何对请求数据进行GZIP压缩
https://cloud.tencent.com/info/61307ab74137a46628c2ea2ca42a6eb4.html

Okhttp3请求网络开启Gzip压缩 - CSDN博客
https://blog.csdn.net/aiynmimi/article/details/77453809

四. Nginx的Gzip可以对服务器端响应内容进行压缩从而减少一定的客户端响应时间

gzip on;
gzip_min_length 1k;
gzip_buffers 4 32k;
gzip_types text/plain application/x-javascript application/javascript text/xml text/css;
gzip_vary on;

API网关那些儿 | I'm Yunlong
http://ylzheng.com/2017/03/14/the-things-about-api-gateway

source: //liuxiang.github.io/2018/08/13/HTTP%20gzip压缩

相关推荐

Python第三课3. Python 的非正式介绍

3.Python的非正式介绍?在下面的例子中,通过提示符(>>>与...)的出现与否来区分输入和输出:如果你想复现这些例子,当提示符出现后,你必须在提示符后键入例子中的每...

如何使用 Python 构建一个“谷歌搜索”系统?| 内附代码

来源|hackernoon编译|武明利,责编|Carol出品|AI科技大本营(ID:rgznai100)在这篇文章中,我将向您展示如何使用Python构建自己的答案查找系统。基本上,这...

Python 模拟微博登陆,亲测有效!(如何用python爬微博)

今天想做一个微博爬个人页面的工具,满足一些不可告人的秘密。那么首先就要做那件必做之事!模拟登陆……代码是参考了:https://www.douban.com/note/201767245/,我对代码进...

Python 驱动的 AI 艺术批量创作: 免费的Bing 绘图代码解析

这篇文章将深入分析一段Python代码,该代码利用Bing的AI绘图功能,即bing的images/create,根据用户提供的文本提示生成图像。我们将详细探讨其工作原理、代码结构、...

Python爬虫Scrapy库的使用入门?(python scrapy爬虫)

Scrapy是一个开源的并且支持高度可扩展的Python爬虫框架,主要被用来实现从网站提取数据。出现之初就是为网页抓取而设计,但是现在它也可以被用于从APIs中抓取数据或通用的Web抓取任务。Sc...

Python3 标准库概览(python标准库有什么)

操作系统接口os模块提供了不少与操作系统相关联的函数。>>>importos>>>os.getcwd()#返回当前的工作目录'C:\\Python34...

零基础入门学习Python(三):变量和字符串

分享兴趣,传播快乐,增长见闻,留下美好!亲爱的您,这里是LearningYard新学苑。今天小编为大家带来的是...

Python读写docx文件(python读写word)

Python读写docx文件Python读写word文档有现成的库可以处理pipinstallpython-docx安装一下。https://python-docx.readthedocs.io/...

如何利用Xpath抓取京东网商品信息

前几小编分别利用Python正则表达式和BeautifulSoup爬取了京东网商品信息,今天小编利用Xpath来为大家演示一下如何实现京东商品信息的精准匹配~~HTML文件其实就是由一组尖括号构成的标...

如何利用Xpath选择器抓取京东网商品信息

前几小编分别利用Python正则表达式和BeautifulSoup爬取了京东网商品信息,今天小编利用Xpath来为大家演示一下如何实现京东商品信息的精准匹配~~HTML文件其实就是由一组尖括号构成的标...

python之Scrapy爬虫案例:豆瓣(python爬虫书籍豆瓣评分)

python模块之Scrapy爬虫框架...

Python编程入门学习:最常见加密方式和Python实现

前言我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes。所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错。将字符串...

一日一技:Python中的string.rindex()方法

string.rindex()方法string.rindex()方法返回字符串内子字符串的最高索引(如果找到)。如果未找到子字符串,则会引发异常。rindex()的语法为:...

Asterisk-ARI对通道中的DTMF事件处理

Asterisk通道中关于DTMF处理是一个非常重要的功能。通过DTMF可以实现很多的业务处理。现在我们介绍一下关于ARI对通道中的DTMF处理,我们通过自动话务员实例来说明Asterisk如何创建一...

PyQt5 初次使用(pyqt5下载官网)

本篇文章默认已安装Python3,本篇文章默认使用虚拟环境。安装pipinstallPyQt5PyQt一些图形界面开发工具QtDesigner、国际化翻译工具Liguist需要另外...

取消回复欢迎 发表评论:

请填写验证码