--- src/lib.rs.before
+++ src/lib.rs.experiment
@@ -196,6 +196,7 @@
     date_at: Cell<u64>,
     read_buffer: RefCell<Vec<u8>>,
     header_names: RefCell<HashMap<Vec<u8>, Py<PyBytes>>>,
+    header_pairs: RefCell<HashMap<Vec<u8>, Py<pyo3::types::PyTuple>>>,
 }
 impl State {
     fn id(&self) -> u64 {
@@ -537,7 +538,10 @@
         )?;
         let headers = PyList::new(
             py,
-            h.headers().map(|(n, v)| {
+            h.headers().map(|(n, v, key)| {
+                if let Some(pair) = self.header_pairs.borrow().get(key) {
+                    return pair.clone_ref(py);
+                }
                 let cached = self.header_names.borrow().get(n).map(|v| v.clone_ref(py));
                 let name = if let Some(name) = cached {
                     name
@@ -550,7 +554,16 @@
                     }
                     name
                 };
-                (name, PyBytes::new(py, v))
+                let pair = (name, PyBytes::new(py, v))
+                    .into_pyobject(py)
+                    .expect("tuple construction")
+                    .unbind();
+                if key.len() <= 256 && self.header_pairs.borrow().len() < 512 {
+                    self.header_pairs
+                        .borrow_mut()
+                        .insert(key.to_vec(), pair.clone_ref(py));
+                }
+                pair
             }),
         )?;
         scope.set_item(pyo3::intern!(py, "headers"), headers)?;
@@ -1271,6 +1284,7 @@
                 date_at: Cell::new(0),
                 read_buffer: RefCell::new(vec![0; 65536]),
                 header_names: RefCell::new(HashMap::new()),
+                header_pairs: RefCell::new(HashMap::new()),
             }),
         })
     }
--- src/http.rs.before
+++ src/http.rs.experiment
@@ -41,10 +41,14 @@
     pub fn target(&self) -> &[u8] {
         &self.wire[self.target.clone()]
     }
-    pub fn headers(&self) -> impl ExactSizeIterator<Item = (&[u8], &[u8])> {
-        self.fields
-            .iter()
-            .map(|(n, v)| (&self.wire[n.clone()], &self.wire[v.clone()]))
+    pub fn headers(&self) -> impl ExactSizeIterator<Item = (&[u8], &[u8], &[u8])> {
+        self.fields.iter().map(|(n, v)| {
+            (
+                &self.wire[n.clone()],
+                &self.wire[v.clone()],
+                &self.wire[n.start..v.end],
+            )
+        })
     }
 }
 pub enum Body {
@@ -203,9 +207,9 @@
         }
         fields.retain(|(n, _)| &wire[n.clone()] != b"host");
         let start = wire.len();
-        wire.extend_from_slice(b"host");
+        wire.extend_from_slice(b"host:");
         wire.extend_from_slice(authority);
-        fields.insert(0, (start..start + 4, start + 4..wire.len()));
+        fields.insert(0, (start..start + 4, start + 5..wire.len()));
         let path = &rest[n..];
         target_span = if path.is_empty() || path[0] == b'?' {
             let start = wire.len();
