@@ -22,6 +22,12 @@ typedef uintptr_t coraza_waf_t;
2222typedef uintptr_t coraza_transaction_t;
2323typedef uintptr_t coraza_matched_rule_t;
2424
25+ typedef enum coraza_result_t {
26+ CORAZA_ERROR = -1,
27+ CORAZA_OK = 0,
28+ CORAZA_INTERRUPTION = 1,
29+ } coraza_result_t;
30+
2531typedef enum coraza_debug_log_level_t {
2632 CORAZA_DEBUG_LOG_LEVEL_UNKNOWN,
2733 CORAZA_DEBUG_LOG_LEVEL_TRACE,
@@ -239,10 +245,14 @@ func coraza_process_connection(t C.coraza_transaction_t, sourceAddress *C.char,
239245//export coraza_process_request_body
240246func coraza_process_request_body (t C.coraza_transaction_t ) C.int {
241247 tx := fromRaw [types.Transaction ](t )
242- if _ , err := tx .ProcessRequestBody (); err != nil {
243- return 1
248+ it , err := tx .ProcessRequestBody ()
249+ if err != nil {
250+ return C .CORAZA_ERROR
244251 }
245- return 0
252+ if it != nil {
253+ return C .CORAZA_INTERRUPTION
254+ }
255+ return C .CORAZA_OK
246256}
247257
248258//export coraza_update_status_code
@@ -277,11 +287,54 @@ func coraza_add_request_header(t C.coraza_transaction_t, name *C.char, name_len
277287 return 0
278288}
279289
290+ // coraza_add_request_headers adds multiple request headers from a packed buffer.
291+ // Encoding: [name_len u16][name_bytes][value_len u32][value_bytes] × count
292+ //
293+ //export coraza_add_request_headers
294+ func coraza_add_request_headers (t C.coraza_transaction_t , packed * C.char , packed_len C.int , count C.int ) C.int {
295+ if packed_len < 0 || count < 0 {
296+ return C .CORAZA_ERROR
297+ }
298+ tx := fromRaw [types.Transaction ](t )
299+ buf := C .GoBytes (unsafe .Pointer (packed ), packed_len )
300+ off := 0
301+ for i := 0 ; i < int (count ); i ++ {
302+ if off + 2 > len (buf ) {
303+ return C .CORAZA_ERROR
304+ }
305+ nameLen := int (uint16 (buf [off ])<< 8 | uint16 (buf [off + 1 ]))
306+ off += 2
307+ if off + nameLen > len (buf ) {
308+ return C .CORAZA_ERROR
309+ }
310+ name := string (buf [off : off + nameLen ])
311+ off += nameLen
312+ if off + 4 > len (buf ) {
313+ return C .CORAZA_ERROR
314+ }
315+ vl := uint32 (buf [off ])<< 24 | uint32 (buf [off + 1 ])<< 16 | uint32 (buf [off + 2 ])<< 8 | uint32 (buf [off + 3 ])
316+ if vl > uint32 (len (buf )) {
317+ return C .CORAZA_ERROR
318+ }
319+ valueLen := int (vl )
320+ off += 4
321+ if off + valueLen > len (buf ) {
322+ return C .CORAZA_ERROR
323+ }
324+ value := string (buf [off : off + valueLen ])
325+ off += valueLen
326+ tx .AddRequestHeader (name , value )
327+ }
328+ return C .CORAZA_OK
329+ }
330+
280331//export coraza_process_request_headers
281332func coraza_process_request_headers (t C.coraza_transaction_t ) C.int {
282333 tx := fromRaw [types.Transaction ](t )
283- tx .ProcessRequestHeaders ()
284- return 0
334+ if it := tx .ProcessRequestHeaders (); it != nil {
335+ return C .CORAZA_INTERRUPTION
336+ }
337+ return C .CORAZA_OK
285338}
286339
287340//export coraza_process_logging
@@ -314,6 +367,47 @@ func coraza_add_response_header(t C.coraza_transaction_t, name *C.char, name_len
314367 return 0
315368}
316369
370+ // coraza_add_response_headers adds multiple response headers from a packed buffer.
371+ // Same encoding as coraza_add_request_headers.
372+ //
373+ //export coraza_add_response_headers
374+ func coraza_add_response_headers (t C.coraza_transaction_t , packed * C.char , packed_len C.int , count C.int ) C.int {
375+ if packed_len < 0 || count < 0 {
376+ return C .CORAZA_ERROR
377+ }
378+ tx := fromRaw [types.Transaction ](t )
379+ buf := C .GoBytes (unsafe .Pointer (packed ), packed_len )
380+ off := 0
381+ for i := 0 ; i < int (count ); i ++ {
382+ if off + 2 > len (buf ) {
383+ return C .CORAZA_ERROR
384+ }
385+ nameLen := int (uint16 (buf [off ])<< 8 | uint16 (buf [off + 1 ]))
386+ off += 2
387+ if off + nameLen > len (buf ) {
388+ return C .CORAZA_ERROR
389+ }
390+ name := string (buf [off : off + nameLen ])
391+ off += nameLen
392+ if off + 4 > len (buf ) {
393+ return C .CORAZA_ERROR
394+ }
395+ vl := uint32 (buf [off ])<< 24 | uint32 (buf [off + 1 ])<< 16 | uint32 (buf [off + 2 ])<< 8 | uint32 (buf [off + 3 ])
396+ if vl > uint32 (len (buf )) {
397+ return C .CORAZA_ERROR
398+ }
399+ valueLen := int (vl )
400+ off += 4
401+ if off + valueLen > len (buf ) {
402+ return C .CORAZA_ERROR
403+ }
404+ value := string (buf [off : off + valueLen ])
405+ off += valueLen
406+ tx .AddResponseHeader (name , value )
407+ }
408+ return C .CORAZA_OK
409+ }
410+
317411//export coraza_append_response_body
318412func coraza_append_response_body (t C.coraza_transaction_t , data * C.uchar , length C.int ) C.int {
319413 tx := fromRaw [types.Transaction ](t )
@@ -326,17 +420,23 @@ func coraza_append_response_body(t C.coraza_transaction_t, data *C.uchar, length
326420//export coraza_process_response_body
327421func coraza_process_response_body (t C.coraza_transaction_t ) C.int {
328422 tx := fromRaw [types.Transaction ](t )
329- if _ , err := tx .ProcessResponseBody (); err != nil {
330- return 1
423+ it , err := tx .ProcessResponseBody ()
424+ if err != nil {
425+ return C .CORAZA_ERROR
331426 }
332- return 0
427+ if it != nil {
428+ return C .CORAZA_INTERRUPTION
429+ }
430+ return C .CORAZA_OK
333431}
334432
335433//export coraza_process_response_headers
336434func coraza_process_response_headers (t C.coraza_transaction_t , status C.int , proto * C.char ) C.int {
337435 tx := fromRaw [types.Transaction ](t )
338- tx .ProcessResponseHeaders (int (status ), C .GoString (proto ))
339- return 0
436+ if it := tx .ProcessResponseHeaders (int (status ), C .GoString (proto )); it != nil {
437+ return C .CORAZA_INTERRUPTION
438+ }
439+ return C .CORAZA_OK
340440}
341441
342442//export coraza_is_response_body_processable
@@ -417,6 +517,15 @@ func coraza_free_waf(t C.coraza_waf_t) C.int {
417517 return 0
418518}
419519
520+ // coraza_free_string frees a string returned by libcoraza (e.g. from
521+ // coraza_matched_rule_get_error_log). Callers must use this instead of
522+ // libc free() to avoid allocator mismatches on Windows.
523+ //
524+ //export coraza_free_string
525+ func coraza_free_string (s * C.char ) {
526+ C .free (unsafe .Pointer (s ))
527+ }
528+
420529/**
421530 * Returns the severity of a matched rule.
422531 * @param[in] pointer to matched rule
0 commit comments