/* (non-Javadoc) * @see org.eclipse.jetty.websocket.AbstractExtension#onFrame(byte, byte, org.eclipse.jetty.io.Buffer) */ @Override public void onFrame(byte flags, byte opcode, Buffer buffer) { if (getConnection().isControl(opcode) || !isFlag(flags, 1)) { super.onFrame(flags, opcode, buffer); return; } if (buffer.array() == null) buffer = buffer.asMutableBuffer(); int length = 0xff & buffer.get(); if (length >= 0x7e) { int b = (length == 0x7f) ? 8 : 2; length = 0; while (b-- > 0) length = 0x100 * length + (0xff & buffer.get()); } // TODO check a max framesize _inflater.setInput(buffer.array(), buffer.getIndex(), buffer.length()); ByteArrayBuffer buf = new ByteArrayBuffer(length); try { while (_inflater.getRemaining() > 0) { int inflated = _inflater.inflate(buf.array(), buf.putIndex(), buf.space()); if (inflated == 0) throw new DataFormatException("insufficient data"); buf.setPutIndex(buf.putIndex() + inflated); } super.onFrame(clearFlag(flags, 1), opcode, buf); } catch (DataFormatException e) { LOG.warn(e); getConnection().close(WebSocketConnectionRFC6455.CLOSE_BAD_PAYLOAD, e.toString()); } }
@Override public Extension newInstance(ExtensionConfig config) { if (config == null) { return null; } String name = config.getName(); if (StringUtil.isBlank(name)) { return null; } Class<? extends Extension> extClass = getExtension(name); if (extClass == null) { return null; } try { Extension ext = extClass.newInstance(); if (ext instanceof AbstractExtension) { AbstractExtension aext = (AbstractExtension) ext; aext.setConfig(config); aext.setPolicy(policy); aext.setBufferPool(bufferPool); } return ext; } catch (InstantiationException | IllegalAccessException e) { throw new WebSocketException("Cannot instantiate extension: " + extClass, e); } }
private AbstractExtensionWrapper getCache(Class<AbstractExtension<?>> cls) throws StartException, InstantiationException, IllegalAccessException, IOException { String id = cls.getName().substring(27); // File cache = Application.getResource("tmp/extensioncache/" + id + // ".json"); // AbstractExtensionWrapper cached = JSonStorage.restoreFrom(cache, // true, (byte[]) null, new TypeRef<AbstractExtensionWrapper>() { AbstractExtensionWrapper cached = cache.get(id); int v = AbstractExtension.readVersion(cls); if (cached != null) { cached._setClazz(cls); if (cached.getVersion() != v || !cached.getLng().equals(_JDT.getLanguage()) || cached._getSettings() == null) { // update cache cached = null; } } if (cached == null) { Log.L.info("Update Cache " + cache); cached = AbstractExtensionWrapper.create(id, cls); cache.put(id, cached); cacheChanged = true; } else { cached._setClazz(cls); } return cached; }
/* (non-Javadoc) * @see org.eclipse.jetty.websocket.AbstractExtension#addFrame(byte, byte, byte[], int, int) */ @Override public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException { if (getConnection().isControl(opcode) || length < _minLength) { super.addFrame(clearFlag(flags, 1), opcode, content, offset, length); return; } // prepare the uncompressed input _deflater.reset(); _deflater.setInput(content, offset, length); _deflater.finish(); // prepare the output buffer byte[] out = new byte[length]; int out_offset = 0; // write the uncompressed length if (length > 0xffff) { out[out_offset++] = 0x7f; out[out_offset++] = (byte) 0; out[out_offset++] = (byte) 0; out[out_offset++] = (byte) 0; out[out_offset++] = (byte) 0; out[out_offset++] = (byte) ((length >> 24) & 0xff); out[out_offset++] = (byte) ((length >> 16) & 0xff); out[out_offset++] = (byte) ((length >> 8) & 0xff); out[out_offset++] = (byte) (length & 0xff); } else if (length >= 0x7e) { out[out_offset++] = 0x7e; out[out_offset++] = (byte) (length >> 8); out[out_offset++] = (byte) (length & 0xff); } else { out[out_offset++] = (byte) (length & 0x7f); } int l = _deflater.deflate(out, out_offset, length - out_offset); if (_deflater.finished()) super.addFrame(setFlag(flags, 1), opcode, out, 0, l + out_offset); else super.addFrame(clearFlag(flags, 1), opcode, content, offset, length); }
@Override public void destroy() { tcFuture.cancel(true); tuFuture.cancel(true); super.destroy(); }