use std::{collections::HashMap, path::PathBuf}; pub use crate::auth::{ AuthChallengeModel as AuthChallenge, AuthCredentialModel as AuthCredential, AuthScheme, }; /// Classifies how one header participates in an HTTP exchange. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum HeaderKind { /// Header belongs to the request. Request, /// Header belongs to the response. Response, /// Header is valid for both directions. General, } /// One normalized HTTP header field. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpHeader { /// Lower-level header name. pub name: String, /// Raw header value. pub value: String, /// Header classification within the exchange. pub kind: HeaderKind, } /// HTTP methods supported by the protocol layer. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum HttpMethod { /// `GET` Get, /// `HEAD` Head, /// `POST` Post, /// `PUT` Put, /// `DELETE` Delete, } /// HTTP versions surfaced by the transport layer. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum HttpVersion { /// HTTP/1.0 Http10, /// HTTP/1.1 Http11, /// HTTP/2 Http2, /// HTTP/3 Http3, } /// One request byte or piece range. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RangeSpec { /// Inclusive start offset. pub start: u64, /// Optional inclusive end offset. pub end_inclusive: Option, /// Unit used by the range. pub unit: RangeUnit, } impl RangeSpec { #[must_use] /// Returns whether the range omits an explicit end bound. pub const fn is_open_ended(&self) -> bool { self.end_inclusive.is_none() } #[must_use] /// Returns the requested length when the end bound is known. pub fn length_hint(&self) -> Option { self.end_inclusive .map(|end| end.saturating_sub(self.start).saturating_add(1)) } } /// Units supported by HTTP-style range models. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum RangeUnit { /// Byte-oriented ranges. Bytes, /// Piece-oriented ranges used by higher-level scheduling. Pieces, } /// Parsed `Content-Range` response metadata. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ContentRangeSpec { /// Unit reported by the server. pub unit: RangeUnit, /// Inclusive start offset returned by the server. pub start: u64, /// Inclusive end offset returned by the server. pub end_inclusive: u64, /// Total object size when known. pub total_size: Option, /// Whether the response represents an unsatisfied range. pub unsatisfied: bool, } impl ContentRangeSpec { #[must_use] /// Returns the completed length implied by the range payload. pub const fn completed_length(&self) -> u64 { if self.unsatisfied { 0 } else { self.end_inclusive.saturating_add(1) } } #[must_use] /// Returns whether the range is explicitly unsatisfied. pub const fn is_unsatisfied(&self) -> bool { self.unsatisfied } } /// Resume metadata carried into one HTTP transfer attempt. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ResumeState { /// Requested starting offset for the retry or resumed request. pub requested_offset: u64, /// Offset actually accepted by the remote server. pub accepted_offset: Option, /// Whether the attempt truly resumed instead of restarting from zero. pub resumed: bool, } /// Retry policy knobs applied to HTTP work. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RetryPolicy { /// Maximum number of attempts. pub max_attempts: u32, /// Initial backoff delay in milliseconds. pub initial_backoff_ms: u64, /// Maximum backoff delay in milliseconds. pub max_backoff_ms: u64, /// Whether `3xx` responses are retryable. pub retry_on_3xx: bool, /// Whether `4xx` responses are retryable. pub retry_on_4xx: bool, /// Whether `5xx` responses are retryable. pub retry_on_5xx: bool, /// Whether transport-level network errors are retryable. pub retry_on_network_error: bool, /// Whether timeout failures are retryable. pub retry_on_timeout: bool, } /// Fully-resolved retry behavior for one request. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RetryStrategy { /// Base retry policy. pub policy: RetryPolicy, /// Optional jitter value in milliseconds. pub jitter: Option, /// Optional upper bound on total retry elapsed time in milliseconds. pub max_elapsed_ms: Option, } /// Normalized reasons for retrying one transfer attempt. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum RetryReason { /// A transport-level network failure occurred. NetworkError, /// The request timed out. Timeout, /// The server responded with a retryable `3xx`. Http3xx, /// The server responded with a retryable `4xx`. Http4xx, /// The server responded with a retryable `5xx`. Http5xx, /// Partial-content semantics did not match the requested resume state. PartialContentMismatch, /// Another retryable condition occurred. Other, } /// One recorded retry attempt. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RetryAttempt { /// Attempt number starting at one. pub attempt: u32, /// Retry reason for the attempt. pub reason: RetryReason, /// Optional HTTP status observed during the attempt. pub status: Option, /// Optional backoff delay in milliseconds before the next attempt. pub backoff_ms: Option, } /// Final or intermediate completion state for one HTTP response. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum HttpCompletionState { /// Response is not yet complete. Incomplete, /// Response is usable but only partial. Partial, /// Response is complete without checksum verification. Complete, /// Response is complete and checksum-verified. Verified, } /// Derived completion summary for one HTTP response. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct HttpCompletionModel { /// Overall completion state. pub state: HttpCompletionState, /// Total payload length when known. pub total_length: Option, /// Number of completed bytes. pub completed_length: u64, /// Whether the response used partial-content semantics. pub partial_content: bool, /// Whether the status code indicates terminal success. pub terminal_success: bool, /// Whether checksum metadata was present. pub checksum_seen: bool, /// Whether the checksum could be verified successfully. pub checksum_verified: bool, } /// Segment-level progress view for one transfer snapshot. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct HttpSegmentProgressModel { /// Range originally requested from the server. pub requested_range: Option, /// Requested starting offset. pub requested_offset: u64, /// Offset accepted by the server when present. pub accepted_offset: Option, /// Completed offset derived from the current response. pub completed_offset: Option, /// Whether the transfer is actively resuming instead of restarting. pub resumed: bool, } /// Retry-attempt detail enriched with segment and resume context. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct HttpRetryAttemptDetailModel { /// Base retry-attempt data. pub base: RetryAttempt, /// Range requested for the attempt. pub requested_range: Option, /// Requested starting offset for the attempt. pub requested_offset: u64, /// Offset accepted by the server when present. pub accepted_offset: Option, /// Resume metadata captured for the attempt. pub resume_state: Option, } /// Snapshot of one in-flight or completed HTTP transfer. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpTransferProgressModel { /// Stable task identifier. pub task_id: String, /// Request model associated with the transfer. pub request: HttpRequestModel, /// Segment-level progress details. pub segment: HttpSegmentProgressModel, /// Retry-attempt history with contextual detail. pub retry_attempts: Vec, /// Maximum number of concurrent connections permitted for the task. pub max_connections: u16, /// Optional checksum hook attached to the transfer. pub checksum_hook: Option, /// Derived completion summary when a response exists. pub completion: Option, } /// Proxy configuration projected into HTTP requests. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProxyConfig { /// Proxy scheme such as `http` or `socks5`. pub scheme: String, /// Proxy host name or IP. pub host: String, /// Proxy port. pub port: u16, /// Optional proxy username. pub username: Option, /// Optional proxy password. pub password: Option, /// Hosts that should bypass the proxy. pub bypass_hosts: Vec, /// Whether proxying is disabled for the request. pub no_proxy: bool, } /// One normalized HTTP cookie. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Cookie { /// Cookie name. pub name: String, /// Cookie value. pub value: String, /// Optional domain constraint. pub domain: Option, /// Optional path constraint. pub path: Option, /// Whether the cookie requires a secure transport. pub secure: bool, /// Whether the cookie is `HttpOnly`. pub http_only: bool, /// Optional same-site policy marker. pub same_site: Option, /// Expiration time as a Unix timestamp when present. pub expires_unix_epoch: Option, } /// TLS behavior attached to one HTTP session. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TlsConfig { /// Whether peer certificates must be verified. pub verify_peer: bool, /// Whether host name verification is enabled. pub verify_host: bool, /// Minimum TLS version when constrained. pub min_version: Option, /// Maximum TLS version when constrained. pub max_version: Option, /// Optional CA bundle path. pub ca_file: Option, /// Optional client certificate path. pub cert_file: Option, /// Optional client key path. pub key_file: Option, } /// Ordered collection of request headers. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpRequestHeaders { /// Stored request headers. pub headers: Vec, } /// Ordered collection of response headers. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpResponseHeaders { /// Stored response headers. pub headers: Vec, } /// Request-body representation for HTTP transfers. #[derive(Clone, Debug, Eq, PartialEq)] pub enum HttpBody { /// No request body. Empty, /// UTF-8 text request body. Text(String), /// Arbitrary binary request body. Binary(Vec), /// Streaming body with an optional declared length. Stream { /// Declared body length when the caller knows it. expected_len: Option, }, } /// Expected and observed checksum metadata for one payload. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ChecksumSpec { /// Hash algorithm name. pub algorithm: String, /// Expected digest hex string. pub expected_hex: String, /// Observed digest hex string when known. pub actual_hex: Option, } /// Optional checksum hook attached to a transfer. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ChecksumHookModel { /// Checksum specification to evaluate. pub spec: ChecksumSpec, /// Whether the hook is enabled. pub enabled: bool, } /// Optional direct-write target for one live HTTP response body. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpResponseSinkTarget { /// Final output path that should receive the response body directly. pub target_path: PathBuf, } /// Fully normalized HTTP request model. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpRequestModel { /// HTTP method. pub method: HttpMethod, /// Fully-qualified request URL. pub url: String, /// Requested HTTP version. pub version: HttpVersion, /// Explicit request headers. pub headers: HttpRequestHeaders, /// Query parameters to attach to the URL. pub query: HashMap, /// Optional range metadata. pub range: Option, /// Request body. pub body: HttpBody, /// Retry strategy for the request. pub retry: RetryStrategy, /// Optional origin credential. pub auth: Option, /// Optional proxy configuration. pub proxy: Option, /// Optional direct-write sink for live response persistence. pub response_sink: Option, } /// Session-scoped defaults that shape HTTP execution. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpSessionModel { /// Stable session identifier. pub session_id: String, /// Optional user-agent string. pub user_agent: Option, /// Default headers applied to requests. pub default_headers: Vec, /// Cookies carried by the session. pub cookies: Vec, /// Optional default credential. pub auth: Option, /// Optional default proxy configuration. pub proxy: Option, /// Optional TLS behavior for the session. pub tls: Option, /// Default retry strategy for the session. pub retry: RetryStrategy, } /// Response-body representation used by the protocol layer. #[derive(Clone, Debug, Eq, PartialEq)] pub enum ResponseBody { /// No response payload. Empty, /// Inline retained payload bytes. Inline(Vec), /// Streamed payload metadata with optional retained artifacts. Streamed { /// Declared content length when known. expected_len: Option, /// Observed byte count written through the sink. observed_len: Option, /// Observed digest when computed by the sink. observed_digest: Option, /// Optional temporary file path holding the streamed body. temp_path: Option, }, } /// Executable HTTP transfer task passed into downloaders. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpTransferTaskModel { /// Stable task identifier. pub task_id: String, /// Request model for the task. pub request: HttpRequestModel, /// Response headers already associated with the task. pub response_headers: HttpResponseHeaders, /// Current response body state. pub body: ResponseBody, /// Resume metadata when resuming is in play. pub resume_state: Option, /// Retry-attempt history. pub retry_attempts: Vec, /// Optional checksum hook. pub checksum_hook: Option, /// Maximum allowed concurrent connections. pub max_connections: u16, /// Retry strategy for the task. pub retry: RetryStrategy, } /// Normalized HTTP response model produced by connectors and fixtures. #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpResponseModel { /// Numeric HTTP status code. pub status: u16, /// Human-readable reason phrase. pub reason: String, /// Negotiated HTTP version. pub version: HttpVersion, /// Response headers. pub headers: HttpResponseHeaders, /// Response body representation. pub body: ResponseBody, /// Parsed `Content-Range` metadata when present. pub content_range: Option, /// Whether the response used partial-content semantics. pub partial_content: bool, /// Optional checksum metadata. pub checksum: Option, /// Original URL before redirects when one occurred. pub redirected_from: Option, }