Add TLS version option (#1655)

* Add a minimum TLS option
* Update help message for min tls version
This commit is contained in:
Hugo McNally 2025-05-10 11:59:55 +01:00 committed by GitHub
parent db6d3334c9
commit fdf105c67a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 1 deletions

View file

@ -393,6 +393,9 @@ Options:
[default: 3]
--min-tls <MIN_TLS>
Minimum accepted TLS Version
--max-concurrency <MAX_CONCURRENCY>
Maximum number of concurrent network requests

View file

@ -76,6 +76,7 @@ pub(crate) fn create(cfg: &Config, cookie_jar: Option<&Arc<CookieStoreMutex>>) -
.accepted(accepted)
.require_https(cfg.require_https)
.cookie_jar(cookie_jar.cloned())
.min_tls_version(cfg.min_tls.clone().map(Into::into))
.include_fragments(cfg.include_fragments)
.fallback_extensions(cfg.fallback_extensions.clone())
.build()

View file

@ -10,6 +10,7 @@ use lychee_lib::{
StatusCodeSelector, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_WAIT_TIME_SECS,
DEFAULT_TIMEOUT_SECS, DEFAULT_USER_AGENT,
};
use reqwest::tls;
use secrecy::{ExposeSecret, SecretString};
use serde::Deserialize;
use std::path::Path;
@ -46,6 +47,34 @@ const HELP_MSG_CONFIG_FILE: &str = formatcp!(
const TIMEOUT_STR: &str = concatcp!(DEFAULT_TIMEOUT_SECS);
const RETRY_WAIT_TIME_STR: &str = concatcp!(DEFAULT_RETRY_WAIT_TIME_SECS);
#[derive(Debug, Display, Deserialize, Default, Clone, EnumString)]
#[non_exhaustive]
pub(crate) enum TlsVersion {
#[serde(rename = "TLSv1_0")]
#[strum(serialize = "TLSv1_0")]
V1_0,
#[serde(rename = "TLSv1_1")]
#[strum(serialize = "TLSv1_1")]
V1_1,
#[serde(rename = "TLSv1_2")]
#[strum(serialize = "TLSv1_2")]
#[default]
V1_2,
#[serde(rename = "TLSv1_3")]
#[strum(serialize = "TLSv1_3")]
V1_3,
}
impl From<TlsVersion> for tls::Version {
fn from(ver: TlsVersion) -> Self {
match ver {
TlsVersion::V1_0 => tls::Version::TLS_1_0,
TlsVersion::V1_1 => tls::Version::TLS_1_1,
TlsVersion::V1_2 => tls::Version::TLS_1_2,
TlsVersion::V1_3 => tls::Version::TLS_1_3,
}
}
}
/// The format to use for the final status report
#[derive(Debug, Deserialize, Default, Clone, Display, EnumIter, VariantNames, PartialEq)]
#[non_exhaustive]
@ -319,6 +348,11 @@ and 501."
#[serde(default = "max_retries")]
pub(crate) max_retries: u64,
/// Minimum accepted TLS Version
#[arg(long)]
#[serde(default)]
pub(crate) min_tls: Option<TlsVersion>,
/// Maximum number of concurrent network requests
#[arg(long, default_value = &MAX_CONCURRENCY_STR)]
#[serde(default = "max_concurrency")]

View file

@ -22,7 +22,7 @@ use http::{
use log::{debug, warn};
use octocrab::Octocrab;
use regex::RegexSet;
use reqwest::{header, redirect};
use reqwest::{header, redirect, tls};
use reqwest_cookie_store::CookieStoreMutex;
use secrecy::{ExposeSecret, SecretString};
use typed_builder::TypedBuilder;
@ -192,6 +192,9 @@ pub struct ClientBuilder {
#[builder(default = DEFAULT_MAX_RETRIES)]
max_retries: u64,
/// Minimum accepted TLS version.
min_tls_version: Option<tls::Version>,
/// User-agent used for checking links.
///
/// Defaults to [`DEFAULT_USER_AGENT`].
@ -352,6 +355,10 @@ impl ClientBuilder {
builder = builder.cookie_provider(cookie_jar);
}
if let Some(min_tls) = self.min_tls_version {
builder = builder.min_tls_version(min_tls);
}
let reqwest_client = match self.timeout {
Some(t) => builder.timeout(t),
None => builder,