switch to using clap v4

pull/383/head
Sunshine 2 weeks ago
parent a3feb7b721
commit c85220bb61
No known key found for this signature in database
GPG Key ID: 1C850498C410353C

157
Cargo.lock generated

@ -56,12 +56,55 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "assert_cmd"
version = "2.0.14"
@ -228,28 +271,50 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.25"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"atty",
"bitflags 1.3.2",
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"indexmap 1.9.3",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
name = "clap_derive"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"os_str_bytes",
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "core-foundation"
version = "0.9.4"
@ -522,7 +587,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap 2.2.6",
"indexmap",
"slab",
"tokio",
"tokio-util",
@ -531,15 +596,15 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.12.3"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.14.5"
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
@ -668,16 +733,6 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.2.6"
@ -685,7 +740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown 0.14.5",
"hashbrown",
]
[[package]]
@ -694,6 +749,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "itoa"
version = "1.0.11"
@ -919,12 +980,6 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "os_str_bytes"
version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "parking_lot"
version = "0.12.2"
@ -1395,9 +1450,9 @@ dependencies = [
[[package]]
name = "strsim"
version = "0.10.0"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
@ -1460,27 +1515,12 @@ dependencies = [
"utf-8",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "termtree"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1609,6 +1649,12 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "vcpkg"
version = "0.2.15"
@ -1737,15 +1783,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"

@ -25,7 +25,7 @@ license = "CC0-1.0"
atty = "0.2.14" # Used for highlighting network errors
base64 = "0.22.1" # Used for integrity attributes
chrono = "0.4.38" # Used for formatting output timestamp
clap = "3.2.25" # Used for processing CLI arguments
clap = { version = "4.5.4", features = ["derive"] }
cssparser = "0.34.0" # Used for dealing with CSS
encoding_rs = "0.8.34" # Used for parsing and converting document charsets
html5ever = "0.27.0" # Used for all things DOM

@ -5,6 +5,7 @@ use reqwest::blocking::Client;
use std::collections::HashMap;
use url::Url;
use crate::cookies::Cookie;
use crate::opts::Options;
use crate::url::{create_data_url, resolve_url, EMPTY_IMAGE_DATA_URL};
use crate::utils::retrieve_asset;
@ -36,6 +37,7 @@ pub fn embed_css(
document_url: &Url,
css: &str,
options: &Options,
cookies: &Vec<Cookie>
) -> String {
let mut input = ParserInput::new(&css);
let mut parser = Parser::new(&mut input);
@ -46,6 +48,7 @@ pub fn embed_css(
document_url,
&mut parser,
options,
cookies,
"",
"",
"",
@ -79,6 +82,7 @@ pub fn process_css<'a>(
document_url: &Url,
parser: &mut Parser,
options: &Options,
cookies: &Vec<Cookie>,
rule_name: &str,
prop_name: &str,
func_name: &str,
@ -132,6 +136,7 @@ pub fn process_css<'a>(
document_url,
parser,
options,
cookies,
rule_name,
curr_prop.as_str(),
func_name,
@ -186,7 +191,7 @@ pub fn process_css<'a>(
}
let import_full_url: Url = resolve_url(&document_url, value);
match retrieve_asset(cache, client, &document_url, &import_full_url, options) {
match retrieve_asset(cache, client, &document_url, &import_full_url, options, cookies) {
Ok((
import_contents,
import_final_url,
@ -202,6 +207,7 @@ pub fn process_css<'a>(
&import_final_url,
&String::from_utf8_lossy(&import_contents),
options,
cookies,
)
.as_bytes(),
&import_final_url,
@ -239,6 +245,7 @@ pub fn process_css<'a>(
&document_url,
&resolved_url,
options,
cookies,
) {
Ok((data, final_url, media_type, charset)) => {
let mut data_url =
@ -328,7 +335,7 @@ pub fn process_css<'a>(
result.push_str("url(");
if is_import {
let full_url: Url = resolve_url(&document_url, value);
match retrieve_asset(cache, client, &document_url, &full_url, options) {
match retrieve_asset(cache, client, &document_url, &full_url, options, cookies) {
Ok((css, final_url, media_type, charset)) => {
let mut data_url = create_data_url(
&media_type,
@ -339,6 +346,7 @@ pub fn process_css<'a>(
&final_url,
&String::from_utf8_lossy(&css),
options,
cookies,
)
.as_bytes(),
&final_url,
@ -359,7 +367,7 @@ pub fn process_css<'a>(
result.push_str(format_quoted_string(EMPTY_IMAGE_DATA_URL).as_str());
} else {
let full_url: Url = resolve_url(&document_url, value);
match retrieve_asset(cache, client, &document_url, &full_url, options) {
match retrieve_asset(cache, client, &document_url, &full_url, options, cookies) {
Ok((data, final_url, media_type, charset)) => {
let mut data_url =
create_data_url(&media_type, &charset, &data, &final_url);
@ -395,6 +403,7 @@ pub fn process_css<'a>(
document_url,
parser,
options,
cookies,
curr_rule.as_str(),
curr_prop.as_str(),
function_name,

@ -15,6 +15,7 @@ use sha2::{Digest, Sha256, Sha384, Sha512};
use std::collections::HashMap;
use std::default::Default;
use crate::cookies::Cookie;
use crate::css::embed_css;
use crate::js::attr_is_event_handler;
use crate::opts::Options;
@ -165,6 +166,7 @@ pub fn embed_srcset(
document_url: &Url,
srcset: &str,
options: &Options,
cookies: &Vec<Cookie>,
) -> String {
let mut array: Vec<SrcSetItem> = vec![];
let re = Regex::new(r",\s+").unwrap();
@ -185,7 +187,7 @@ pub fn embed_srcset(
result.push_str(EMPTY_IMAGE_DATA_URL);
} else {
let image_full_url: Url = resolve_url(&document_url, part.path);
match retrieve_asset(cache, client, &document_url, &image_full_url, options) {
match retrieve_asset(cache, client, &document_url, &image_full_url, options, cookies) {
Ok((image_data, image_final_url, image_media_type, image_charset)) => {
let mut image_data_url = create_data_url(
&image_media_type,
@ -603,10 +605,11 @@ pub fn retrieve_and_embed_asset(
attr_name: &str,
attr_value: &str,
options: &Options,
cookies: &Vec<Cookie>
) {
let resolved_url: Url = resolve_url(document_url, attr_value);
match retrieve_asset(cache, client, &document_url.clone(), &resolved_url, options) {
match retrieve_asset(cache, client, &document_url.clone(), &resolved_url, options, cookies) {
Ok((data, final_url, mut media_type, charset)) => {
let node_name: &str = get_node_name(&node).unwrap();
@ -635,7 +638,7 @@ pub fn retrieve_and_embed_asset(
if node_name == "link" && determine_link_node_type(node) == "stylesheet" {
// Stylesheet LINK elements require special treatment
let css: String = embed_css(cache, client, &final_url, &s, options);
let css: String = embed_css(cache, client, &final_url, &s, options, cookies);
// Create and embed data URL
let css_data_url =
@ -644,7 +647,7 @@ pub fn retrieve_and_embed_asset(
} else if node_name == "frame" || node_name == "iframe" {
// (I)FRAMEs are also quite different from conventional resources
let frame_dom = html_to_dom(&data, charset.clone());
walk_and_embed_assets(cache, client, &final_url, &frame_dom.document, &options);
walk_and_embed_assets(cache, client, &final_url, &frame_dom.document, &options, &cookies);
let mut frame_data: Vec<u8> = Vec::new();
serialize(
@ -699,12 +702,13 @@ pub fn walk_and_embed_assets(
document_url: &Url,
node: &Handle,
options: &Options,
cookies: &Vec<Cookie>,
) {
match node.data {
NodeData::Document => {
// Dig deeper
for child in node.children.borrow().iter() {
walk_and_embed_assets(cache, client, &document_url, child, options);
walk_and_embed_assets(cache, client, &document_url, child, options, cookies);
}
}
NodeData::Element {
@ -739,6 +743,7 @@ pub fn walk_and_embed_assets(
"href",
&link_attr_href_value,
options,
cookies,
);
} else {
set_node_attr(node, "href", None);
@ -761,6 +766,7 @@ pub fn walk_and_embed_assets(
"href",
&link_attr_href_value,
options,
cookies,
);
}
}
@ -802,6 +808,7 @@ pub fn walk_and_embed_assets(
"background",
&body_attr_background_value,
options,
cookies,
);
}
}
@ -847,6 +854,7 @@ pub fn walk_and_embed_assets(
"src",
&img_full_url,
options,
cookies,
);
}
}
@ -855,7 +863,7 @@ pub fn walk_and_embed_assets(
if let Some(img_srcset) = get_node_attr(node, "srcset") {
if !img_srcset.is_empty() {
let resolved_srcset: String =
embed_srcset(cache, client, &document_url, &img_srcset, options);
embed_srcset(cache, client, &document_url, &img_srcset, options, cookies);
set_node_attr(node, "srcset", Some(resolved_srcset));
}
}
@ -885,6 +893,7 @@ pub fn walk_and_embed_assets(
"src",
&input_attr_src_value,
options,
cookies,
);
}
}
@ -917,6 +926,7 @@ pub fn walk_and_embed_assets(
"href",
&image_href,
options,
cookies,
);
}
}
@ -937,6 +947,7 @@ pub fn walk_and_embed_assets(
"src",
&source_attr_src_value,
options,
cookies,
);
}
} else if parent_node_name == "video" {
@ -951,6 +962,7 @@ pub fn walk_and_embed_assets(
"src",
&source_attr_src_value,
options,
cookies,
);
}
}
@ -972,6 +984,7 @@ pub fn walk_and_embed_assets(
&document_url,
&source_attr_srcset_value,
options,
cookies,
);
set_node_attr(node, "srcset", Some(resolved_srcset));
}
@ -1024,6 +1037,7 @@ pub fn walk_and_embed_assets(
"src",
&script_attr_src.unwrap_or_default(),
options,
cookies,
);
}
}
@ -1041,6 +1055,7 @@ pub fn walk_and_embed_assets(
&document_url,
tendril.as_ref(),
options,
cookies,
);
tendril.clear();
tendril.push_slice(&replacement);
@ -1072,6 +1087,7 @@ pub fn walk_and_embed_assets(
"src",
&frame_attr_src_value,
options,
cookies,
);
}
}
@ -1091,6 +1107,7 @@ pub fn walk_and_embed_assets(
"src",
&audio_attr_src_value,
options,
cookies,
);
}
}
@ -1109,6 +1126,7 @@ pub fn walk_and_embed_assets(
"src",
&video_attr_src_value,
options,
cookies,
);
}
}
@ -1132,6 +1150,7 @@ pub fn walk_and_embed_assets(
"poster",
&video_attr_poster_value,
options,
cookies,
);
}
}
@ -1155,6 +1174,7 @@ pub fn walk_and_embed_assets(
&document_url,
&noscript_contents_dom.document,
&options,
cookies,
);
// Get rid of original contents
noscript_contents.clear();
@ -1195,6 +1215,7 @@ pub fn walk_and_embed_assets(
&document_url,
&node_attr_style_value,
options,
cookies,
);
set_node_attr(node, "style", Some(embedded_style));
}
@ -1218,7 +1239,7 @@ pub fn walk_and_embed_assets(
// Dig deeper
for child in node.children.borrow().iter() {
walk_and_embed_assets(cache, client, &document_url, child, options);
walk_and_embed_assets(cache, client, &document_url, child, options, cookies);
}
}
_ => {

@ -1,3 +1,4 @@
use clap::Parser;
use encoding_rs::Encoding;
use markup5ever_rcdom::RcDom;
use reqwest::blocking::Client;
@ -10,7 +11,7 @@ use std::process;
use std::time::Duration;
use url::Url;
use monolith::cookies::parse_cookie_file_contents;
use monolith::cookies::{parse_cookie_file_contents, Cookie};
use monolith::html::{
add_favicon, create_metadata_tag, get_base_url, get_charset, has_favicon, html_to_dom,
serialize_document, set_base_url, set_charset, walk_and_embed_assets,
@ -65,7 +66,8 @@ pub fn read_stdin() -> Vec<u8> {
}
fn main() {
let mut options = Options::from_args();
let options = Options::parse();
let mut cookies: Vec<Cookie> = vec![];
// Check if target was provided
if options.target.len() == 0 {
@ -144,8 +146,8 @@ fn main() {
if let Some(opt_cookie_file) = options.cookie_file.clone() {
match fs::read_to_string(opt_cookie_file) {
Ok(str) => match parse_cookie_file_contents(&str) {
Ok(cookies) => {
options.cookies = cookies;
Ok(parsed_cookies) => {
cookies = parsed_cookies;
// for c in &cookies {
// // if !cookie.is_expired() {
// // options.cookies.append(c);
@ -198,7 +200,7 @@ fn main() {
|| (target_url.scheme() == "http" || target_url.scheme() == "https")
|| target_url.scheme() == "data"
{
match retrieve_asset(&mut cache, &client, &target_url, &target_url, &options) {
match retrieve_asset(&mut cache, &client, &target_url, &target_url, &options, &cookies) {
Ok((retrieved_data, final_url, media_type, charset)) => {
// Provide output as text without processing it, the way browsers do
if !media_type.eq_ignore_ascii_case("text/html")
@ -306,7 +308,7 @@ fn main() {
}
// Traverse through the document and embed remote assets
walk_and_embed_assets(&mut cache, &client, &base_url, &dom.document, &options);
walk_and_embed_assets(&mut cache, &client, &base_url, &dom.document, &options, &cookies);
// Update or add new BASE element to reroute network requests and hash-links
if let Some(new_base_url) = options.base_url.clone() {
@ -320,7 +322,7 @@ fn main() {
{
let favicon_ico_url: Url = resolve_url(&base_url, "/favicon.ico");
match retrieve_asset(&mut cache, &client, &target_url, &favicon_ico_url, &options) {
match retrieve_asset(&mut cache, &client, &target_url, &favicon_ico_url, &options, &cookies) {
Ok((data, final_url, media_type, charset)) => {
let favicon_data_url: Url =
create_data_url(&media_type, &charset, &data, &final_url);

@ -1,51 +1,160 @@
use clap::{App, Arg, ArgAction};
use clap::Parser;
use std::env;
use crate::cookies::Cookie;
// #[derive(Default)]
// pub struct Options {
// pub base_url: Option<String>,
// pub blacklist_domains: bool,
// pub cookie_file: Option<String>,
// pub cookies: Vec<Cookie>,
// pub domains: Option<Vec<String>>,
// pub encoding: Option<String>,
// pub ignore_errors: bool,
// pub insecure: bool,
// pub isolate: bool,
// pub no_audio: bool,
// pub no_color: bool,
// pub no_css: bool,
// pub no_frames: bool,
// pub no_fonts: bool,
// pub no_images: bool,
// pub no_js: bool,
// pub no_metadata: bool,
// pub no_video: bool,
// pub output: String,
// pub silent: bool,
// pub target: String,
// pub timeout: u64,
// pub unwrap_noscript: bool,
// pub user_agent: Option<String>,
// }
#[derive(Default)]
const ASCII: &'static str = " \
_____ ______________ __________ ___________________ ___
| \\ / \\ | | | | | |
| \\_/ __ \\_| __ | | ___ ___ |__| |
| | | | | | | | | | | |
| |\\ /| |__| _ |__| |____| | | | | __ |
| | \\___/ | | \\ | | | | | | |
|___| |__________| \\_____________________| |___| |___| |___|
";
const DEFAULT_NETWORK_TIMEOUT: u64 = 120;
const DEFAULT_USER_AGENT: &'static str =
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0";
#[derive(Parser, Debug)]
#[command(
version,
// author = format!("\n{}\n\n", env!("CARGO_PKG_AUTHORS").replace(':', "\n")).as_str(),
// about = format!("{}\n{}", ASCII, env!("CARGO_PKG_DESCRIPTION")).as_str()
)]
pub struct Options {
/// Remove audio sources
#[arg(short = 'a', long = "no-audio")]
pub no_audio: bool,
/// Set custom base URL
#[arg(short = 'b', long = "base-url")]
pub base_url: Option<String>,
/// Treat list of specified domains as blacklist
#[arg(short = 'B', long = "blacklist-domains")]
pub blacklist_domains: bool,
/// Remove CSS
#[arg(short = 'c', long = "no-css")]
pub no_css: bool,
/// Specify cookie file
#[arg(short = 'C', long = "cookies")]
pub cookie_file: Option<String>,
pub cookies: Vec<Cookie>,
/// Specify domains to use for white/black-listing
#[arg(short = 'd', long = "domains")]
pub domains: Option<Vec<String>>,
/// Ignore network errors
#[arg(short = 'e', long = "ignore-errors")]
pub ignore_errors: bool,
/// Enforce custom charset
#[arg(short = 'E', long = "encoding")]
pub encoding: Option<String>,
/// Remove frames and iframes
#[arg(short = 'f', long = "no-frames")]
pub no_frames: bool,
/// Remove fonts
#[arg(short = 'F', long = "no-fonts")]
pub no_fonts: bool,
/// Remove images
#[arg(short = 'i', long = "no-images")]
pub no_images: bool,
/// Cut off document from the Internet
#[arg(short = 'I', long = "isolate")]
pub isolate: bool,
/// Remove JavaScript
#[arg(short = 'j', long = "no-js")]
pub no_js: bool,
/// Allow invalid X.509 (TLS) certificates
#[arg(short = 'k', long = "insecure")]
pub insecure: bool,
/// Exclude timestamp and source information
#[arg(short = 'M', long = "no-metadata")]
pub no_metadata: bool,
/// Replace NOSCRIPT elements with their contents
#[arg(short = 'n', long = "unwrap-noscript")]
pub unwrap_noscript: bool,
/// Write output to <file>, use - for STDOUT
#[arg(short = 'o', long = "output")]
pub output: String,
/// Suppress verbosity
#[arg(short = 's', long = "silent")]
pub silent: bool,
/// Adjust network request timeout
// #[arg(short = 't', long = "timeout", default_value = format!("{}", DEFAULT_NETWORK_TIMEOUT).as_str())]
#[arg(short = 't', long = "timeout", default_value = "60")]
pub timeout: u64,
/// Set custom User-Agent string
#[arg(short = 'u', long = "user-agent")]
pub user_agent: Option<String>,
/// Remove video sources
#[arg(short = 'v', long = "no-video")]
pub no_video: bool,
/// URL or file path, use - for STDIN
#[arg(name = "target", default_value = "-")]
pub target: String,
pub no_color: bool,
pub unwrap_noscript: bool,
}
const ASCII: &'static str = " \
_____ ______________ __________ ___________________ ___
| \\ / \\ | | | | | |
| \\_/ __ \\_| __ | | ___ ___ |__| |
| | | | | | | | | | | |
| |\\ /| |__| _ |__| |____| | | | | __ |
| | \\___/ | | \\ | | | | | | |
|___| |__________| \\_____________________| |___| |___| |___|
";
const DEFAULT_NETWORK_TIMEOUT: u64 = 120;
const DEFAULT_USER_AGENT: &'static str =
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0";
const ENV_VAR_NO_COLOR: &str = "NO_COLOR";
const ENV_VAR_TERM: &str = "TERM";
/*
/// Files to cat
#[arg(name = "FILES", default_value = "-")]
files: Vec<String>,
/// Print line numbers
#[arg(short, long = "number")]
number_lines: bool,
/// Print line numbers for nonblank lines
#[arg(short = 'b', long = "number-nonblank", conflicts_with = "number_lines")]
number_nonblank_lines: bool,
/// Show $ at the end of each line
#[arg(short = 'E', long = "show-ends")]
show_ends: bool,
*/
}
/*
impl Options {
pub fn from_args() -> Options {
let app = App::new(env!("CARGO_PKG_NAME"))
@ -141,14 +250,7 @@ impl Options {
options.unwrap_noscript = app.is_present("unwrap-noscript");
options.no_video = app.is_present("no-video");
options.no_color =
env::var_os(ENV_VAR_NO_COLOR).is_some() || atty::isnt(atty::Stream::Stderr);
if let Some(term) = env::var_os(ENV_VAR_TERM) {
if term == "dumb" {
options.no_color = true;
}
}
options
}
}
*/

@ -1,3 +1,4 @@
use std::env;
use reqwest::blocking::Client;
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE, COOKIE};
use std::collections::HashMap;
@ -5,11 +6,14 @@ use std::fs;
use std::path::{Path, PathBuf};
use url::Url;
use crate::cookies::Cookie;
use crate::opts::Options;
use crate::url::{clean_url, parse_data_url};
const ANSI_COLOR_RED: &'static str = "\x1b[31m";
const ANSI_COLOR_RESET: &'static str = "\x1b[0m";
const ENV_VAR_NO_COLOR: &str = "NO_COLOR";
const ENV_VAR_TERM: &str = "TERM";
const MAGIC: [[&[u8]; 2]; 18] = [
// Image
[b"GIF87a", b"image/gif"],
@ -186,7 +190,16 @@ pub fn retrieve_asset(
parent_url: &Url,
url: &Url,
options: &Options,
cookies: &Vec<Cookie>
) -> Result<(Vec<u8>, Url, String, String), reqwest::Error> {
let mut no_color: bool =
env::var_os(ENV_VAR_NO_COLOR).is_some() || atty::isnt(atty::Stream::Stderr);
if let Some(term) = env::var_os(ENV_VAR_TERM) {
if term == "dumb" {
no_color = true;
}
}
if url.scheme() == "data" {
let (media_type, charset, data) = parse_data_url(url);
Ok((data, url.clone(), media_type, charset))
@ -196,10 +209,10 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{} ({}){}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
&url,
"Security Error",
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET
@ -217,9 +230,9 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{} (is a directory){}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
&url,
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET
@ -247,9 +260,9 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{} (not found){}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
&url,
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET
@ -289,8 +302,8 @@ pub fn retrieve_asset(
// URL not in cache, we retrieve the file
let mut headers = HeaderMap::new();
if options.cookies.len() > 0 {
for cookie in &options.cookies {
if cookies.len() > 0 {
for cookie in cookies {
if !cookie.is_expired() && cookie.matches_url(url.as_str()) {
let cookie_header_value: String = cookie.name.clone() + "=" + &cookie.value;
headers
@ -304,10 +317,10 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{} ({}){}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
&url,
response.status(),
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET
@ -349,9 +362,9 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{}{}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
error,
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET
@ -371,10 +384,10 @@ pub fn retrieve_asset(
if !options.silent {
eprintln!(
"{}{} ({}){}",
if options.no_color { "" } else { ANSI_COLOR_RED },
if no_color { "" } else { ANSI_COLOR_RED },
&url,
error,
if options.no_color {
if no_color {
""
} else {
ANSI_COLOR_RESET

Loading…
Cancel
Save