qpack: avoid multiple copies when decoding literals

When literal names and values are decoded, they are additionally cloned
when Header::new() is called. However in many cases these values are
already of type String, which means that the additional clone is
unnecessary, so try to create Header objects directly when possible to
avoid such clones.

In the case of literal names, the source buffer was additionally cloned
in case of plain strings (i.e. not huffman-encoded), so avoid that as
well.
diff --git a/src/h3/qpack/decoder.rs b/src/h3/qpack/decoder.rs
index c89e380..3bcc9d7 100644
--- a/src/h3/qpack/decoder.rs
+++ b/src/h3/qpack/decoder.rs
@@ -124,7 +124,8 @@
                         .checked_sub((name.len() + value.len()) as u64)
                         .ok_or(Error::HeaderListTooLarge)?;
 
-                    out.push(Header::new(&name, &value));
+                    let hdr = Header::new(name, value);
+                    out.push(hdr);
                 },
 
                 Representation::IndexedWithPostBase => {
@@ -141,27 +142,35 @@
                     let name_len = decode_int(&mut b, 3)? as usize;
 
                     let mut name = b.get_bytes(name_len)?;
+
                     let name = if name_huff {
-                        super::huffman::decode(&mut name)?
+                        let name = super::huffman::decode(&mut name, true)?;
+
+                        String::from_utf8(name)
+                            .map_err(|_| Error::InvalidHeaderValue)?
                     } else {
-                        name.to_vec()
+                        let name = std::str::from_utf8(name.as_ref())
+                            .map_err(|_| Error::InvalidHeaderValue)?;
+
+                        name.to_ascii_lowercase()
                     };
 
-                    let name = String::from_utf8(name)
-                        .map_err(|_| Error::InvalidHeaderValue)?;
                     let value = decode_str(&mut b)?;
 
                     trace!(
                         "Literal Without Name Reference name={:?} value={:?}",
                         name,
-                        value
+                        value,
                     );
 
                     left = left
                         .checked_sub((name.len() + value.len()) as u64)
                         .ok_or(Error::HeaderListTooLarge)?;
 
-                    out.push(Header::new(&name, &value));
+                    // Instead of calling Header::new(), create Header directly
+                    // from `name` and `value`, which are already String.
+                    let hdr = Header(name, value);
+                    out.push(hdr);
                 },
 
                 Representation::LiteralWithNameRef => {
@@ -189,7 +198,11 @@
                         .checked_sub((name.len() + value.len()) as u64)
                         .ok_or(Error::HeaderListTooLarge)?;
 
-                    out.push(Header::new(name, &value));
+                    // Instead of calling Header::new(), create Header directly
+                    // from `value`, which is already String, but clone `name`
+                    // as it is just a reference.
+                    let hdr = Header(name.to_string(), value);
+                    out.push(hdr);
                 },
 
                 Representation::LiteralWithPostBase => {
@@ -254,7 +267,7 @@
     let mut val = b.get_bytes(len)?;
 
     let val = if huff {
-        super::huffman::decode(&mut val)?
+        super::huffman::decode(&mut val, false)?
     } else {
         val.to_vec()
     };
diff --git a/src/h3/qpack/huffman/mod.rs b/src/h3/qpack/huffman/mod.rs
index 3a6ff06..996de72 100644
--- a/src/h3/qpack/huffman/mod.rs
+++ b/src/h3/qpack/huffman/mod.rs
@@ -32,7 +32,7 @@
 use self::table::DECODE_TABLE;
 use self::table::ENCODE_TABLE;
 
-pub fn decode(b: &mut octets::Octets) -> Result<Vec<u8>> {
+pub fn decode(b: &mut octets::Octets, low: bool) -> Result<Vec<u8>> {
     // Max compression ratio is >= 0.5
     let mut out = Vec::with_capacity(b.len() << 1);
 
@@ -42,10 +42,12 @@
         let byte = b.get_u8()?;
 
         if let Some(b) = decoder.decode4(byte >> 4)? {
+            let b = if low { b.to_ascii_lowercase() } else { b };
             out.push(b);
         }
 
         if let Some(b) = decoder.decode4(byte & 0xf)? {
+            let b = if low { b.to_ascii_lowercase() } else { b };
             out.push(b);
         }
     }