omjadas / hudsucker

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

How to set whitelist url not proxy by hudsucker ? #114

Open songjiachao opened 1 month ago

songjiachao commented 1 month ago

whitelist or blacklist config for hudsucker

omjadas commented 1 month ago

The should_intercept method of the HttpHandler trait can be used to determine whether a CONNECT request should be intercepted. Most applications will also allow you to bypass a configured proxy for certain domains using a no_proxy setting.

songjiachao commented 1 month ago

I add should_intercept config like *.gamecenter.com , I just can visit www.gamecenter.com. I visit other website, got the error

image
omjadas commented 1 month ago

Could you please share your implementation of should_intercept?

omjadas commented 1 month ago

Also, are you able to visit those websites when not using the proxy?

songjiachao commented 1 month ago
  fn should_intercept(&mut self, _ctx: &HttpContext, req: &Request<Body>) -> impl Future<Output = bool> + Send {
    let config = get_config();
    let white_domain_list = config.proxy.white_domain_list;
    let black_domain_list = config.proxy.black_domain_list;
    let authority = req.uri().authority().unwrap().to_string();
    let host = authority.split(':').next().unwrap_or(authority.as_str());

    // 优先白名单
    let flag = if !white_domain_list.is_empty() {
      let mut builder = GlobSetBuilder::new();
      white_domain_list.split(";").for_each(|domain| {
        if let Ok(domain) = Glob::new(domain) {
          builder.add(domain);
        } else {
          error!("White domain list parse error: {}", domain);
        }
      });
      match builder.build() {
        Ok(set) => set.is_match(host),
        Err(_) => true,
      }
    } else if !black_domain_list.is_empty() {
      let mut builder = GlobSetBuilder::new();
      black_domain_list.split(";").for_each(|domain| {
        if let Ok(domain) = Glob::new(domain) {
          builder.add(domain);
        } else {
          error!("Black domain list parse error: {}", domain);
        }
      });
      match builder.build() {
        Ok(set) => !set.is_match(host),
        Err(_) => true,
      }
    } else {
      true
    };
    async move { flag }
  }
}
songjiachao commented 1 month ago

I set the whitelist ".vmic.xyz" ,means that only .vmic.xyz should_intercept return true, other website return false. I just can visit xxx.vmic,xyz. Ohter website got the error [2024-06-04][11:19:55][ERROR][mitm::proxy::internal] HTTPS connect error: connection error, www.google.com:443

I delete the white_domain_list config and set all the website should_intercept return true . can visit

songjiachao commented 1 month ago

May be this code Just Reford the req without do anything.Got the error :Failed to tunnel to filters.adtidy.org:443: Connection reset by peer (os error 54)

let mut server = match TcpStream::connect(authority.as_ref()).await {
        Ok(server) => server,
        Err(e) => {
            error!("Failed to connect to: {}, {}", e, req.uri());
            return;
        }
    };

    if let Err(e) =
        tokio::io::copy_bidirectional(&mut upgraded, &mut server).await
    {
        error!("Failed to tunnel to {}: {}", authority, e);
    }

image

image

omjadas commented 1 month ago

Could you try just returning false from should_intercept? Could you also share your handle_request implementation?

songjiachao commented 1 month ago

Could you try just returning false from should_intercept? YES, you can try it.

omjadas commented 1 month ago

Could you try just returning false from should_intercept? YES, you can try it.

The reason I am asking is because when I return false from should_intercept it works as expected. So I am trying to figure out if there is something going on with your setup that could be causing the issue, but want to try and eliminate as many variables as possible.