0

I have implemented a reverse proxy with hyper-rustls and tokio. It works as intended when I use it against a non-https site, but when it hits a https host I get this from curl:

curl: (52) Empty reply from server

Structs

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Hive {
    path: String,
    hive: Option<String>,
    host: Option<String>,
    route: Option<String>,
    java: Option<bool>,
}

impl Hive {
    fn new() -> Hive {
        Hive {
            path: String::from(""),
            hive: Option::from(String::from("")),
            host: Option::from(String::from("")),
            route: Option::from(String::from("")),
            java: Option::from(false)
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
struct Hives {
    local_hives: Vec<Hive>,
    remote_hives: Vec<Hive>,
    critical_hives: Vec<Hive>,
}

impl Hives {
    fn new() -> Hives {

        Hives {
            local_hives: Vec::new(),
            remote_hives: Vec::new(),
            critical_hives: Vec::new()
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
struct ServerObject {
    https: Option<bool>,
    name: String,
    host: String,
    port: String,
    hives: Hives,
}

impl ServerObject {
    fn new() -> ServerObject {

        ServerObject {
            hives: Hives::new(),
            https: Option::from(false),
            name: String::from(""),
            host: String::from(""),
            port: String::from("")
        }
    }
}

#[derive(Serialize, Deserialize)]
struct List  {
    servers: Vec<ServerObject>,
}

the code is pretty simple, but for some reason it does not work...

// current_server is a json with config about routes and host url

let connector = hyper_rustls::HttpsConnectorBuilder::new()
                .with_native_roots()
                .https_or_http()
                .enable_http1()
                .build();

let client: Client<_, hyper::Body> = Client::builder().build(connector);

let client: Arc<Client<_, hyper::Body>> = Arc::new(client);

let make_service = make_service_fn(move |_| {

    let current_server = current_server.clone();

    let client = Arc::clone(&client);

    async move {

        let client = Arc::clone(&client);

        Ok::<_, Infallible>(
            service_fn(move |req| {
                
                let client = Arc::clone(&client);

                handle(req, current_server.clone(), client)
            })
        )
        
    }
});

handle is a bit more complicated.. but in essense this is the part that does the reverse proxy

async fn handle(
    mut req: Request<Body>, 
    server: Arc<ServerObject>, 
    client: Arc<hyper::Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>>
) -> Result<hyper::Response<hyper::Body>, Infallible> {

    let headers = req.headers_mut();

    headers.insert("cache-control", HeaderValue::from_static("no-store"));
    headers.insert("service-worker-allowed", HeaderValue::from_static("/"));
    
    let uri = req.uri();
    
    let uri_str = match uri.query() {
        None => format!("{}{}", server.host, uri.path()),
        Some(query) => format!("{}{}?{}", server.host, uri.path(), query),
    };
    
    *req.uri_mut() = uri_str.parse().unwrap();


    match client.request(req).await {
        Ok(response) => {
            Ok(response)
        },
        Err(err) =>{
            println!("Error {}", err);
            Ok(hyper::Response::builder()
                                .status(hyper::StatusCode::INTERNAL_SERVER_ERROR)
                                .body(Body::empty())
                                .unwrap())
        }
    }
}

Here is the request headers from the call:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: da,en;q=0.9,en-GB;q=0.8,en-US;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: sys_sesid="2022-02-12-11.58.41.684888"
Host: localhost:4001
Pragma: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Microsoft Edge";v="98"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 Edg/98.0.1108.43

Why does this happen and how can I fix it?

  • Welcome to StackOverflow! Sorry for the late response, I've adjusted the title and tags so hopefully your question reaches the right people. Your code sample is missing the configuration of hyper-rustls which could be the problem or at least would provide a [reproducible example](/help/minimal-reproducible-example). – kmdreko Sep 22 '22 at 15:38
  • Hi @kmdreko Thanks for the response :-) I have updated the description, so i contains more info on the subject :-) i hope this will help with the question :-) – Peter Nøbbe Sep 23 '22 at 19:41

0 Answers0