opal-up 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -51
  3. data/ext/up_ext/App.h +665 -544
  4. data/ext/up_ext/AsyncSocket.h +307 -284
  5. data/ext/up_ext/AsyncSocketData.h +35 -51
  6. data/ext/up_ext/BloomFilter.h +37 -42
  7. data/ext/up_ext/ChunkedEncoding.h +174 -175
  8. data/ext/up_ext/ClientApp.h +20 -23
  9. data/ext/up_ext/HttpContext.h +476 -381
  10. data/ext/up_ext/HttpContextData.h +20 -20
  11. data/ext/up_ext/HttpErrors.h +14 -10
  12. data/ext/up_ext/HttpParser.h +631 -563
  13. data/ext/up_ext/HttpResponse.h +526 -460
  14. data/ext/up_ext/HttpResponseData.h +59 -55
  15. data/ext/up_ext/HttpRouter.h +328 -310
  16. data/ext/up_ext/Loop.h +174 -168
  17. data/ext/up_ext/LoopData.h +60 -67
  18. data/ext/up_ext/MoveOnlyFunction.h +71 -80
  19. data/ext/up_ext/PerMessageDeflate.h +218 -198
  20. data/ext/up_ext/ProxyParser.h +100 -99
  21. data/ext/up_ext/QueryParser.h +91 -84
  22. data/ext/up_ext/TopicTree.h +273 -268
  23. data/ext/up_ext/Utilities.h +25 -25
  24. data/ext/up_ext/WebSocket.h +376 -310
  25. data/ext/up_ext/WebSocketContext.h +487 -372
  26. data/ext/up_ext/WebSocketContextData.h +74 -62
  27. data/ext/up_ext/WebSocketData.h +53 -46
  28. data/ext/up_ext/WebSocketExtensions.h +194 -178
  29. data/ext/up_ext/WebSocketHandshake.h +115 -110
  30. data/ext/up_ext/WebSocketProtocol.h +441 -398
  31. data/ext/up_ext/extconf.rb +1 -1
  32. data/ext/up_ext/libuwebsockets.cpp +1262 -1292
  33. data/ext/up_ext/libuwebsockets.h +337 -201
  34. data/ext/up_ext/up_ext.c +853 -163
  35. data/lib/up/bun/rack_env.rb +1 -13
  36. data/lib/up/bun/server.rb +93 -19
  37. data/lib/up/cli.rb +3 -0
  38. data/lib/up/client.rb +68 -0
  39. data/lib/up/ruby/cluster.rb +62 -0
  40. data/lib/up/ruby/rack_cluster.rb +1 -1
  41. data/lib/up/ruby/rack_server.rb +0 -1
  42. data/lib/up/u_web_socket/cluster.rb +18 -3
  43. data/lib/up/u_web_socket/server.rb +108 -15
  44. data/lib/up/version.rb +1 -1
  45. metadata +4 -15
  46. data/bin/up_node +0 -12
  47. data/bin/up_node_cluster +0 -12
  48. data/lib/up/node/cluster.rb +0 -39
  49. data/lib/up/node/cluster_cli.rb +0 -15
  50. data/lib/up/node/rack_cluster.rb +0 -25
  51. data/lib/up/node/rack_env.rb +0 -106
  52. data/lib/up/node/rack_server.rb +0 -25
  53. data/lib/up/node/server.rb +0 -84
  54. data/lib/up/node/server_cli.rb +0 -15
  55. data/lib/up/ruby/rack_env.rb +0 -97
  56. data/lib/up/u_web_socket/rack_env.rb +0 -101
@@ -25,49 +25,49 @@
25
25
 
26
26
  /* We always define these options no matter if ZLIB is enabled or not */
27
27
  namespace uWS {
28
- /* Compressor mode is 8 lowest bits where HIGH4(windowBits), LOW4(memLevel).
29
- * Decompressor mode is 8 highest bits LOW4(windowBits).
30
- * If compressor or decompressor bits are 1, then they are shared.
31
- * If everything is just simply 0, then everything is disabled. */
32
- enum CompressOptions : uint16_t {
33
- /* These are not actual compression options */
34
- _COMPRESSOR_MASK = 0x00FF,
35
- _DECOMPRESSOR_MASK = 0x0F00,
36
- /* Disabled, shared, shared are "special" values */
37
- DISABLED = 0,
38
- SHARED_COMPRESSOR = 1,
39
- SHARED_DECOMPRESSOR = 1 << 8,
40
- /* Highest 4 bits describe decompressor */
41
- DEDICATED_DECOMPRESSOR_32KB = 15 << 8,
42
- DEDICATED_DECOMPRESSOR_16KB = 14 << 8,
43
- DEDICATED_DECOMPRESSOR_8KB = 13 << 8,
44
- DEDICATED_DECOMPRESSOR_4KB = 12 << 8,
45
- DEDICATED_DECOMPRESSOR_2KB = 11 << 8,
46
- DEDICATED_DECOMPRESSOR_1KB = 10 << 8,
47
- DEDICATED_DECOMPRESSOR_512B = 9 << 8,
48
- /* Same as 32kb */
49
- DEDICATED_DECOMPRESSOR = 15 << 8,
50
-
51
- /* Lowest 8 bit describe compressor */
52
- DEDICATED_COMPRESSOR_3KB = 9 << 4 | 1,
53
- DEDICATED_COMPRESSOR_4KB = 9 << 4 | 2,
54
- DEDICATED_COMPRESSOR_8KB = 10 << 4 | 3,
55
- DEDICATED_COMPRESSOR_16KB = 11 << 4 | 4,
56
- DEDICATED_COMPRESSOR_32KB = 12 << 4 | 5,
57
- DEDICATED_COMPRESSOR_64KB = 13 << 4 | 6,
58
- DEDICATED_COMPRESSOR_128KB = 14 << 4 | 7,
59
- DEDICATED_COMPRESSOR_256KB = 15 << 4 | 8,
60
- /* Same as 256kb */
61
- DEDICATED_COMPRESSOR = 15 << 4 | 8
62
- };
63
- }
28
+ /* Compressor mode is 8 lowest bits where HIGH4(windowBits), LOW4(memLevel).
29
+ * Decompressor mode is 8 highest bits LOW4(windowBits).
30
+ * If compressor or decompressor bits are 1, then they are shared.
31
+ * If everything is just simply 0, then everything is disabled. */
32
+ enum CompressOptions : uint16_t {
33
+ /* These are not actual compression options */
34
+ _COMPRESSOR_MASK = 0x00FF,
35
+ _DECOMPRESSOR_MASK = 0x0F00,
36
+ /* Disabled, shared, shared are "special" values */
37
+ DISABLED = 0,
38
+ SHARED_COMPRESSOR = 1,
39
+ SHARED_DECOMPRESSOR = 1 << 8,
40
+ /* Highest 4 bits describe decompressor */
41
+ DEDICATED_DECOMPRESSOR_32KB = 15 << 8,
42
+ DEDICATED_DECOMPRESSOR_16KB = 14 << 8,
43
+ DEDICATED_DECOMPRESSOR_8KB = 13 << 8,
44
+ DEDICATED_DECOMPRESSOR_4KB = 12 << 8,
45
+ DEDICATED_DECOMPRESSOR_2KB = 11 << 8,
46
+ DEDICATED_DECOMPRESSOR_1KB = 10 << 8,
47
+ DEDICATED_DECOMPRESSOR_512B = 9 << 8,
48
+ /* Same as 32kb */
49
+ DEDICATED_DECOMPRESSOR = 15 << 8,
50
+
51
+ /* Lowest 8 bit describe compressor */
52
+ DEDICATED_COMPRESSOR_3KB = 9 << 4 | 1,
53
+ DEDICATED_COMPRESSOR_4KB = 9 << 4 | 2,
54
+ DEDICATED_COMPRESSOR_8KB = 10 << 4 | 3,
55
+ DEDICATED_COMPRESSOR_16KB = 11 << 4 | 4,
56
+ DEDICATED_COMPRESSOR_32KB = 12 << 4 | 5,
57
+ DEDICATED_COMPRESSOR_64KB = 13 << 4 | 6,
58
+ DEDICATED_COMPRESSOR_128KB = 14 << 4 | 7,
59
+ DEDICATED_COMPRESSOR_256KB = 15 << 4 | 8,
60
+ /* Same as 256kb */
61
+ DEDICATED_COMPRESSOR = 15 << 4 | 8
62
+ };
63
+ } // namespace uWS
64
64
 
65
65
  #if !defined(UWS_NO_ZLIB) && !defined(UWS_MOCK_ZLIB)
66
66
  #include <zlib.h>
67
67
  #endif
68
68
 
69
- #include <string>
70
69
  #include <optional>
70
+ #include <string>
71
71
 
72
72
  #ifdef UWS_USE_LIBDEFLATE
73
73
  #include "libdeflate.h"
@@ -80,236 +80,256 @@ namespace uWS {
80
80
  #if defined(UWS_NO_ZLIB) || defined(UWS_MOCK_ZLIB)
81
81
  struct ZlibContext {};
82
82
  struct InflationStream {
83
- std::optional<std::string_view> inflate(ZlibContext * /*zlibContext*/, std::string_view compressed, size_t maxPayloadLength, bool /*reset*/) {
84
- return compressed.substr(0, std::min(maxPayloadLength, compressed.length()));
85
- }
86
- InflationStream(CompressOptions /*compressOptions*/) {
87
- }
83
+ std::optional<std::string_view> inflate(ZlibContext * /*zlibContext*/,
84
+ std::string_view compressed,
85
+ size_t maxPayloadLength,
86
+ bool /*reset*/) {
87
+ return compressed.substr(0,
88
+ std::min(maxPayloadLength, compressed.length()));
89
+ }
90
+ InflationStream(CompressOptions /*compressOptions*/) {}
88
91
  };
89
92
  struct DeflationStream {
90
- std::string_view deflate(ZlibContext * /*zlibContext*/, std::string_view raw, bool /*reset*/) {
91
- return raw;
92
- }
93
- DeflationStream(CompressOptions /*compressOptions*/) {
94
- }
93
+ std::string_view deflate(ZlibContext * /*zlibContext*/, std::string_view raw,
94
+ bool /*reset*/) {
95
+ return raw;
96
+ }
97
+ DeflationStream(CompressOptions /*compressOptions*/) {}
95
98
  };
96
99
  #else
97
100
 
98
101
  #define LARGE_BUFFER_SIZE 1024 * 16 // todo: fix this
99
102
 
100
103
  struct ZlibContext {
101
- /* Any returned data is valid until next same-class call.
102
- * We need to have two classes to allow inflation followed
103
- * by many deflations without modifying the inflation */
104
- std::string dynamicDeflationBuffer;
105
- std::string dynamicInflationBuffer;
106
- char *deflationBuffer;
107
- char *inflationBuffer;
104
+ /* Any returned data is valid until next same-class call.
105
+ * We need to have two classes to allow inflation followed
106
+ * by many deflations without modifying the inflation */
107
+ std::string dynamicDeflationBuffer;
108
+ std::string dynamicInflationBuffer;
109
+ char *deflationBuffer;
110
+ char *inflationBuffer;
108
111
 
109
112
  #ifdef UWS_USE_LIBDEFLATE
110
- libdeflate_decompressor *decompressor;
111
- libdeflate_compressor *compressor;
113
+ libdeflate_decompressor *decompressor;
114
+ libdeflate_compressor *compressor;
112
115
  #endif
113
116
 
114
- ZlibContext() {
115
- deflationBuffer = (char *) malloc(LARGE_BUFFER_SIZE);
116
- inflationBuffer = (char *) malloc(LARGE_BUFFER_SIZE);
117
+ ZlibContext() {
118
+ deflationBuffer = (char *)malloc(LARGE_BUFFER_SIZE);
119
+ inflationBuffer = (char *)malloc(LARGE_BUFFER_SIZE);
117
120
 
118
121
  #ifdef UWS_USE_LIBDEFLATE
119
- decompressor = libdeflate_alloc_decompressor();
120
- compressor = libdeflate_alloc_compressor(6);
122
+ decompressor = libdeflate_alloc_decompressor();
123
+ compressor = libdeflate_alloc_compressor(6);
121
124
  #endif
122
- }
125
+ }
123
126
 
124
- ~ZlibContext() {
125
- free(deflationBuffer);
126
- free(inflationBuffer);
127
+ ~ZlibContext() {
128
+ free(deflationBuffer);
129
+ free(inflationBuffer);
127
130
 
128
131
  #ifdef UWS_USE_LIBDEFLATE
129
- libdeflate_free_decompressor(decompressor);
130
- libdeflate_free_compressor(compressor);
132
+ libdeflate_free_decompressor(decompressor);
133
+ libdeflate_free_compressor(compressor);
131
134
  #endif
132
- }
135
+ }
133
136
  };
134
137
 
135
138
  struct DeflationStream {
136
- z_stream deflationStream = {};
139
+ z_stream deflationStream = {};
137
140
 
138
- DeflationStream(CompressOptions compressOptions) {
141
+ DeflationStream(CompressOptions compressOptions) {
139
142
 
140
- /* Sliding inflator should be about 44kb by default, less than compressor */
143
+ /* Sliding inflator should be about 44kb by default, less than compressor */
141
144
 
142
- /* Memory usage is given by 2 ^ (windowBits + 2) + 2 ^ (memLevel + 9) */
143
- int windowBits = -(int) ((compressOptions & _COMPRESSOR_MASK) >> 4), memLevel = compressOptions & 0xF;
145
+ /* Memory usage is given by 2 ^ (windowBits + 2) + 2 ^ (memLevel + 9) */
146
+ int windowBits = -(int)((compressOptions & _COMPRESSOR_MASK) >> 4),
147
+ memLevel = compressOptions & 0xF;
144
148
 
145
- //printf("windowBits: %d, memLevel: %d\n", windowBits, memLevel);
149
+ // printf("windowBits: %d, memLevel: %d\n", windowBits, memLevel);
146
150
 
147
- deflateInit2(&deflationStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, windowBits, memLevel, Z_DEFAULT_STRATEGY);
148
- }
151
+ deflateInit2(&deflationStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
152
+ windowBits, memLevel, Z_DEFAULT_STRATEGY);
153
+ }
149
154
 
150
- /* Deflate and optionally reset. You must not deflate an empty string. */
151
- std::string_view deflate(ZlibContext *zlibContext, std::string_view raw, bool reset) {
155
+ /* Deflate and optionally reset. You must not deflate an empty string. */
156
+ std::string_view deflate(ZlibContext *zlibContext, std::string_view raw,
157
+ bool reset) {
152
158
 
153
159
  #ifdef UWS_USE_LIBDEFLATE
154
- /* Run a fast path in case of shared_compressor */
155
- if (reset) {
156
- size_t written = 0;
157
- static unsigned char buf[1024 + 1];
158
-
159
- written = libdeflate_deflate_compress(zlibContext->compressor, raw.data(), raw.length(), buf, 1024);
160
-
161
- if (written) {
162
- memcpy(&buf[written], "\x00", 1);
163
- return std::string_view((char *) buf, written + 1);
164
- }
165
- }
160
+ /* Run a fast path in case of shared_compressor */
161
+ if (reset) {
162
+ size_t written = 0;
163
+ static unsigned char buf[1024 + 1];
164
+
165
+ written = libdeflate_deflate_compress(zlibContext->compressor, raw.data(),
166
+ raw.length(), buf, 1024);
167
+
168
+ if (written) {
169
+ memcpy(&buf[written], "\x00", 1);
170
+ return std::string_view((char *)buf, written + 1);
171
+ }
172
+ }
166
173
  #endif
167
174
 
168
- /* Odd place to clear this one, fix */
169
- zlibContext->dynamicDeflationBuffer.clear();
170
-
171
- deflationStream.next_in = (Bytef *) raw.data();
172
- deflationStream.avail_in = (unsigned int) raw.length();
173
-
174
- /* This buffer size has to be at least 6 bytes for Z_SYNC_FLUSH to work */
175
- const int DEFLATE_OUTPUT_CHUNK = LARGE_BUFFER_SIZE;
175
+ /* Odd place to clear this one, fix */
176
+ zlibContext->dynamicDeflationBuffer.clear();
176
177
 
177
- int err;
178
- do {
179
- deflationStream.next_out = (Bytef *) zlibContext->deflationBuffer;
180
- deflationStream.avail_out = DEFLATE_OUTPUT_CHUNK;
178
+ deflationStream.next_in = (Bytef *)raw.data();
179
+ deflationStream.avail_in = (unsigned int)raw.length();
181
180
 
182
- err = ::deflate(&deflationStream, Z_SYNC_FLUSH);
183
- if (Z_OK == err && deflationStream.avail_out == 0) {
184
- zlibContext->dynamicDeflationBuffer.append(zlibContext->deflationBuffer, DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out);
185
- continue;
186
- } else {
187
- break;
188
- }
189
- } while (true);
181
+ /* This buffer size has to be at least 6 bytes for Z_SYNC_FLUSH to work */
182
+ const int DEFLATE_OUTPUT_CHUNK = LARGE_BUFFER_SIZE;
190
183
 
191
- /* This must not change avail_out */
192
- if (reset) {
193
- deflateReset(&deflationStream);
194
- }
184
+ int err;
185
+ do {
186
+ deflationStream.next_out = (Bytef *)zlibContext->deflationBuffer;
187
+ deflationStream.avail_out = DEFLATE_OUTPUT_CHUNK;
195
188
 
196
- if (zlibContext->dynamicDeflationBuffer.length()) {
197
- zlibContext->dynamicDeflationBuffer.append(zlibContext->deflationBuffer, DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out);
198
-
199
- return std::string_view((char *) zlibContext->dynamicDeflationBuffer.data(), zlibContext->dynamicDeflationBuffer.length() - 4);
200
- }
201
-
202
- /* Note: We will get an interger overflow resulting in heap buffer overflow if Z_BUF_ERROR is returned
203
- * from passing 0 as avail_in. Therefore we must not deflate an empty string */
204
- return {
189
+ err = ::deflate(&deflationStream, Z_SYNC_FLUSH);
190
+ if (Z_OK == err && deflationStream.avail_out == 0) {
191
+ zlibContext->dynamicDeflationBuffer.append(
205
192
  zlibContext->deflationBuffer,
206
- DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out - 4
207
- };
193
+ DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out);
194
+ continue;
195
+ } else {
196
+ break;
197
+ }
198
+ } while (true);
199
+
200
+ /* This must not change avail_out */
201
+ if (reset) {
202
+ deflateReset(&deflationStream);
208
203
  }
209
204
 
210
- ~DeflationStream() {
211
- deflateEnd(&deflationStream);
205
+ if (zlibContext->dynamicDeflationBuffer.length()) {
206
+ zlibContext->dynamicDeflationBuffer.append(zlibContext->deflationBuffer,
207
+ DEFLATE_OUTPUT_CHUNK -
208
+ deflationStream.avail_out);
209
+
210
+ return std::string_view(
211
+ (char *)zlibContext->dynamicDeflationBuffer.data(),
212
+ zlibContext->dynamicDeflationBuffer.length() - 4);
212
213
  }
214
+
215
+ /* Note: We will get an interger overflow resulting in heap buffer overflow
216
+ * if Z_BUF_ERROR is returned from passing 0 as avail_in. Therefore we must
217
+ * not deflate an empty string */
218
+ return {zlibContext->deflationBuffer,
219
+ DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out - 4};
220
+ }
221
+
222
+ ~DeflationStream() { deflateEnd(&deflationStream); }
213
223
  };
214
224
 
215
225
  struct InflationStream {
216
- z_stream inflationStream = {};
226
+ z_stream inflationStream = {};
217
227
 
218
- InflationStream(CompressOptions compressOptions) {
219
- /* Inflation windowBits are the top 8 bits of the 16 bit compressOptions */
220
- inflateInit2(&inflationStream, -(compressOptions >> 8));
221
- }
228
+ InflationStream(CompressOptions compressOptions) {
229
+ /* Inflation windowBits are the top 8 bits of the 16 bit compressOptions */
230
+ inflateInit2(&inflationStream, -(compressOptions >> 8));
231
+ }
222
232
 
223
- ~InflationStream() {
224
- inflateEnd(&inflationStream);
225
- }
233
+ ~InflationStream() { inflateEnd(&inflationStream); }
226
234
 
227
- /* Zero length inflates are possible and valid */
228
- std::optional<std::string_view> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength, bool reset) {
235
+ /* Zero length inflates are possible and valid */
236
+ std::optional<std::string_view> inflate(ZlibContext *zlibContext,
237
+ std::string_view compressed,
238
+ size_t maxPayloadLength, bool reset) {
229
239
 
230
240
  #ifdef UWS_USE_LIBDEFLATE
231
- /* Try fast path first */
232
- size_t written = 0;
233
- static char buf[1024];
234
-
235
- /* We have to pad 9 bytes and restore those bytes when done since 9 is more than 6 of next WebSocket message */
236
- char tmp[9];
237
- memcpy(tmp, (char *) compressed.data() + compressed.length(), 9);
238
- memcpy((char *) compressed.data() + compressed.length(), "\x00\x00\xff\xff\x01\x00\x00\xff\xff", 9);
239
- libdeflate_result res = libdeflate_deflate_decompress(zlibContext->decompressor, compressed.data(), compressed.length() + 9, buf, 1024, &written);
240
- memcpy((char *) compressed.data() + compressed.length(), tmp, 9);
241
-
242
- if (res == 0) {
243
- /* Fast path wins */
244
- return std::string_view(buf, written);
245
- }
241
+ /* Try fast path first */
242
+ size_t written = 0;
243
+ static char buf[1024];
244
+
245
+ /* We have to pad 9 bytes and restore those bytes when done since 9 is more
246
+ * than 6 of next WebSocket message */
247
+ char tmp[9];
248
+ memcpy(tmp, (char *)compressed.data() + compressed.length(), 9);
249
+ memcpy((char *)compressed.data() + compressed.length(),
250
+ "\x00\x00\xff\xff\x01\x00\x00\xff\xff", 9);
251
+ libdeflate_result res = libdeflate_deflate_decompress(
252
+ zlibContext->decompressor, compressed.data(), compressed.length() + 9,
253
+ buf, 1024, &written);
254
+ memcpy((char *)compressed.data() + compressed.length(), tmp, 9);
255
+
256
+ if (res == 0) {
257
+ /* Fast path wins */
258
+ return std::string_view(buf, written);
259
+ }
246
260
  #endif
247
261
 
248
- /* Save off the bytes we're about to overwrite */
249
- char* tailLocation = (char*)compressed.data() + compressed.length();
250
- char preTailBytes[4];
251
- memcpy(preTailBytes, tailLocation, 4);
252
-
253
- /* Append tail to chunk */
254
- unsigned char tail[4] = {0x00, 0x00, 0xff, 0xff};
255
- memcpy(tailLocation, tail, 4);
256
- compressed = {compressed.data(), compressed.length() + 4};
257
-
258
- /* We clear this one here, could be done better */
259
- zlibContext->dynamicInflationBuffer.clear();
262
+ /* Save off the bytes we're about to overwrite */
263
+ char *tailLocation = (char *)compressed.data() + compressed.length();
264
+ char preTailBytes[4];
265
+ memcpy(preTailBytes, tailLocation, 4);
260
266
 
261
- inflationStream.next_in = (Bytef *) compressed.data();
262
- inflationStream.avail_in = (unsigned int) compressed.length();
267
+ /* Append tail to chunk */
268
+ unsigned char tail[4] = {0x00, 0x00, 0xff, 0xff};
269
+ memcpy(tailLocation, tail, 4);
270
+ compressed = {compressed.data(), compressed.length() + 4};
263
271
 
264
- int err;
265
- do {
266
- inflationStream.next_out = (Bytef *) zlibContext->inflationBuffer;
267
- inflationStream.avail_out = LARGE_BUFFER_SIZE;
272
+ /* We clear this one here, could be done better */
273
+ zlibContext->dynamicInflationBuffer.clear();
268
274
 
269
- err = ::inflate(&inflationStream, Z_SYNC_FLUSH);
270
- if (err == Z_OK && inflationStream.avail_out) {
271
- break;
272
- }
275
+ inflationStream.next_in = (Bytef *)compressed.data();
276
+ inflationStream.avail_in = (unsigned int)compressed.length();
273
277
 
274
- zlibContext->dynamicInflationBuffer.append(zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out);
278
+ int err;
279
+ do {
280
+ inflationStream.next_out = (Bytef *)zlibContext->inflationBuffer;
281
+ inflationStream.avail_out = LARGE_BUFFER_SIZE;
275
282
 
283
+ err = ::inflate(&inflationStream, Z_SYNC_FLUSH);
284
+ if (err == Z_OK && inflationStream.avail_out) {
285
+ break;
286
+ }
276
287
 
277
- } while (inflationStream.avail_out == 0 && zlibContext->dynamicInflationBuffer.length() <= maxPayloadLength);
288
+ zlibContext->dynamicInflationBuffer.append(zlibContext->inflationBuffer,
289
+ LARGE_BUFFER_SIZE -
290
+ inflationStream.avail_out);
278
291
 
279
- if (reset) {
280
- inflateReset(&inflationStream);
281
- }
292
+ } while (inflationStream.avail_out == 0 &&
293
+ zlibContext->dynamicInflationBuffer.length() <= maxPayloadLength);
282
294
 
283
- /* Restore the bytes we used for the tail */
284
- memcpy(tailLocation, preTailBytes, 4);
295
+ if (reset) {
296
+ inflateReset(&inflationStream);
297
+ }
285
298
 
286
- if ((err != Z_BUF_ERROR && err != Z_OK) || zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
287
- return std::nullopt;
288
- }
299
+ /* Restore the bytes we used for the tail */
300
+ memcpy(tailLocation, preTailBytes, 4);
289
301
 
290
- if (zlibContext->dynamicInflationBuffer.length()) {
291
- zlibContext->dynamicInflationBuffer.append(zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out);
302
+ if ((err != Z_BUF_ERROR && err != Z_OK) ||
303
+ zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
304
+ return std::nullopt;
305
+ }
292
306
 
293
- /* Let's be strict about the max size */
294
- if (zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
295
- return std::nullopt;
296
- }
307
+ if (zlibContext->dynamicInflationBuffer.length()) {
308
+ zlibContext->dynamicInflationBuffer.append(zlibContext->inflationBuffer,
309
+ LARGE_BUFFER_SIZE -
310
+ inflationStream.avail_out);
297
311
 
298
- return std::string_view(zlibContext->dynamicInflationBuffer.data(), zlibContext->dynamicInflationBuffer.length());
299
- }
312
+ /* Let's be strict about the max size */
313
+ if (zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
314
+ return std::nullopt;
315
+ }
300
316
 
301
- /* Let's be strict about the max size */
302
- if ((LARGE_BUFFER_SIZE - inflationStream.avail_out) > maxPayloadLength) {
303
- return std::nullopt;
304
- }
317
+ return std::string_view(zlibContext->dynamicInflationBuffer.data(),
318
+ zlibContext->dynamicInflationBuffer.length());
319
+ }
305
320
 
306
- return std::string_view(zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out);
321
+ /* Let's be strict about the max size */
322
+ if ((LARGE_BUFFER_SIZE - inflationStream.avail_out) > maxPayloadLength) {
323
+ return std::nullopt;
307
324
  }
308
325
 
326
+ return std::string_view(zlibContext->inflationBuffer,
327
+ LARGE_BUFFER_SIZE - inflationStream.avail_out);
328
+ }
309
329
  };
310
330
 
311
331
  #endif
312
332
 
313
- }
333
+ } // namespace uWS
314
334
 
315
335
  #endif // UWS_PERMESSAGEDEFLATE_H