]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http2: faster when reducing dynamic headers size 8688/head
authorPhilippe Antoine <pantoine@oisf.net>
Thu, 16 Mar 2023 08:20:40 +0000 (09:20 +0100)
committerVictor Julien <vjulien@oisf.net>
Wed, 5 Apr 2023 16:13:58 +0000 (18:13 +0200)
avoid quadratic complexity from removing the first element
and copying all the contents a big number fo times.

Ticket: #5909

rust/src/http2/parser.rs

index 6ed570e09acf2b3341aee0250168940410c059de..7c8c88101eb0bb3917e4f21f49a88289fffaf92f 100644 (file)
@@ -456,7 +456,8 @@ fn http2_parse_headers_block_literal_incindex<'a>(
                 } else {
                     dyn_headers.table.push(headcopy);
                 }
-                while dyn_headers.current_size > dyn_headers.max_size && !dyn_headers.table.is_empty()
+                while dyn_headers.current_size > dyn_headers.max_size
+                    && !dyn_headers.table.is_empty()
                 {
                     dyn_headers.current_size -=
                         32 + dyn_headers.table[0].name.len() + dyn_headers.table[0].value.len();
@@ -539,13 +540,16 @@ fn http2_parse_headers_block_dynamic_size<'a>(
     if (maxsize2 as usize) < dyn_headers.max_size {
         //dyn_headers.max_size is updated later with all headers
         //may evict entries
-        while dyn_headers.current_size > (maxsize2 as usize) && !dyn_headers.table.is_empty() {
+        let mut toremove = 0;
+        while dyn_headers.current_size > (maxsize2 as usize) && toremove < dyn_headers.table.len() {
             // we check dyn_headers.table as we may be in best effort
             // because the previous maxsize was too big for us to retain all the headers
-            dyn_headers.current_size -=
-                32 + dyn_headers.table[0].name.len() + dyn_headers.table[0].value.len();
-            dyn_headers.table.remove(0);
+            dyn_headers.current_size -= 32
+                + dyn_headers.table[toremove].name.len()
+                + dyn_headers.table[toremove].value.len();
+            toremove += 1;
         }
+        dyn_headers.table.drain(0..toremove);
     }
     return Ok((
         i3,