@@ -239,7 +239,11 @@ func coraza_process_connection(t C.coraza_transaction_t, sourceAddress *C.char,
239239//export coraza_process_request_body
240240func coraza_process_request_body (t C.coraza_transaction_t ) C.int {
241241 tx := fromRaw [types.Transaction ](t )
242- if _ , err := tx .ProcessRequestBody (); err != nil {
242+ it , err := tx .ProcessRequestBody ()
243+ if err != nil {
244+ return - 1
245+ }
246+ if it != nil {
243247 return 1
244248 }
245249 return 0
@@ -277,10 +281,46 @@ func coraza_add_request_header(t C.coraza_transaction_t, name *C.char, name_len
277281 return 0
278282}
279283
284+ // coraza_add_request_headers adds multiple request headers from a packed buffer.
285+ // Encoding: [name_len u16][name_bytes][value_len u32][value_bytes] × count
286+ //
287+ //export coraza_add_request_headers
288+ func coraza_add_request_headers (t C.coraza_transaction_t , packed * C.char , packed_len C.int , count C.int ) C.int {
289+ tx := fromRaw [types.Transaction ](t )
290+ buf := C .GoBytes (unsafe .Pointer (packed ), packed_len )
291+ off := 0
292+ for i := 0 ; i < int (count ); i ++ {
293+ if off + 2 > len (buf ) {
294+ return - 1
295+ }
296+ nameLen := int (buf [off ])<< 8 | int (buf [off + 1 ])
297+ off += 2
298+ if off + nameLen > len (buf ) {
299+ return - 1
300+ }
301+ name := string (buf [off : off + nameLen ])
302+ off += nameLen
303+ if off + 4 > len (buf ) {
304+ return - 1
305+ }
306+ valueLen := int (buf [off ])<< 24 | int (buf [off + 1 ])<< 16 | int (buf [off + 2 ])<< 8 | int (buf [off + 3 ])
307+ off += 4
308+ if off + valueLen > len (buf ) {
309+ return - 1
310+ }
311+ value := string (buf [off : off + valueLen ])
312+ off += valueLen
313+ tx .AddRequestHeader (name , value )
314+ }
315+ return 0
316+ }
317+
280318//export coraza_process_request_headers
281319func coraza_process_request_headers (t C.coraza_transaction_t ) C.int {
282320 tx := fromRaw [types.Transaction ](t )
283- tx .ProcessRequestHeaders ()
321+ if it := tx .ProcessRequestHeaders (); it != nil {
322+ return 1
323+ }
284324 return 0
285325}
286326
@@ -314,6 +354,40 @@ func coraza_add_response_header(t C.coraza_transaction_t, name *C.char, name_len
314354 return 0
315355}
316356
357+ // coraza_add_response_headers adds multiple response headers from a packed buffer.
358+ // Same encoding as coraza_add_request_headers.
359+ //
360+ //export coraza_add_response_headers
361+ func coraza_add_response_headers (t C.coraza_transaction_t , packed * C.char , packed_len C.int , count C.int ) C.int {
362+ tx := fromRaw [types.Transaction ](t )
363+ buf := C .GoBytes (unsafe .Pointer (packed ), packed_len )
364+ off := 0
365+ for i := 0 ; i < int (count ); i ++ {
366+ if off + 2 > len (buf ) {
367+ return - 1
368+ }
369+ nameLen := int (buf [off ])<< 8 | int (buf [off + 1 ])
370+ off += 2
371+ if off + nameLen > len (buf ) {
372+ return - 1
373+ }
374+ name := string (buf [off : off + nameLen ])
375+ off += nameLen
376+ if off + 4 > len (buf ) {
377+ return - 1
378+ }
379+ valueLen := int (buf [off ])<< 24 | int (buf [off + 1 ])<< 16 | int (buf [off + 2 ])<< 8 | int (buf [off + 3 ])
380+ off += 4
381+ if off + valueLen > len (buf ) {
382+ return - 1
383+ }
384+ value := string (buf [off : off + valueLen ])
385+ off += valueLen
386+ tx .AddResponseHeader (name , value )
387+ }
388+ return 0
389+ }
390+
317391//export coraza_append_response_body
318392func coraza_append_response_body (t C.coraza_transaction_t , data * C.uchar , length C.int ) C.int {
319393 tx := fromRaw [types.Transaction ](t )
@@ -326,7 +400,11 @@ func coraza_append_response_body(t C.coraza_transaction_t, data *C.uchar, length
326400//export coraza_process_response_body
327401func coraza_process_response_body (t C.coraza_transaction_t ) C.int {
328402 tx := fromRaw [types.Transaction ](t )
329- if _ , err := tx .ProcessResponseBody (); err != nil {
403+ it , err := tx .ProcessResponseBody ()
404+ if err != nil {
405+ return - 1
406+ }
407+ if it != nil {
330408 return 1
331409 }
332410 return 0
@@ -335,7 +413,9 @@ func coraza_process_response_body(t C.coraza_transaction_t) C.int {
335413//export coraza_process_response_headers
336414func coraza_process_response_headers (t C.coraza_transaction_t , status C.int , proto * C.char ) C.int {
337415 tx := fromRaw [types.Transaction ](t )
338- tx .ProcessResponseHeaders (int (status ), C .GoString (proto ))
416+ if it := tx .ProcessResponseHeaders (int (status ), C .GoString (proto )); it != nil {
417+ return 1
418+ }
339419 return 0
340420}
341421
@@ -417,6 +497,15 @@ func coraza_free_waf(t C.coraza_waf_t) C.int {
417497 return 0
418498}
419499
500+ // coraza_free_string frees a string returned by libcoraza (e.g. from
501+ // coraza_matched_rule_get_error_log). Callers must use this instead of
502+ // libc free() to avoid allocator mismatches on Windows.
503+ //
504+ //export coraza_free_string
505+ func coraza_free_string (s * C.char ) {
506+ C .free (unsafe .Pointer (s ))
507+ }
508+
420509/**
421510 * Returns the severity of a matched rule.
422511 * @param[in] pointer to matched rule
0 commit comments