use crate::context::ScanContext;
use crate::existence::cache_probing::{
CpAccept, CpIfMatch, CpIfModifiedSince, CpIfNoneMatch, CpIfRange, CpIfUnmodifiedSince,
CpRangeSatisfiable, CpRangeUnsatisfiable,
};
use crate::existence::error_message_granularity::{
EmgAppVsServer404, EmgBola, EmgFkViolation, EmgQueryValidation, EmgSchemaValidationPatch,
EmgSchemaValidationPut, EmgStateConflict,
};
use crate::existence::redirect_diff::{
RdCaseVariation, RdDoubleSlash, RdPercentEncoding, RdPostTo303, RdProtocolUpgrade, RdPutTo303,
RdSlashAppend, RdSlashStrip,
};
use crate::existence::status_code_diff::{
AcceptElicitation, AuthStripElicitation, CaseNormalizeElicitation, ContentTypeElicitation,
DependencyDeleteElicitation, EmptyBodyElicitation, IfMatchElicitation, IfMatchReadElicitation,
IfNoneMatchElicitation, LowPrivilegeElicitation, RateLimitBurstElicitation,
RateLimitHeadersElicitation, ScopeManipulationElicitation, StateTransitionElicitation,
TrailingSlashElicitation, UniquenessElicitation,
};
use crate::strategy::Strategy;
use crate::types::ProbeSpec;
#[must_use]
pub fn all_strategies() -> Vec<Box<dyn Strategy>> {
vec![
Box::new(AcceptElicitation),
Box::new(IfNoneMatchElicitation),
Box::new(IfMatchReadElicitation),
Box::new(TrailingSlashElicitation),
Box::new(CaseNormalizeElicitation),
Box::new(AuthStripElicitation),
Box::new(LowPrivilegeElicitation),
Box::new(ScopeManipulationElicitation),
Box::new(RateLimitHeadersElicitation),
Box::new(CpIfNoneMatch),
Box::new(CpIfModifiedSince),
Box::new(CpIfMatch),
Box::new(CpIfUnmodifiedSince),
Box::new(CpRangeSatisfiable),
Box::new(CpRangeUnsatisfiable),
Box::new(CpIfRange),
Box::new(CpAccept),
Box::new(EmgBola),
Box::new(EmgQueryValidation),
Box::new(EmgAppVsServer404),
Box::new(RdSlashAppend),
Box::new(RdSlashStrip),
Box::new(RdCaseVariation),
Box::new(RdDoubleSlash),
Box::new(RdPercentEncoding),
Box::new(RdProtocolUpgrade),
Box::new(ContentTypeElicitation),
Box::new(IfMatchElicitation),
Box::new(EmptyBodyElicitation),
Box::new(StateTransitionElicitation),
Box::new(EmgSchemaValidationPatch),
Box::new(EmgSchemaValidationPut),
Box::new(EmgStateConflict),
Box::new(EmgFkViolation),
Box::new(RdPostTo303),
Box::new(RdPutTo303),
Box::new(UniquenessElicitation),
Box::new(DependencyDeleteElicitation),
Box::new(RateLimitBurstElicitation),
]
}
pub(crate) fn applicable_strategies<'a>(
strategies: &'a [Box<dyn Strategy>],
ctx: &'a ScanContext,
) -> impl Iterator<Item = &'a dyn Strategy> {
strategies
.iter()
.map(Box::as_ref)
.filter(move |s| s.risk() <= ctx.max_risk)
.filter(move |s| s.is_applicable(ctx))
}
#[must_use]
pub fn generate_plan(ctx: &ScanContext) -> Vec<ProbeSpec> {
let strategies = all_strategies();
applicable_strategies(&strategies, ctx)
.flat_map(|s| s.generate(ctx))
.collect()
}
#[cfg(test)]
#[path = "registry_tests.rs"]
mod tests;