@@ -1127,61 +1127,76 @@ proxy_wasm_execute(struct vwasm_engine *engine,
11271127 }
11281128
11291129 /*
1130- * Deferred HTTP call callback : if proxy_http_call stored a
1131- * response during the header function, invoke the callback now
1132- * that the header function has returned (avoids RefCell panic
1130+ * Deferred HTTP call callbacks : if proxy_http_call stored one or
1131+ * more responses during the header function, invoke the callbacks
1132+ * now that the header function has returned (avoids RefCell panic
11331133 * in the proxy-wasm Rust SDK from re-entrant borrows).
1134+ *
1135+ * Iterate the VRBT in insertion order (ascending token_id).
11341136 */
1135- if (proxy_ctx .http_call_pending ) {
1137+ if (! VRBT_EMPTY ( & proxy_ctx .http_calls ) ) {
11361138 wasmtime_extern_t cb_item ;
1137- proxy_ctx . http_call_pending = 0 ;
1139+ struct vwasm_http_call_entry * ent , * tent ;
11381140
11391141 if (wasmtime_instance_export_get (context , & instance ,
11401142 "proxy_on_http_call_response" , 27 , & cb_item ) &&
11411143 cb_item .kind == WASMTIME_EXTERN_FUNC ) {
1142- wasmtime_val_t cb_args [5 ];
1143- wasmtime_error_t * cb_err ;
1144- wasm_trap_t * cb_trap = NULL ;
1145-
1146- wasmtime_context_set_epoch_deadline (context ,
1147- VWASM_DEFAULT_EPOCH_DEADLINE_MS );
1148-
1149- cb_args [0 ].kind = WASMTIME_I32 ;
1150- cb_args [0 ].of .i32 =
1151- (int32_t )proxy_ctx .stream_context_id ;
1152- cb_args [1 ].kind = WASMTIME_I32 ;
1153- cb_args [1 ].of .i32 =
1154- (int32_t )proxy_ctx .http_call_token_id ;
1155- cb_args [2 ].kind = WASMTIME_I32 ;
1156- cb_args [2 ].of .i32 =
1157- (int32_t )proxy_ctx .http_call_num_headers ;
1158- cb_args [3 ].kind = WASMTIME_I32 ;
1159- cb_args [3 ].of .i32 =
1160- (int32_t )proxy_ctx .http_call_body_len ;
1161- cb_args [4 ].kind = WASMTIME_I32 ;
1162- cb_args [4 ].of .i32 = 0 ; /* num_trailers */
1163-
1164- cb_err = wasmtime_func_call (context ,
1165- & cb_item .of .func , cb_args , 5 ,
1166- NULL , 0 , & cb_trap );
1167- if (cb_err != NULL )
1168- wasmtime_error_delete (cb_err );
1169- if (cb_trap != NULL )
1170- wasm_trap_delete (cb_trap );
11711144
1145+ VRBT_FOREACH_SAFE (ent , vwasm_http_call_tree ,
1146+ & proxy_ctx .http_calls , tent ) {
1147+ wasmtime_val_t cb_args [5 ];
1148+ wasmtime_error_t * cb_err ;
1149+ wasm_trap_t * cb_trap = NULL ;
1150+
1151+ wasmtime_context_set_epoch_deadline (context ,
1152+ VWASM_DEFAULT_EPOCH_DEADLINE_MS );
1153+
1154+ /* Set active call so header maps can look up
1155+ * the correct response */
1156+ proxy_ctx .active_http_call = ent ;
1157+
1158+ cb_args [0 ].kind = WASMTIME_I32 ;
1159+ cb_args [0 ].of .i32 =
1160+ (int32_t )proxy_ctx .stream_context_id ;
1161+ cb_args [1 ].kind = WASMTIME_I32 ;
1162+ cb_args [1 ].of .i32 =
1163+ (int32_t )ent -> token_id ;
1164+ cb_args [2 ].kind = WASMTIME_I32 ;
1165+ cb_args [2 ].of .i32 =
1166+ (int32_t )ent -> response .num_headers ;
1167+ cb_args [3 ].kind = WASMTIME_I32 ;
1168+ cb_args [3 ].of .i32 =
1169+ (int32_t )ent -> response .body_len ;
1170+ cb_args [4 ].kind = WASMTIME_I32 ;
1171+ cb_args [4 ].of .i32 = 0 ; /* num_trailers */
1172+
1173+ cb_err = wasmtime_func_call (context ,
1174+ & cb_item .of .func , cb_args , 5 ,
1175+ NULL , 0 , & cb_trap );
1176+ if (cb_err != NULL )
1177+ wasmtime_error_delete (cb_err );
1178+ if (cb_trap != NULL )
1179+ wasm_trap_delete (cb_trap );
1180+
1181+ proxy_ctx .active_http_call = NULL ;
1182+
1183+ /*
1184+ * If the callback sent a local response,
1185+ * stop iterating and return immediately.
1186+ */
1187+ if (proxy_ctx .local_response_set ) {
1188+ * status_code =
1189+ proxy_ctx .local_response_code ;
1190+ ret = 0 ;
1191+ goto cleanup ;
1192+ }
1193+ }
11721194 /*
1173- * After successful callback, reset action to
1174- * CONTINUE so the request proceeds (the original
1175- * PAUSE was only to wait for the HTTP call).
1176- * If the callback sent a local response, return
1177- * the status code immediately.
1195+ * All callbacks succeeded without sending a local
1196+ * response — reset action to CONTINUE so the
1197+ * request proceeds (the original PAUSE was only to
1198+ * wait for the HTTP call(s)).
11781199 */
1179- if (proxy_ctx .local_response_set ) {
1180- * status_code =
1181- proxy_ctx .local_response_code ;
1182- ret = 0 ;
1183- goto cleanup ;
1184- }
11851200 action = 0 ;
11861201 }
11871202 }
0 commit comments