25
25
timeout ]).
26
26
27
27
-record (reader_state , {socket , conn_name , parse_state , processor_state , state ,
28
- conserve_resources , recv_outstanding , stats_timer ,
29
- parent , connection , heartbeat_sup , heartbeat ,
28
+ conserve_resources , recv_outstanding , max_frame_length , frame_length ,
29
+ stats_timer , parent , connection , heartbeat_sup , heartbeat ,
30
30
timeout_sec % % heartbeat timeout value used, 0 means
31
31
% % heartbeats are disabled
32
32
}).
@@ -69,6 +69,7 @@ init([SupHelperPid, Ref, Configuration]) ->
69
69
_ = register_resource_alarm (),
70
70
71
71
LoginTimeout = application :get_env (rabbitmq_stomp , login_timeout , 10_000 ),
72
+ MaxFrameLength = application :get_env (rabbitmq_stomp , max_frame_length , 192 * 1024 ),
72
73
erlang :send_after (LoginTimeout , self (), login_timeout ),
73
74
74
75
gen_server2 :enter_loop (? MODULE , [],
@@ -80,6 +81,8 @@ init([SupHelperPid, Ref, Configuration]) ->
80
81
processor_state = ProcState ,
81
82
heartbeat_sup = SupHelperPid ,
82
83
heartbeat = {none , none },
84
+ max_frame_length = MaxFrameLength ,
85
+ frame_length = 0 ,
83
86
state = running ,
84
87
conserve_resources = false ,
85
88
recv_outstanding = false })), # reader_state .stats_timer ),
@@ -222,23 +225,41 @@ process_received_bytes([], State) ->
222
225
{ok , State };
223
226
process_received_bytes (Bytes ,
224
227
State = # reader_state {
225
- processor_state = ProcState ,
226
- parse_state = ParseState }) ->
228
+ max_frame_length = MaxFrameLength ,
229
+ frame_length = FrameLength ,
230
+ processor_state = ProcState ,
231
+ parse_state = ParseState }) ->
227
232
case rabbit_stomp_frame :parse (Bytes , ParseState ) of
228
233
{more , ParseState1 } ->
229
- {ok , State # reader_state {parse_state = ParseState1 }};
234
+ FrameLength1 = FrameLength + byte_size (Bytes ),
235
+ case FrameLength1 > MaxFrameLength of
236
+ true ->
237
+ log_reason ({network_error , {frame_too_big , {FrameLength1 , MaxFrameLength }}}, State ),
238
+ {stop , normal , State };
239
+ false ->
240
+ {ok , State # reader_state {parse_state = ParseState1 ,
241
+ frame_length = FrameLength1 }}
242
+ end ;
230
243
{ok , Frame , Rest } ->
231
- case rabbit_stomp_processor :process_frame (Frame , ProcState ) of
232
- {ok , NewProcState , Conn } ->
233
- PS = rabbit_stomp_frame :initial_state (),
234
- NextState = maybe_block (State , Frame ),
235
- process_received_bytes (Rest , NextState # reader_state {
236
- processor_state = NewProcState ,
237
- parse_state = PS ,
238
- connection = Conn });
239
- {stop , Reason , NewProcState } ->
240
- {stop , Reason ,
241
- processor_state (NewProcState , State )}
244
+ FrameLength1 = FrameLength + byte_size (Bytes ) - byte_size (Rest ),
245
+ case FrameLength1 > MaxFrameLength of
246
+ true ->
247
+ log_reason ({network_error , {frame_too_big , {FrameLength1 , MaxFrameLength }}}, State ),
248
+ {stop , normal , State };
249
+ false ->
250
+ case rabbit_stomp_processor :process_frame (Frame , ProcState ) of
251
+ {ok , NewProcState , Conn } ->
252
+ PS = rabbit_stomp_frame :initial_state (),
253
+ NextState = maybe_block (State , Frame ),
254
+ process_received_bytes (Rest , NextState # reader_state {
255
+ frame_length = 0 ,
256
+ processor_state = NewProcState ,
257
+ parse_state = PS ,
258
+ connection = Conn });
259
+ {stop , Reason , NewProcState } ->
260
+ {stop , Reason ,
261
+ processor_state (NewProcState , State )}
262
+ end
242
263
end ;
243
264
{error , Reason } ->
244
265
% % The parser couldn't parse data. We log the reason right
0 commit comments