27
27
import java .util .zip .Deflater ;
28
28
import java .util .zip .Inflater ;
29
29
30
- import org .eclipse .jetty .io .Buffer ;
31
30
import org .eclipse .jetty .util .log .Log ;
32
31
import org .eclipse .jetty .util .log .Logger ;
33
32
import org .eclipse .jetty .websocket .WebSocket .FrameConnection ;
@@ -46,7 +45,8 @@ public class PerMessageDeflateExtension implements Extension {
46
45
47
46
private static final Logger __log = Log .getLogger (PerMessageDeflateExtension .class .getName ());
48
47
private static final byte [] TAIL_BYTES = new byte [] { 0x00 , 0x00 , (byte ) 0xff , (byte ) 0xff };
49
- private static final int INITIAL_CAPACITY = 8192 ;
48
+ private static final int TAIL_LENGTH = TAIL_BYTES .length ;
49
+ private static final int INITIAL_CAPACITY = 16384 ;
50
50
private static final String EXTENSION = "permessage-deflate" ;
51
51
private static final String CLIENT_NO_CONTEXT_TAKEOVER = "client_no_context_takeover" ;
52
52
private static final String SERVER_NO_CONTEXT_TAKEOVER = "server_no_context_takeover" ;
@@ -55,52 +55,59 @@ public class PerMessageDeflateExtension implements Extension {
55
55
private static class Zlib {
56
56
protected Deflater _deflater ;
57
57
protected Inflater _inflater ;
58
- protected WebSocketBuffer _buffer ;
59
- protected byte [] _buf ;
58
+ protected byte [] _buffer ;
60
59
protected int _capcacity ;
61
60
protected boolean _deflaterReset ;
62
61
protected boolean _inflaterReset ;
63
62
64
63
public Zlib (boolean deflaterReset , boolean inflaterReset ) {
65
64
_deflater = new Deflater (Deflater .DEFAULT_COMPRESSION , true );
66
65
_inflater = new Inflater (true );
67
- _buffer = new WebSocketBuffer (INITIAL_CAPACITY );
68
- _buf = new byte [INITIAL_CAPACITY ];
69
- _capcacity = INITIAL_CAPACITY ;
66
+ _buffer = new byte [INITIAL_CAPACITY ];
67
+ _capcacity = _buffer .length ;
70
68
_deflaterReset = deflaterReset ;
71
69
_inflaterReset = inflaterReset ;
72
70
}
73
71
72
+ public static byte [] appendTailBytes (byte [] array , int offset , int length ) {
73
+ byte [] buffer = Arrays .copyOfRange (array , offset , offset + length + TAIL_LENGTH );
74
+ System .arraycopy (TAIL_BYTES , 0 , buffer , length , TAIL_LENGTH );
75
+ return buffer ;
76
+ }
77
+
74
78
public byte [] compress (byte [] b , int offset , int length ) {
75
79
int len ;
76
- int index = 0 ;
80
+ int position = 0 ;
77
81
78
82
_deflater .reset ();
79
83
_deflater .setInput (b , offset , length );
80
84
_deflater .finish ();
81
- while ((len = _deflater .deflate (_buf , index , _capcacity - index )) > 0 ) {
82
- if ((index += len ) == _capcacity ) {
83
- _buf = Arrays .copyOf (_buf , _capcacity <<= 1 );
85
+ while ((len = _deflater .deflate (_buffer , position , _capcacity - position )) > 0 ) {
86
+ if ((position += len ) == _capcacity ) {
87
+ _buffer = Arrays .copyOf (_buffer , _capcacity <<= 1 );
84
88
}
85
89
}
86
- return Arrays .copyOf (_buf , index );
90
+ return Arrays .copyOf (_buffer , position );
91
+ }
92
+
93
+ public byte [] decompress (byte [] b ) throws DataFormatException {
94
+ return decompress (b , 0 , b .length );
87
95
}
88
96
89
- public Buffer decompress (byte [] b , int offset , int length ) throws DataFormatException {
97
+ public byte [] decompress (byte [] b , int offset , int length ) throws DataFormatException {
90
98
int len ;
91
- int index = 0 ;
99
+ int position = 0 ;
92
100
93
101
if (_inflaterReset ) {
94
102
_inflater .reset ();
95
103
}
96
104
_inflater .setInput (b , offset , length );
97
- while ((len = _inflater .inflate (_buf , index , _capcacity - index )) > 0 ) {
98
- if ((index += len ) == _capcacity ) {
99
- _buf = Arrays .copyOf (_buf , _capcacity <<= 1 );
105
+ while ((len = _inflater .inflate (_buffer , position , _capcacity - position )) > 0 ) {
106
+ if ((position += len ) == _capcacity ) {
107
+ _buffer = Arrays .copyOf (_buffer , _capcacity <<= 1 );
100
108
}
101
109
}
102
- _buffer .clear ();
103
- return _buffer .append (_buf , 0 , index );
110
+ return Arrays .copyOf (_buffer , position );
104
111
}
105
112
106
113
public boolean isCompressible () {
@@ -122,18 +129,18 @@ public NewZlib(boolean deflaterReset, boolean inflaterReset) {
122
129
@ Override
123
130
public byte [] compress (byte [] b , int offset , int length ) {
124
131
int len ;
125
- int index = 0 ;
132
+ int position = 0 ;
126
133
127
134
if (_deflaterReset ) {
128
135
_deflater .reset ();
129
136
}
130
137
_deflater .setInput (b , offset , length );
131
- while ((len = _deflater .deflate (_buf , index , _capcacity - index , Deflater .SYNC_FLUSH )) > 0 ) {
132
- if ((index += len ) == _capcacity ) {
133
- _buf = Arrays .copyOf (_buf , _capcacity <<= 1 );
138
+ while ((len = _deflater .deflate (_buffer , position , _capcacity - position , Deflater .SYNC_FLUSH )) > 0 ) {
139
+ if ((position += len ) == _capcacity ) {
140
+ _buffer = Arrays .copyOf (_buffer , _capcacity <<= 1 );
134
141
}
135
142
}
136
- return Arrays .copyOf (_buf , index - TAIL_BYTES . length );
143
+ return Arrays .copyOf (_buffer , position - TAIL_LENGTH );
137
144
}
138
145
139
146
@ Override
@@ -159,26 +166,29 @@ public PerMessageDeflateExtension() {
159
166
}
160
167
161
168
@ Override
162
- public void onFrame (byte flags , byte opcode , Buffer buffer ) {
169
+ public void onFrame (byte flags , byte opcode , byte [] array , int offset , int length ) {
163
170
switch (opcode ) {
164
171
case WebSocketConnectionRFC6455 .OP_TEXT :
165
172
case WebSocketConnectionRFC6455 .OP_BINARY :
166
173
_compressed = ((flags & 0x07 ) == 0x04 );
167
174
case WebSocketConnectionRFC6455 .OP_CONTINUATION :
168
175
if (_compressed ) {
169
176
try {
177
+ byte [] buffer ;
170
178
if ((flags &= 0x08 ) > 0 ) {
171
- buffer .put (TAIL_BYTES );
179
+ buffer = _zlib .decompress (Zlib .appendTailBytes (array , offset , length ));
180
+ } else {
181
+ buffer = _zlib .decompress (array , offset , length );
172
182
}
173
- _inbound .onFrame (flags , opcode , _zlib . decompress ( buffer . array (), buffer . getIndex () , buffer .length ()) );
183
+ _inbound .onFrame (flags , opcode , buffer , 0 , buffer .length );
174
184
} catch (DataFormatException e ) {
175
185
__log .warn (e );
176
186
_connection .close (WebSocketConnectionRFC6455 .CLOSE_BAD_DATA , "Bad data" );
177
187
}
178
188
return ;
179
189
}
180
190
}
181
- _inbound .onFrame (flags , opcode , buffer );
191
+ _inbound .onFrame (flags , opcode , array , offset , length );
182
192
}
183
193
184
194
@ Override
0 commit comments