omjadas / hudsucker

Intercepting HTTP/S proxy
https://crates.io/crates/hudsucker
Apache License 2.0
205 stars 34 forks source link

Failed to forward request: client requires absolute-form URIs #103

Closed doublepithre closed 5 months ago

doublepithre commented 5 months ago

When attempting to execute the log example within the package on Windows, the error mentioned above is encountered. I've attempted importing the certificate into the Trust Root Certificates, yet the issue persists. The proxy is returning a 502 Bad Gateway error.

Could I be overlooking something?

I tried making the requests from chrome browser with proxy set to the hudsucker server:port

omjadas commented 5 months ago

Few questions:

What version of Windows are you using? What version of Chrome are you using? Are you running the log example on the main branch? If so, could you also try the latest tagged version (https://github.com/omjadas/hudsucker/tree/v0.21.0)?

doublepithre commented 5 months ago

@omjadas thanks so much for the quick response.

I'm running the log example from the stable v0.21.0 (from crate)

Windows: 11 Chrome: Version 122.0.6261.112 (Official Build) (64-bit)

Cargo.toml

[package]
name = "huduse"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
hudsucker = { version = "0.21.0", features = ["default"] }
rcgen = "0.12.1"
reqwest = "0.11.10"
rustls-pemfile = "2.0.0"
tokio = { version = "1.24.2", features = ["full"] }
tracing = { version = "0.1.40", features = ["log"] }
tracing-subscriber = "0.3.8"

main.rs

use hudsucker::{
    async_trait::async_trait,
    certificate_authority::RcgenAuthority,
    hyper::{Body, Request, Response},
    *,
};
use rustls_pemfile as pemfile;
use std::net::SocketAddr;
use tracing::*;

async fn shutdown_signal() {
    tokio::signal::ctrl_c()
        .await
        .expect("Failed to install CTRL+C signal handler");
}

#[derive(Clone)]
struct LogHandler;

#[async_trait]
impl HttpHandler for LogHandler {
    async fn handle_request(
        &mut self,
        _ctx: &HttpContext,
        req: Request<Body>,
    ) -> RequestOrResponse {
        println!(" {:?}", req);
        req.into()
    }

    async fn handle_response(&mut self, _ctx: &HttpContext, res: Response<Body>) -> Response<Body> {
        println!("RES::: {:?}", res);
        res
    }
}

#[tokio::main]
async fn main() {

    tracing_subscriber::fmt::init();

    let mut private_key_bytes: &[u8] = include_bytes!("ca/rpai.key");
    let mut ca_cert_bytes: &[u8] = include_bytes!("ca/rpai.pem");
    let private_key = rustls::PrivateKey(
        pemfile::pkcs8_private_keys(&mut private_key_bytes)
            .next()
            .unwrap()
            .expect("Failed to parse private key")
            .secret_pkcs8_der()
            .to_vec(),
    );
    let ca_cert = rustls::Certificate(
        pemfile::certs(&mut ca_cert_bytes)
            .next()
            .unwrap()
            .expect("Failed to parse CA certificate")
            .to_vec(),
    );

    let ca = RcgenAuthority::new(private_key, ca_cert, 1_000)
        .expect("Failed to create Certificate Authority");
    let proxy = Proxy::builder()
        .with_addr(SocketAddr::from(([127, 0, 0, 1], 6070)))
        .with_rustls_client()
        .with_ca(ca)
        .with_http_handler(LogHandler)
        .build();

    if let Err(e) = proxy.start(shutdown_signal()).await {
        error!("{}", e);
    }
}
omjadas commented 5 months ago

What site are you navigating to in Chrome that causes the error?

doublepithre commented 5 months ago

I tried different websites. Few of them are:

1) https://www.wikipedia.org/ 2) https://crates.io/

Also, I tried proxy url itself

doublepithre commented 5 months ago

I'm using this Proxy Extension on chrome browser

omjadas commented 5 months ago

I am having trouble reproducing the issue. Using the Cargo.toml and main.rs files you provided with the same Chrome extension on Windows, everything seems to be working for me. Could you let me know what version of Rust you are using to build your project? Would you also be able to try the same thing with Firefox? And just to confirm, you are using those exact same Cargo.toml and main.rs files yourself?

doublepithre commented 5 months ago

Rust Version : rustup 1.26.0 (5af9b9484 2023-04-05)

Yes, using the same files. It worked in Firefox. Not sure, what's with Chrome. Let me try again. Thanks for the help.

Aside: I was trying to intercept a particular URL and write the response to file and post the same response to some other API. Can we do this ?

omjadas commented 5 months ago

Would you be able to share a list of all the other Chrome extensions you have installed? Also, have you enabled/disabled any Chrome flags?

In regards to your query, that should definitely be possible.

doublepithre commented 5 months ago

In regards to your query, that should definitely be possible. Great! I will try to do it.

Would you be able to share a list of all the other Chrome extensions you have installed? Also, have you enabled/disabled any Chrome flags?

I tried to open the chrome browser with Proxy server argument, may be this is the issue.

"C:\Program Files\Google\Chrome\Application\chrome.exe" --profile-directory="Profile1" --proxy-server="127.0.0.1:6070"

Thanks for the help

omjadas commented 5 months ago

Just to confirm, are you saying that it worked when using the --proxy-server argument?

doublepithre commented 5 months ago

With --proxy-server argument, the traffic is not intercepted, I might be doing something wrong. If I use extension with latest Rust version, proxy chrome extension and with latest stable hudsucker crate, it's working.

omjadas commented 5 months ago

When you specify --proxy-server, do you also have the extension enabled? If so, they may be conflicting with each other.

When I use the --proxy-server argument myself, I can see traffic coming through.

doublepithre commented 5 months ago

Yes, that's the root cause. I tried to use only Proxy chrome extension. It worked. Thanks for the help