Skip to content

Commit

Permalink
Use rule file
Browse files Browse the repository at this point in the history
  • Loading branch information
zu1k committed Sep 14, 2021
1 parent adb3ccc commit b9dfca7
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 26 deletions.
87 changes: 87 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ codegen-units = 1

[dependencies]
bytes = { version = "1", features = ["serde"] }
clap = "2.33.3"
env_logger = "0.9"
fancy-regex = "0.7"
hudsucker = "0.4"
lazy_static = "1.4"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
tokio = { version = "1", features = ["full"] }

[dev-dependencies]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Adding `http` and `https` proxies to the browser, `http://127.0.0.1:34567` if no

Now I add two demo websites, removing ADs using good-MITM `rewrite` feature.

You should use the demo rule file, `good-mitm.exe -f demo.yaml`

See the effect by comparing the content(ads) with and without using `good-MITM`.

- [低端影视](https://ddrk.me/)
Expand Down
23 changes: 23 additions & 0 deletions assets/rules/demo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- name: "奈菲影视去广告"
filter:
url-regex: '(nfmovies)(?!.*?(\.css|\.js|\.jpeg|\.png|\.gif)).*'
action:
modify:
body:
origin: '<head>'
new: '<link rel="stylesheet" href="https://limbopro.com/CSS/nfmovies.css" type="text/css"><script type="text/javascript" src="//limbopro.com/Adguard/nfmovies.js"></script></head>'

- name: "低端影视去广告"
filter:
url-regex: '^https:?/\/ddrk.me.*'
action:
modify:
body:
origin: '<head>'
new: '<head><link rel="stylesheet" href="https://limbopro.com/CSS/ddrk.css" type="text/css"><script type="text/javascript" src="//limbopro.com/Adguard/ddrk.js"></script>'

- name: "跳转博客"
filter:
domain: 'none.lgf.im'
action:
redirect: "https://lgf.im/"
8 changes: 3 additions & 5 deletions src/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ pub use modify::*;

use hudsucker::hyper::{header, header::HeaderValue, Body, Request, Response, StatusCode};
use hudsucker::RequestOrResponse;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum Action {
Reject,
Redirect(String),
Modify(Modify),
}

impl Action {
pub fn new() -> Self {
Self::Redirect("https://lgf.im/".into())
}

pub async fn do_req(&self, req: Request<Body>) -> RequestOrResponse {
match self {
Action::Reject => {
Expand Down
22 changes: 6 additions & 16 deletions src/action/modify.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
use hudsucker::hyper::{body::*, header, Body, Request, Response, StatusCode};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct BodyModify {
pub origin: String,
pub new: String,
}

impl BodyModify {
pub fn new(origin: &str, new: &str) -> Self {
Self {
origin: String::from(origin),
new: String::from(new),
}
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum Modify {
Header,
Cookie,
Body(BodyModify),
}

impl Modify {
pub fn new_modify_body(origin: &str, new: &str) -> Self {
Self::Body(BodyModify::new(origin, new))
}

pub async fn modify_req(&self, req: Request<Body>) -> Request<Body> {
match self {
Modify::Body(bm) => req,
Modify::Body(_bm) => req,
_ => req,
}
}
Expand Down
30 changes: 28 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod filter;
mod handler;
mod rule;

use clap::{App, Arg};
use hudsucker::{rustls::internal::pemfile, *};
use log::*;
use std::net::SocketAddr;
Expand All @@ -17,9 +18,9 @@ async fn shutdown_signal() {
}

#[tokio::main]
async fn main() {
async fn run() {
env_logger::init();
rule::add_rule_examples();
// rule::add_rule_examples_internal();

let mut private_key_bytes: &[u8] = include_bytes!("../assets/ca/private.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("../assets/ca/cert.crt");
Expand Down Expand Up @@ -47,3 +48,28 @@ async fn main() {
error!("{}", e);
}
}

fn main() {
let matches = App::new("Good Man in the Middle")
.author("zu1k <i@lgf.im>")
.about("Use MITM technology to provide features like rewrite, redirect.")
.arg(
Arg::with_name("rule")
.short("f")
.long("rule")
.help("rule file")
.long_help("load rules from file")
.takes_value(true)
.required(true),
)
.get_matches();

let rule_file = matches
.value_of("rule")
.expect("rule file path should not be none");
if let Err(err) = rule::add_rule_file(rule_file) {
error!("parse rule file failed, err: {}", err);
std::process::exit(3);
}
run()
}
66 changes: 66 additions & 0 deletions src/rule/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::action;
use serde::{Deserialize, Serialize};
use std::error::Error;
use std::path::Path;
use std::{fs::File, io::BufReader};

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Rule {
pub name: String,
pub filter: Filter,
pub action: action::Action,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum Filter {
Domain(String),
DomainKeyword(String),
DomainPrefix(String),
DomainSuffix(String),
UrlRegex(String),
}

pub fn read_rules_from_file<P: AsRef<Path>>(path: P) -> Result<Vec<Rule>, Box<dyn Error>> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let rules = serde_yaml::from_reader(reader)?;
Ok(rules)
}

#[test]
fn test_gen_yaml() {
let rules = vec![
Rule {
name: "demo rule 1".into(),
filter: Filter::Domain("domain.com".into()),
action: action::Action::Modify(action::Modify::new_modify_body(
"origin body",
"new body",
)),
},
Rule {
name: "demo rule 2".into(),
filter: Filter::UrlRegex(r".*\.domain.com".into()),
action: action::Action::Modify(action::Modify::new_modify_body(
"origin body",
"new body",
)),
},
];

let s = serde_yaml::to_string(&rules).expect("serde yaml failed!");
println!("{}", s);

let f = include_str!("../../assets/rules/demo.yaml");
let rules: Vec<Rule> = serde_yaml::from_str(f).expect("parse failed!");
println!("{:#?}", rules);
if let Filter::UrlRegex(r) = rules[0].clone().filter {
println!("{}", r)
}

// match read_rules_from_file("assets/rules/demo.yaml") {
// Ok(rules) => println!("{:#?}", rules),
// Err(err) => panic!("{}", err),
// }
}
Loading

0 comments on commit b9dfca7

Please sign in to comment.