summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/mitm-cache-head-requests.patch
blob: 5e641c01b5e4054aa75d0f58d7b3f81e430809f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Upstream-status: <https://github.com/chayleaf/mitm-cache/pull/5>

diff --git a/src/main.rs b/src/main.rs
index d9f760f..215ed89 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
 use base64::Engine;
 use clap::{Parser, Subcommand};
+use futures_util::StreamExt;
 use http_body_util::BodyExt;
 use hudsucker::{
     certificate_authority::RcgenAuthority,
@@ -11,6 +12,7 @@ use hudsucker::{
     tokio_tungstenite::tungstenite::http::uri::Scheme,
     Body, HttpContext, HttpHandler, Proxy, RequestOrResponse,
 };
+use hyper::Method;
 use hyper::{StatusCode, Uri};
 use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
 use hyper_util::{
@@ -137,11 +139,15 @@ impl HttpHandler for Handler {
                             "GET" | "POST" | "HEAD" => {
                                 let original_url = req.uri().clone();
                                 println!("{req:?}");
-                                let Ok(req) = decode_request(req) else {
+                                let Ok(mut req) = decode_request(req) else {
                                     let mut res = Response::new("not found".into());
                                     *res.status_mut() = StatusCode::NOT_FOUND;
                                     return res.into();
                                 };
+                                let is_head_request = req.method() == "HEAD";
+                                if is_head_request {
+                                    *req.method_mut() = Method::GET;
+                                }
                                 let (info, body) = req.into_parts();
                                 let Ok(req_body) = body.collect().await.map(|x| x.to_bytes())
                                 else {
@@ -165,7 +171,7 @@ impl HttpHandler for Handler {
                                         req_body
                                     )])),
                                 );
-                                let store_body_info = req.method() != "HEAD";
+                                let store_body_info = true;
                                 let url = process_uri(original_url);
                                 if matches!(forget_regex, Some(x) if x.is_match(&url.to_string())) {
                                     forget = true;
@@ -307,7 +313,20 @@ impl HttpHandler for Handler {
                                             }
                                         }
                                     });
-                                    Response::from_parts(info, ret_body)
+                                    if is_head_request {
+                                        // For HEAD requests, drain the channel
+                                        // output; otherwise rx will be dropped,
+                                        // which closes the channel and causes
+                                        // the tx.poll_ready call above to
+                                        // return an error
+                                        let mut stream = ret_body.into_data_stream();
+                                        while let Some(_) = stream.next().await {
+                                            // do nothing
+                                        }
+                                        Response::from_parts(info, Body::empty())
+                                    } else {
+                                        Response::from_parts(info, ret_body)
+                                    }
                                 } else {
                                     // remove hash headers to force the software to download this
                                     // so we get sha256