Coverage Report

Created: 2026-02-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata/rust/htp/src/c_api/transaction.rs
Line
Count
Source
1
use crate::{
2
    bstr::Bstr, c_api::header::htp_headers_get, connection_parser::ConnectionParser,
3
    request::HtpMethod, transaction::*, uri::Uri,
4
};
5
use std::convert::{TryFrom, TryInto};
6
7
/// Destroys the supplied transaction.
8
/// # Safety
9
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
10
#[no_mangle]
11
292k
pub unsafe extern "C" fn htp_tx_destroy(connp: *mut ConnectionParser, index: usize) {
12
292k
    if let Some(connp) = connp.as_mut() {
13
292k
        connp.remove_tx(index)
14
0
    }
15
292k
}
16
17
/// Get a transaction's normalized parsed uri.
18
///
19
/// tx: Transaction pointer.
20
/// # Safety
21
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
22
#[no_mangle]
23
2.67k
pub unsafe extern "C" fn htp_tx_normalized_uri(tx: *const Transaction) -> *const Bstr {
24
2.67k
    if (*tx).cfg.decoder_cfg.normalized_uri_include_all {
25
0
        tx.as_ref()
26
0
            .and_then(|tx| tx.complete_normalized_uri.as_ref())
27
0
            .map(|uri| uri as *const Bstr)
28
0
            .unwrap_or(std::ptr::null())
29
    } else {
30
2.67k
        tx.as_ref()
31
2.67k
            .and_then(|tx| tx.partial_normalized_uri.as_ref())
32
2.67k
            .map(|uri| uri as *const Bstr)
33
2.67k
            .unwrap_or(std::ptr::null())
34
    }
35
2.67k
}
36
37
/// Returns the user data associated with this transaction or NULL on error.
38
/// # Safety
39
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
40
#[no_mangle]
41
182M
pub unsafe extern "C" fn htp_tx_get_user_data(tx: *const Transaction) -> *mut libc::c_void {
42
182M
    tx.as_ref()
43
182M
        .and_then(|val| val.user_data::<*mut libc::c_void>())
44
182M
        .copied()
45
182M
        .unwrap_or(std::ptr::null_mut())
46
182M
}
47
48
/// Get a transaction's request line.
49
///
50
/// tx: Transaction pointer.
51
///
52
/// Returns the request line or NULL on error.
53
/// # Safety
54
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
55
#[no_mangle]
56
4.74k
pub unsafe extern "C" fn htp_tx_request_line(tx: *const Transaction) -> *const Bstr {
57
4.74k
    tx.as_ref()
58
4.74k
        .and_then(|tx| tx.request_line.as_ref())
59
4.74k
        .map(|line| line as *const Bstr)
60
4.74k
        .unwrap_or(std::ptr::null())
61
4.74k
}
62
63
/// Get a transaction's request method.
64
///
65
/// tx: Transaction pointer.
66
///
67
/// Returns the request method or NULL on error.
68
/// # Safety
69
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
70
#[no_mangle]
71
634k
pub unsafe extern "C" fn htp_tx_request_method(tx: *const Transaction) -> *const Bstr {
72
634k
    tx.as_ref()
73
634k
        .and_then(|tx| tx.request_method.as_ref())
74
634k
        .map(|method| method as *const Bstr)
75
634k
        .unwrap_or(std::ptr::null())
76
634k
}
77
78
/// Get the transaction's request method number.
79
///
80
/// tx: Transaction pointer.
81
///
82
/// Returns the request method number or ERROR on error.
83
/// # Safety
84
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
85
#[no_mangle]
86
1.04M
pub unsafe extern "C" fn htp_tx_request_method_number(tx: *const Transaction) -> HtpMethod {
87
1.04M
    tx.as_ref()
88
1.04M
        .map(|tx| tx.request_method_number)
89
1.04M
        .unwrap_or(HtpMethod::ERROR)
90
1.04M
}
91
92
/// Get a transaction's request uri.
93
///
94
/// tx: Transaction pointer.
95
///
96
/// Returns the request uri or NULL on error.
97
/// # Safety
98
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
99
#[no_mangle]
100
931k
pub unsafe extern "C" fn htp_tx_request_uri(tx: *const Transaction) -> *const Bstr {
101
931k
    tx.as_ref()
102
931k
        .and_then(|tx| tx.request_uri.as_ref())
103
931k
        .map(|uri| uri as *const Bstr)
104
931k
        .unwrap_or(std::ptr::null())
105
931k
}
106
107
/// Get a transaction's request protocol.
108
///
109
/// tx: Transaction pointer.
110
///
111
/// Returns the protocol or NULL on error.
112
/// # Safety
113
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
114
#[no_mangle]
115
579k
pub unsafe extern "C" fn htp_tx_request_protocol(tx: *const Transaction) -> *const Bstr {
116
579k
    tx.as_ref()
117
579k
        .and_then(|tx| tx.request_protocol.as_ref())
118
579k
        .map(|protocol| protocol as *const Bstr)
119
579k
        .unwrap_or(std::ptr::null())
120
579k
}
121
122
/// Get a transaction's request protocol number.
123
///
124
/// tx: Transaction pointer.
125
///
126
/// Returns the protocol number or ERROR on error.
127
/// # Safety
128
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
129
#[no_mangle]
130
124k
pub unsafe extern "C" fn htp_tx_request_protocol_number(tx: *const Transaction) -> HtpProtocol {
131
124k
    tx.as_ref()
132
124k
        .map(|tx| tx.request_protocol_number)
133
124k
        .unwrap_or(HtpProtocol::Error)
134
124k
}
135
136
/// Get whether a transaction's protocol is version 0.9.
137
///
138
/// tx: Transaction pointer.
139
///
140
/// Returns 1 if the version is 0.9 or 0 otherwise. A NULL argument will
141
/// also result in a return value of 0.
142
/// # Safety
143
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
144
#[no_mangle]
145
1.52M
pub unsafe extern "C" fn htp_tx_is_protocol_0_9(tx: *const Transaction) -> i32 {
146
1.52M
    tx.as_ref().map(|tx| tx.is_protocol_0_9 as i32).unwrap_or(0)
147
1.52M
}
148
149
/// Get a transaction's parsed uri.
150
///
151
/// tx: Transaction pointer.
152
///
153
/// Returns the parsed uri or NULL on error.
154
/// # Safety
155
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
156
#[no_mangle]
157
1.47M
pub unsafe extern "C" fn htp_tx_parsed_uri(tx: *const Transaction) -> *const Uri {
158
1.47M
    tx.as_ref()
159
1.47M
        .and_then(|tx| tx.parsed_uri.as_ref())
160
1.47M
        .map(|uri| uri as *const Uri)
161
1.47M
        .unwrap_or(std::ptr::null())
162
1.47M
}
163
164
/// Get a transaction's request headers.
165
///
166
/// tx: Transaction pointer.
167
///
168
/// Returns the request headers or NULL on error.
169
/// # Safety
170
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
171
#[no_mangle]
172
556k
pub unsafe extern "C" fn htp_tx_request_headers(tx: *const Transaction) -> *const Headers {
173
556k
    tx.as_ref()
174
556k
        .map(|tx| &tx.request_headers as *const Headers)
175
556k
        .unwrap_or(std::ptr::null())
176
556k
}
177
178
/// Get a transaction's request headers size.
179
///
180
/// tx: Transaction pointer.
181
///
182
/// Returns the size or -1 on error.
183
/// # Safety
184
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
185
#[no_mangle]
186
517
pub unsafe extern "C" fn htp_tx_request_headers_size(tx: *const Transaction) -> isize {
187
517
    tx.as_ref()
188
517
        .map(|tx| isize::try_from(tx.request_headers.size()).unwrap_or(-1))
189
517
        .unwrap_or(-1)
190
517
}
191
192
/// Get the first request header value matching the key from a transaction.
193
///
194
/// tx: Transaction pointer.
195
/// ckey: Header name to match.
196
///
197
/// Returns the header or NULL when not found or on error
198
/// # Safety
199
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
200
#[no_mangle]
201
1.30M
pub unsafe extern "C" fn htp_tx_request_header(
202
1.30M
    tx: *const Transaction, ckey: *const libc::c_char,
203
1.30M
) -> *const Header {
204
1.30M
    tx.as_ref()
205
1.30M
        .map(|tx| htp_headers_get(&tx.request_headers, ckey))
206
1.30M
        .unwrap_or(std::ptr::null())
207
1.30M
}
208
209
/// Get the request header at the given index.
210
///
211
/// tx: Transaction pointer.
212
/// index: request header table index.
213
///
214
/// Returns the header or NULL on error
215
/// # Safety
216
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
217
#[no_mangle]
218
2.85k
pub unsafe extern "C" fn htp_tx_request_header_index(
219
2.85k
    tx: *const Transaction, index: usize,
220
2.85k
) -> *const Header {
221
2.85k
    tx.as_ref()
222
2.85k
        .map(|tx| {
223
2.85k
            tx.request_headers
224
2.85k
                .elements
225
2.85k
                .get(index)
226
2.85k
                .map(|value| value as *const Header)
227
2.85k
                .unwrap_or(std::ptr::null())
228
2.85k
        })
229
2.85k
        .unwrap_or(std::ptr::null())
230
2.85k
}
231
232
/// Get the transaction's request authentication type.
233
///
234
/// tx: Transaction pointer.
235
///
236
/// Returns the auth type or HTP_AUTH_ERROR on error.
237
/// # Safety
238
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
239
#[no_mangle]
240
1.52M
pub unsafe extern "C" fn htp_tx_request_auth_type(tx: *const Transaction) -> HtpAuthType {
241
1.52M
    tx.as_ref()
242
1.52M
        .map(|tx| tx.request_auth_type)
243
1.52M
        .unwrap_or(HtpAuthType::ERROR)
244
1.52M
}
245
246
/// Get a transaction's request hostname.
247
///
248
/// tx: Transaction pointer.
249
///
250
/// Returns the request hostname or NULL on error.
251
/// # Safety
252
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
253
#[no_mangle]
254
523k
pub unsafe extern "C" fn htp_tx_request_hostname(tx: *const Transaction) -> *const Bstr {
255
523k
    tx.as_ref()
256
523k
        .and_then(|tx| tx.request_hostname.as_ref())
257
523k
        .map(|hostname| hostname as *const Bstr)
258
523k
        .unwrap_or(std::ptr::null())
259
523k
}
260
261
/// Get the transaction's request port number.
262
///
263
/// tx: Transaction pointer.
264
///
265
/// Returns the request port number or -1 on error.
266
/// # Safety
267
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
268
#[no_mangle]
269
240k
pub unsafe extern "C" fn htp_tx_request_port_number(tx: *const Transaction) -> i32 {
270
240k
    tx.as_ref()
271
240k
        .and_then(|tx| tx.request_port_number.as_ref())
272
240k
        .map(|port| *port as i32)
273
240k
        .unwrap_or(-1)
274
240k
}
275
276
/// Get a transaction's request message length.
277
///
278
/// tx: Transaction pointer.
279
///
280
/// Returns the request message length or -1 on error.
281
/// # Safety
282
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
283
#[no_mangle]
284
0
pub unsafe extern "C" fn htp_tx_request_message_len(tx: *const Transaction) -> i64 {
285
0
    tx.as_ref()
286
0
        .map(|tx| tx.request_message_len.try_into().ok().unwrap_or(-1))
287
0
        .unwrap_or(-1)
288
0
}
289
290
/// Get a transaction's response line.
291
///
292
/// tx: Transaction pointer.
293
///
294
/// Returns the response line or NULL on error.
295
/// # Safety
296
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
297
#[no_mangle]
298
73
pub unsafe extern "C" fn htp_tx_response_line(tx: *const Transaction) -> *const Bstr {
299
73
    tx.as_ref()
300
73
        .and_then(|tx| tx.response_line.as_ref())
301
73
        .map(|response_line| response_line as *const Bstr)
302
73
        .unwrap_or(std::ptr::null())
303
73
}
304
305
/// Get a transaction's response protocol.
306
///
307
/// tx: Transaction pointer.
308
///
309
/// Returns the response protocol or NULL on error.
310
/// # Safety
311
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
312
#[no_mangle]
313
151
pub unsafe extern "C" fn htp_tx_response_protocol(tx: *const Transaction) -> *const Bstr {
314
151
    tx.as_ref()
315
151
        .and_then(|tx| tx.response_protocol.as_ref())
316
151
        .map(|response_protocol| response_protocol as *const Bstr)
317
151
        .unwrap_or(std::ptr::null())
318
151
}
319
320
/// Get a transaction's response protocol number.
321
///
322
/// tx: Transaction pointer.
323
///
324
/// Returns the protocol number or ERROR on error.
325
/// # Safety
326
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
327
#[no_mangle]
328
0
pub unsafe extern "C" fn htp_tx_response_protocol_number(tx: *const Transaction) -> HtpProtocol {
329
0
    tx.as_ref()
330
0
        .map(|tx| tx.response_protocol_number)
331
0
        .unwrap_or(HtpProtocol::Error)
332
0
}
333
334
/// Get the transaction's response status.
335
///
336
/// tx: Transaction pointer.
337
///
338
/// Returns the response status or NULL on error.
339
/// # Safety
340
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
341
#[no_mangle]
342
366k
pub unsafe extern "C" fn htp_tx_response_status(tx: *const Transaction) -> *const Bstr {
343
366k
    tx.as_ref()
344
366k
        .and_then(|tx| tx.response_status.as_ref())
345
366k
        .map(|response_status| response_status as *const Bstr)
346
366k
        .unwrap_or(std::ptr::null())
347
366k
}
348
349
/// Get the transaction's response status number.
350
///
351
/// tx: Transaction pointer.
352
///
353
/// Returns the response status number or -1 on error.
354
/// # Safety
355
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
356
#[no_mangle]
357
281k
pub unsafe extern "C" fn htp_tx_response_status_number(tx: *const Transaction) -> i32 {
358
281k
    tx.as_ref()
359
281k
        .map(|tx| match tx.response_status_number {
360
128k
            HtpResponseNumber::Unknown => 0,
361
31.2k
            HtpResponseNumber::Invalid => -1,
362
122k
            HtpResponseNumber::Valid(status) => status as i32,
363
281k
        })
364
281k
        .unwrap_or(-1)
365
281k
}
366
367
/// Get a transaction's response message.
368
///
369
/// tx: Transaction pointer.
370
///
371
/// Returns the response message or NULL on error.
372
/// # Safety
373
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
374
#[no_mangle]
375
695
pub unsafe extern "C" fn htp_tx_response_message(tx: *const Transaction) -> *const Bstr {
376
695
    tx.as_ref()
377
695
        .and_then(|tx| tx.response_message.as_ref())
378
695
        .map(|response_message| response_message as *const Bstr)
379
695
        .unwrap_or(std::ptr::null())
380
695
}
381
382
/// Get a transaction's response headers.
383
///
384
/// tx: Transaction pointer.
385
///
386
/// Returns the response headers or NULL on error.
387
/// # Safety
388
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
389
#[no_mangle]
390
325k
pub unsafe extern "C" fn htp_tx_response_headers(tx: *const Transaction) -> *const Headers {
391
325k
    tx.as_ref()
392
325k
        .map(|tx| &tx.response_headers as *const Headers)
393
325k
        .unwrap_or(std::ptr::null())
394
325k
}
395
396
/// Get the first response header value matching the key from a transaction.
397
///
398
/// tx: Transaction pointer.
399
/// ckey: Header name to match.
400
///
401
/// Returns the header or NULL when not found or on error
402
/// # Safety
403
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
404
#[no_mangle]
405
1.77M
pub unsafe extern "C" fn htp_tx_response_header(
406
1.77M
    tx: *const Transaction, ckey: *const libc::c_char,
407
1.77M
) -> *const Header {
408
1.77M
    tx.as_ref()
409
1.77M
        .map(|tx| htp_headers_get(&tx.response_headers, ckey))
410
1.77M
        .unwrap_or(std::ptr::null())
411
1.77M
}
412
413
/// Get a transaction's response message length.
414
///
415
/// tx: Transaction pointer.
416
///
417
/// Returns the response message length or -1 on error.
418
/// # Safety
419
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
420
#[no_mangle]
421
316k
pub unsafe extern "C" fn htp_tx_response_message_len(tx: *const Transaction) -> i64 {
422
316k
    tx.as_ref()
423
316k
        .map(|tx| tx.response_message_len.try_into().ok().unwrap_or(-1))
424
316k
        .unwrap_or(-1)
425
316k
}
426
427
/// Get the transaction's bit flags.
428
///
429
/// tx: Transaction pointer.
430
///
431
/// Returns the flags represented as an integer or 0 if the flags are empty
432
/// or a NULL ptr is passed as an argument.
433
/// # Safety
434
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
435
#[no_mangle]
436
4.86M
pub unsafe extern "C" fn htp_tx_flags(tx: *const Transaction) -> u64 {
437
4.86M
    tx.as_ref().map(|tx| tx.flags).unwrap_or(0)
438
4.86M
}
439
440
/// Get the transaction's index.
441
///
442
/// tx: Transaction pointer.
443
///
444
/// # Safety
445
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
446
#[no_mangle]
447
201M
pub unsafe extern "C" fn htp_tx_index(tx: *const Transaction) -> usize {
448
201M
    tx.as_ref().map(|tx| tx.index).unwrap_or(0)
449
201M
}
450
451
/// Get the transaction's request progress.
452
///
453
/// tx: Transaction pointer.
454
///
455
/// Returns the progress or HTP_REQUEST_ERROR on error.
456
/// # Safety
457
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
458
#[no_mangle]
459
37.4M
pub unsafe extern "C" fn htp_tx_request_progress(tx: *const Transaction) -> HtpRequestProgress {
460
37.4M
    tx.as_ref()
461
37.4M
        .map(|tx| tx.request_progress)
462
37.4M
        .unwrap_or(HtpRequestProgress::ERROR)
463
37.4M
}
464
465
/// Get the transaction's response progress.
466
///
467
/// tx: Transaction pointer.
468
///
469
/// Returns the progress or ERROR on error.
470
/// # Safety
471
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
472
#[no_mangle]
473
88.0M
pub unsafe extern "C" fn htp_tx_response_progress(tx: *const Transaction) -> HtpResponseProgress {
474
88.0M
    tx.as_ref()
475
88.0M
        .map(|tx| tx.response_progress)
476
88.0M
        .unwrap_or(HtpResponseProgress::ERROR)
477
88.0M
}
478
479
/// Get the data's transaction.
480
///
481
/// Returns the transaction or NULL on error.
482
/// # Safety
483
/// When calling this method, you have to ensure that data is either properly initialized or NULL
484
#[no_mangle]
485
11.6M
pub unsafe extern "C" fn htp_tx_data_tx(data: *const Data) -> *const Transaction {
486
11.6M
    data.as_ref()
487
11.6M
        .map(|data| data.tx() as *const Transaction)
488
11.6M
        .unwrap_or(std::ptr::null())
489
11.6M
}
490
491
/// Get the data pointer.
492
///
493
/// Returns the data or NULL on error.
494
/// # Safety
495
/// When calling this method, you have to ensure that data is either properly initialized or NULL
496
#[no_mangle]
497
8.11M
pub unsafe extern "C" fn htp_tx_data_data(data: *const Data) -> *const u8 {
498
8.11M
    data.as_ref()
499
8.11M
        .map(|data| data.data())
500
8.11M
        .unwrap_or(std::ptr::null())
501
8.11M
}
502
503
/// Get the length of the data.
504
///
505
/// Returns the length or -1 on error.
506
/// # Safety
507
/// When calling this method, you have to ensure that data is either properly initialized or NULL
508
#[no_mangle]
509
11.8M
pub unsafe extern "C" fn htp_tx_data_len(data: *const Data) -> isize {
510
11.8M
    data.as_ref()
511
11.8M
        .map(|data| isize::try_from(data.len()).unwrap_or(-1))
512
11.8M
        .unwrap_or(-1)
513
11.8M
}
514
515
/// Get whether this data is empty.
516
///
517
/// Returns true if data is NULL or zero-length.
518
/// # Safety
519
/// When calling this method, you have to ensure that data is either properly initialized or NULL
520
#[no_mangle]
521
8.88M
pub unsafe extern "C" fn htp_tx_data_is_empty(data: *const Data) -> bool {
522
8.88M
    data.as_ref().map(|data| data.is_empty()).unwrap_or(true)
523
8.88M
}