Skip to content

Commit 5ca9e44

Browse files
Fix large packets fails; Change memory leak case
1 parent 55f948f commit 5ca9e44

4 files changed

+35
-28
lines changed

ngx_http_websocket_stat_frame_counter.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ frame_counter_process_message(u_char **buffer, ssize_t *size,
112112
} else {
113113
frame_counter->bytes_consumed += *size;
114114
if (frame_counter->bytes_consumed >
115-
frame_counter->total_payload_size) {
115+
frame_counter->current_payload_size) {
116116
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "WTF?");
117117
frame_counter->stage = HEADER;
118118
}

ngx_http_websocket_stat_frame_counter.h

-3
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ typedef enum { CONTINUATION, TEXT, BINARY, CLOSE = 8, PING, PONG } frame_type;
1515

1616
// Structure representing frame statistic and parsing stage
1717
typedef struct {
18-
// statistic fields
19-
ngx_int_t frames;
2018
ngx_int_t total_payload_size;
21-
ngx_int_t total_size;
2219

2320
// private fields representing current parcing stage
2421
ngx_int_t bytes_consumed;

ngx_http_websocket_stat_module.c

+23-15
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,24 @@
77

88
typedef struct {
99
time_t ws_conn_start_time;
10+
ngx_frame_counter_t frame_counter;
11+
1012
} ngx_http_websocket_stat_ctx;
1113

14+
typedef struct {
15+
ngx_int_t frames;
16+
ngx_int_t total_payload_size;
17+
ngx_int_t total_size;
18+
} ngx_http_websocket_stat_statistic_t;
19+
20+
ngx_http_websocket_stat_statistic_t frames_in;
21+
ngx_http_websocket_stat_statistic_t frames_out;
22+
1223
ngx_frame_counter_t frame_counter_in;
1324
ngx_frame_counter_t frame_counter_out;
1425

1526
ngx_http_websocket_stat_ctx *stat_counter;
1627
typedef struct {
17-
ngx_frame_counter_t *counter;
1828
int from_client;
1929
ngx_http_websocket_stat_ctx *ws_ctx;
2030

@@ -137,9 +147,9 @@ ngx_http_websocket_stat_handler(ngx_http_request_t *r)
137147
out.buf = b;
138148
out.next = NULL;
139149
sprintf((char *)msg, (char *)responce_template, ngx_websocket_stat_active,
140-
frame_counter_in.frames, frame_counter_in.total_payload_size,
141-
frame_counter_in.total_size, frame_counter_out.frames,
142-
frame_counter_out.total_payload_size, frame_counter_out.total_size);
150+
frames_in.frames, frames_in.total_payload_size,
151+
frames_in.total_size, frames_out.frames,
152+
frames_out.total_payload_size, frames_out.total_size);
143153

144154
b->pos = msg; /* first position in memory of the data */
145155
b->last =
@@ -210,20 +220,20 @@ my_send(ngx_connection_t *c, u_char *buf, size_t size)
210220
ngx_http_websocket_stat_ctx *ctx;
211221
ssize_t sz = size;
212222
u_char *buffer = buf;
213-
ngx_frame_counter_t *frame_counter = &frame_counter_out;
223+
ngx_http_websocket_stat_statistic_t *frame_counter = &frames_out;
214224
frame_counter->total_size += sz;
215225
ngx_http_request_t *r = c->data;
216226

217227
ctx = ngx_http_get_module_ctx(r, ngx_http_websocket_stat_module);
218228
template_ctx_s template_ctx;
219-
template_ctx.counter = frame_counter;
220229
template_ctx.from_client = 0;
221230
template_ctx.ws_ctx = ctx;
222231
while (sz > 0) {
223-
if (frame_counter_process_message(&buffer, &sz, frame_counter)) {
232+
if (frame_counter_process_message(&buffer, &sz,
233+
&(ctx->frame_counter))) {
224234
frame_counter->frames++;
225235
frame_counter->total_payload_size +=
226-
frame_counter->current_payload_size;
236+
ctx->frame_counter.current_payload_size;
227237
char *log_line = apply_template(log_template, r, &template_ctx);
228238
websocket_log(log_line);
229239
free(log_line);
@@ -241,19 +251,18 @@ my_recv(ngx_connection_t *c, u_char *buf, size_t size)
241251

242252
ngx_http_websocket_stat_ctx *ctx;
243253
ssize_t sz = n;
244-
ngx_frame_counter_t *frame_counter = &frame_counter_in;
254+
ngx_http_websocket_stat_statistic_t *frame_counter = &frames_in;
245255
ngx_http_request_t *r = c->data;
246256
ctx = ngx_http_get_module_ctx(r, ngx_http_websocket_stat_module);
247257
frame_counter->total_size += n;
248258
template_ctx_s template_ctx;
249-
template_ctx.counter = frame_counter;
250259
template_ctx.from_client = 1;
251260
template_ctx.ws_ctx = ctx;
252261
while (sz > 0) {
253-
if (frame_counter_process_message(&buf, &sz, frame_counter)) {
262+
if (frame_counter_process_message(&buf, &sz, &ctx->frame_counter)) {
254263
frame_counter->frames++;
255264
frame_counter->total_payload_size +=
256-
frame_counter->current_payload_size;
265+
ctx->frame_counter.current_payload_size;
257266
if (ws_log) {
258267
char *log_line = apply_template(log_template, r, &template_ctx);
259268
websocket_log(log_line);
@@ -274,7 +283,6 @@ ngx_http_websocket_stat_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
274283
ngx_http_websocket_stat_ctx *ctx;
275284
ctx = ngx_http_get_module_ctx(r, ngx_http_websocket_stat_module);
276285
template_ctx_s template_ctx;
277-
template_ctx.counter = NULL;
278286
template_ctx.ws_ctx = ctx;
279287

280288
if (r->upstream->upgrade) {
@@ -317,7 +325,7 @@ const char *
317325
ws_packet_type(ngx_http_request_t *r, void *data)
318326
{
319327
template_ctx_s *ctx = data;
320-
ngx_frame_counter_t *frame_cntr = ctx->counter;
328+
ngx_frame_counter_t *frame_cntr = &(ctx->ws_ctx->frame_counter);
321329
if (!ctx || !frame_cntr)
322330
return UNKNOWN_VAR;
323331
sprintf(buff, "%d", frame_cntr->current_frame_type);
@@ -328,7 +336,7 @@ const char *
328336
ws_packet_size(ngx_http_request_t *r, void *data)
329337
{
330338
template_ctx_s *ctx = data;
331-
ngx_frame_counter_t *frame_cntr = ctx->counter;
339+
ngx_frame_counter_t *frame_cntr = &ctx->ws_ctx->frame_counter;
332340
if (!ctx || !frame_cntr)
333341
return UNKNOWN_VAR;
334342
sprintf(buff, "%lu", frame_cntr->current_payload_size);

test/unit_test.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ def regularCheck(self, sent_frames, sent_payload,
3737
self.assertEqual(logged_payload, reported_payload)
3838
self.assertEqual(connections, 0)
3939

40-
@unittest.skip("")
4140
def testSimple(self):
4241
self_run_cmd = local["python3"]['test/ws_test.py'] \
4342
[
@@ -52,7 +51,6 @@ def testSimple(self):
5251
]
5352
self.regularCheck(*[int(x) for x in self_run_cmd().split()])
5453

55-
@unittest.skip("")
5654
def test500Cons(self):
5755
self_run_cmd = local["python3"]['test/ws_test.py'] \
5856
[
@@ -67,7 +65,6 @@ def test500Cons(self):
6765
]
6866
self.regularCheck(*[int(x) for x in self_run_cmd().split()])
6967

70-
@unittest.skip("")
7168
def testLongRun500Cons(self):
7269
self_run_cmd = local["python3"]['test/ws_test.py'] \
7370
[
@@ -82,7 +79,6 @@ def testLongRun500Cons(self):
8279
]
8380
self.regularCheck(*[int(x) for x in self_run_cmd().split()])
8481

85-
@unittest.skip("")
8682
def testLargePackets(self):
8783
self_run_cmd = local["python3"]['test/ws_test.py'] \
8884
[
@@ -91,7 +87,7 @@ def testLargePackets(self):
9187
"--fps", 3,
9288
"--seconds", 30,
9389
"--connections", 5,
94-
"--packet", 3000,
90+
"--packet", 5000,
9591
"--instances", 100,
9692
"--robot_friendly"
9793
]
@@ -113,15 +109,21 @@ def testMemoryLeak(self):
113109
"--robot_friendly",
114110
"--keepNginx"
115111
]
112+
print("First run")
116113
self_run_cmd()
117114
self.assertEqual(pid, getNginxPID())
118-
memAfter = getTotalMem(pid)
115+
mem1stRun = getTotalMem(pid)
116+
print("Second run")
119117
self_run_cmd()
120118
self.assertEqual(pid, getNginxPID())
121119
mem2ndRun = getTotalMem(pid)
122-
print("Mem before: {}, Mem after: {}, mem2ndrun: {}".format(memBefore, memAfter, mem2ndRun))
123-
self.assertTrue(memAfter - memBefore <= 24)
124-
self.assertEqual(memAfter, mem2ndRun)
120+
print("Third run")
121+
self_run_cmd()
122+
self.assertEqual(pid, getNginxPID())
123+
mem3rdRun = getTotalMem(pid)
124+
self.assertTrue(mem1stRun - memBefore <= 24)
125+
self.assertEqual(mem1stRun, mem2ndRun)
126+
self.assertEqual(mem2ndRun, mem3rdRun)
125127

126128
if __name__ == "__main__":
127129
f = local["python3"]["test/test_server.py"] & BG

0 commit comments

Comments
 (0)