http – Google App Engine – 如何正确gzip请求

在我的Google App Engine应用程序(标准环境,用Java Scala编写)中,我希望对服务器的一些请求进行gzip压缩.经过一些实验后,我得到了大部分工作,但有几点我不确定.我没有找到关于正确的客户端gzip使用的文档,大多数文档和示例似乎都关心服务器编码其响应,因此我不确定我是否正在做我应该做的一切.

我以这种方式发送请求(在客户端应用程序中使用akka.http):

        val uploadReq = Http().singleRequest(
          HttpRequest(
            uri = "https://xxx.appspot.com/upload-a-file",
            method = HttpMethods.POST,
            headers = List(headers.`Content-Encoding`(HttpEncodings.gzip)) 
            entity = HttpEntity(ContentTypes.`text/plain(UTF-8)`,  Gzip.encode(ByteString(bytes)))
          )
        )

在生产GAE服务器上,我得到了已经解码的gzip压缩请求体,编码头仍然存在.在开发服务器上,这是不同的,标题也存在,但请求正文仍然是gzip压缩.

解码请求输入流的代码不是问题,但我没有找到一种干净的方法来检查我的服务器代码是否应该解码请求体.我目前的解决方法是,如果客户端知道它正在与开发服务器通信,它根本不使用gzip编码,我从不尝试解码请求体,因为我依靠Google App Engine为我这样做.

>我应该在客户端上对请求主体进行不同的编码吗?
>是否还有其他方法可以在服务器上识别传入的请求体是否需要解码?
>我可以假设Google App Engine生产服务器会为我解码身体吗?

最佳答案
为了记录:我最终得到的解决方案是我检查请求正文,如果它看起来像gzip,我解压缩它,完全忽略标题.这适用于prod(App Engine进行解压缩,代码无损)和dev(代码解压缩). Scala代码如下:

def decompressStream(input: InputStream): InputStream = {
  val pushbackInputStream = new PushbackInputStream(input, 2)
  val signature = new Array[Byte](2)
  pushbackInputStream.read(signature)
  pushbackInputStream.unread(signature)
  if (signature(0) == 0x1f.toByte && signature(1) == 0x8b.toByte) {
    new GZIPInputStream(pushbackInputStream)
  } else pushbackInputStream
}

理论上的缺点是有人可能只是偶然发送一个包含0x1f / 0x8b标头的请求.在我的情况下这不可能发生,因此我很好.

转载注明原文:http – Google App Engine – 如何正确gzip请求 - 代码日志