java - websocket protocol error when server deflates payload -


i'm writing java websocket server , receives opening handshake message client (in chrome version 57.0.2987.133 (64-bit)) , responds complete handshake, both shown below.

received: / http/1.1
received: host: localhost:6789
received: connection: upgrade
received: pragma: no-cache
received: cache-control: no-cache
received: upgrade: websocket
received: origin: http://localhost:8080
received: sec-websocket-version: 13
received: user-agent: mozilla/5.0 (macintosh; intel mac os x 10_9_5) applewebkit/537.36 (khtml, gecko) chrome/57.0.2987.133 safari/537.36
received: accept-encoding: gzip, deflate, sdch, br
received: accept-language: en-us,en;q=0.8
received: sec-websocket-key: l1iiusgijbgmtpthwsebog==
received: sec-websocket-extensions: permessage-deflate; client_max_window_bits

sending: http/1.1 101 switching protocols
sending: upgrade: websocket
sending: connection: upgrade
sending: sec-websocket-accept: l5hxndjgdmybwr5grcqmowknf3q=
sending: accept-encoding: gzip, deflate
sending: sec-websocket-extensions: permessage-deflate; client_no_context_takeover; server_no_context_takeover

now, client can send messages , without problem , code uncompresses them using java.util.zip.deflater and... if server responds header bytes 0x81 (fin, no compression, text) , 0x5 bytes 'hello' (as example) websocket client in javascript on chrome entirely happy when try compress response, client closes connection citing error code 1002 , text 'websocket protocol error'.

deflate

    public void sendmessagedeflated(string rxmessage, outputstream streamout) {      system.out.println("message client is: " + rxmessage);      // , compress response , send out.     deflater compressor = new deflater(deflater.deflated);     try {         int headerlength = 2;         byte unzippedmsg[] = rxmessage.getbytes("utf-8");         compressor.setinput(unzippedmsg);         compressor.finish();         byte zippedmsg[] = new byte[2048];  // nasty constant have now.         int tocompresslength = unzippedmsg.length;         int complength = compressor.deflate(zippedmsg, headerlength, zippedmsg.length - headerlength);         compressor.end();          zippedmsg[0] = (byte)0xc1; // fin bit, compression plus opcode text message         zippedmsg[1] = (byte)((byte)0x00 | (byte)complength); // no mask on return data.          streamout.write(zippedmsg, 0, complength + headerlength);      } catch ( ioexception ioex ) {         // tbd         system.out.println("ioexception: " + ioex.tostring());     } catch ( exception ex ) {         // tbd         system.out.println("ioexception: " + ex.tostring());     } } 

gzip

    public void sendmessagegzipped(string rxmessage, outputstream streamout) {     // message here...      system.out.println("message client is: " + rxmessage);      // , compress response , send out.     try {         int headerlength = 2;         byte unzippedmsg[] = rxmessage.getbytes("utf-8");         int tocompresslength = unzippedmsg.length;          bytearrayoutputstream baos = new bytearrayoutputstream();         gzipoutputstream gzipout = new gzipoutputstream(baos);         gzipout.write(unzippedmsg, 0, tocompresslength);         gzipout.close();         byte[] payload = baos.tobytearray();          byte header[] = new byte[32];         header[0] = (byte)0xc1; // fin bit plus opcode text message         header[1] = (byte)((byte)0x00 | (byte)payload.length); // no mask on return data.          streamout.write(header, 0, 2);         streamout.write(payload);      } catch ( ioexception ioex ) {         // tbd         system.out.println("ioexception: " + ioex.tostring());     } catch ( exception ex ) {         // tbd         system.out.println("ioexception: " + ex.tostring());     } } 

i've tried switching opcode binary thinking perhaps compressed text = binary didn't work. can't see i've done wrong or missed out. implementation not include sliding compression window spans messages. think response headers make clear. gratefully accepted.

i solved building client-side websocket code , seeing exception thrown when tried inflate message: "invalid stored block lengths". led me post: java decompressing array of bytes talks deflate being able compress zlib wrapper or without. change 1 line in processmessage2 example code above this...

        deflater compressor = new deflater(deflater.deflated, true); 

...which sets 'nowrap' true.

in headers chrome browser client claims support gzip. if working i'll come here , post answer too.


Comments

Popular posts from this blog

inversion of control - Autofac named registration constructor injection -

verilog - Systemverilog dynamic casting issues -

ios - Change Storyboard View using Seague -