0
votes

I have a question for which I was not able to find sufficient information from the Play Framework's documentation. I have a JSON which is quite big and I send this JSON to a WebSocket Endpoint. I would now need to somehow zip this JSON from the client and send that to the WebSocket Endpoint. Once the server gets this zipped JSON, it unzips it and processes it. Is there any way currently to do this using any of the Play Framework's features? Or is there a library that I can look into?

I'm using Play Framework 2.1.1.

Here is what I do to send the Zipped JSON request to the server:

val input = Source.fromURL(getClass.getResource("/bulk_json_10000.txt")).mkString
val bulkJson: Array[Byte] = Utility.zipJson(input)

Just for testing purposes, I'm using a HTTP library that sends a request to the server:

val result = Http.postData(url, bulkJson)
  .header("Content-Type", "application/json")
  .header("Charset", "UTF-8")
  .option(HttpOptions.readTimeout(10000))
  .responseCode
logger.info("The response from the server " + result)

But all what I see is a 400 as the response code.

After adding the Content-Encoding header like below:

.header("Content-Encoding", "gzip")

I was able to get rid of the bad request error and now the server throws "Unexpected end of file from Server" error.

Here is what I do on the controller:

  def gzipTest = Action(parse.anyContent) { request =>
    println(request.body)
    Ok("Done!")
  }

Is there anything I'm missing? I'm not even trying to do anything on the server side with the in-coming request. Why should the server fail?

After fiddling around with GZIPing the request on the client, I added the GZipFilter to my Global.scala and I have the following error that I see is getting thrown from the server:

org.jboss.netty.handler.codec.embedder.CodecEmbedderException: org.jboss.netty.handler.codec.compression.CompressionException: decompression failure (-3): not a gzip stream at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:116) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459) at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536) at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:107) at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312) at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:88) at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: org.jboss.netty.handler.codec.compression.CompressionException: decompression failure (-3): not a gzip stream at org.jboss.netty.handler.codec.compression.ZlibUtil.exception(ZlibUtil.java:31) at org.jboss.netty.handler.codec.compression.ZlibUtil.fail(ZlibUtil.java:27) at org.jboss.netty.handler.codec.compression.ZlibDecoder.decode(ZlibDecoder.java:152) at org.jboss.netty.handler.codec.oneone.OneToOneDecoder.handleUpstream(OneToOneDecoder.java:66) ... 19 more java.nio.channels.ClosedChannelException at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:409) at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:127) at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36) at org.jboss.netty.channel.Channels.write(Channels.java:725) at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:59) at org.jboss.netty.channel.Channels.write(Channels.java:704) at org.jboss.netty.channel.Channels.write(Channels.java:671) at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:248) at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$6$$anonfun$12.apply(PlayDefaultUpstreamHandler.scala:208) at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$6$$anonfun$12.apply(PlayDefaultUpstreamHandler.scala:204) at play.api.libs.iteratee.Enumeratee$$anon$50$$anon$16$$anonfun$play$api$libs$iteratee$Enumeratee$$anon$$anon$$step$2$$anonfun$apply$13.apply(Enumeratee.scala:359) at play.api.libs.iteratee.Enumeratee$$anon$50$$anon$16$$anonfun$play$api$libs$iteratee$Enumeratee$$anon$$anon$$step$2$$anonfun$apply$13.apply(Enumeratee.scala:359) at scala.concurrent.Future$$anonfun$map$1.liftedTree2$1(Future.scala:253) at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:249) at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:249) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:29) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

1
In the client request, try adding the header gzip: .header("Content-Encoding", "gzip") - Didac Montero
I sort of did that and ran into the following error: java.net.SocketException: Unexpected end of file from server - joesan
From the error "not a gzip stream" it looks like your method zipJson is not compressing it as a GZIP but as something different - Didac Montero
I checked my function that Gzip's and UnGzip's the String back and forth. It works. But when I send that to the server, it fails. - joesan
Check the following code: stackoverflow.com/questions/21885825/… - joesan

1 Answers

1
votes

Play Framework 2.2.x supports Gzip directly. For your version you can take a look to this related answer. As explained there, if Play is behind a front end, you can just perform the gzip/gunzip in the front end.