@@ -217,20 +217,19 @@ struct PerMessageDeflate {
217217 inflateEnd (&readStream);
218218 }
219219
220- bool inflate (char *src, size_t srcLength, char *dst, size_t &dstLength)
221- {
220+ void setInput (char *src, size_t srcLength) {
222221 readStream.next_in = (unsigned char *) src;
223222 readStream.avail_in = srcLength;
223+ }
224+
225+ size_t inflate (char *dst, size_t dstLength) {
224226 readStream.next_out = (unsigned char *) dst;
225227 readStream.avail_out = dstLength;
226-
227- if (Z_OK != ::inflate (&readStream, Z_NO_FLUSH)) {
228- dstLength = 0 ;
229- return true ;
230- } else {
231- dstLength = (dstLength - readStream.avail_out );
232- return false ;
228+ int err = ::inflate (&readStream, Z_NO_FLUSH);
229+ if (err != Z_STREAM_END && err != Z_OK) {
230+ throw err;
233231 }
232+ return readStream.avail_out ;
234233 }
235234};
236235
@@ -295,7 +294,7 @@ Server::Server(int port, bool master, int options, int maxPayload, string path)
295294 receiveBuffer = (char *) new uint32_t [BUFFER_SIZE / 4 + 6 ];
296295
297296 sendBuffer = new char [SHORT_SEND];
298- inflateBuffer = new char [BUFFER_SIZE ];
297+ inflateBuffer = new char [INFLATE_BUFFER_SIZE ];
299298 upgradeResponse = new char [2048 ];
300299
301300 // set default fragment handler
@@ -417,20 +416,30 @@ void Server::internalFragment(Socket socket, const char *fragment, size_t length
417416
418417 // permessage-deflate
419418 if (compressed) {
419+ socketData->pmd ->setInput ((char *) fragment, length);
420+ size_t bufferSpace;
421+ try {
422+ while (!(bufferSpace = socketData->pmd ->inflate (socketData->server ->inflateBuffer , INFLATE_BUFFER_SIZE))) {
423+ socketData->buffer .append (socketData->server ->inflateBuffer , INFLATE_BUFFER_SIZE);
424+ }
420425
421- // todo: if we did not fit in inflateBuffer, append to buffer, rerun
426+ if (!remainingBytes && fin) {
427+ unsigned char tail[4 ] = {0 , 0 , 255 , 255 };
428+ socketData->pmd ->setInput ((char *) tail, 4 );
429+ if (!socketData->pmd ->inflate (socketData->server ->inflateBuffer + INFLATE_BUFFER_SIZE - bufferSpace, bufferSpace)) {
430+ socketData->buffer .append (socketData->server ->inflateBuffer + INFLATE_BUFFER_SIZE - bufferSpace, bufferSpace);
431+ while (!(bufferSpace = socketData->pmd ->inflate (socketData->server ->inflateBuffer , INFLATE_BUFFER_SIZE))) {
432+ socketData->buffer .append (socketData->server ->inflateBuffer , INFLATE_BUFFER_SIZE);
433+ }
434+ }
435+ }
436+ } catch (...) {
437+ socket.close (true , 1006 );
438+ return ;
439+ }
422440
423- size_t inflatedLength = BUFFER_SIZE;
424- socketData->pmd ->inflate ((char *) fragment, length, socketData->server ->inflateBuffer , inflatedLength);
425441 fragment = socketData->server ->inflateBuffer ;
426- length = inflatedLength;
427-
428- if (!remainingBytes && fin) {
429- size_t tailLength = BUFFER_SIZE - inflatedLength;
430- unsigned char tail[4 ] = {0 , 0 , 255 , 255 };
431- socketData->pmd ->inflate ((char *) tail, 4 , socketData->server ->inflateBuffer + inflatedLength, tailLength);
432- length += tailLength;
433- }
442+ length = INFLATE_BUFFER_SIZE - bufferSpace;
434443 }
435444
436445 if (!remainingBytes && fin && !socketData->buffer .length ()) {
0 commit comments