Repository: servo/servo
File: components/shared/net/lib.rs (Rust)

Code before:

impl fmt::Debug for NetworkError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            NetworkError::Internal(s) => write!(f, "{}", s),
            NetworkError::UnsupportedScheme => write!(f, "Unsupported scheme"),
            NetworkError::CorsGeneral => write!(f, "CORS check failed"),
            NetworkError::CrossOriginResponse => write!(f, "Cross-origin response"),
            NetworkError::CorsCredentials => write!(f, "Cross-origin credentials check failed"),
            NetworkError::CorsAllowMethods => write!(f, "CORS ACAM check failed"),
            NetworkError::CorsAllowHeaders => write!(f, "CORS ACAH check failed"),
            NetworkError::CorsMethod => write!(f, "CORS method check failed"),
            NetworkError::CorsAuthorization => write!(f, "CORS authorization check failed"),
            NetworkError::CorsHeaders => write!(f, "CORS headers check failed"),
            NetworkError::ConnectionFailure => write!(f, "Request failed"),
            NetworkError::RedirectError => write!(f, "Too many redirects"),
            NetworkError::InvalidMethod => write!(f, "Unexpected method"),
            NetworkError::ResourceError => write!(f, "Resource access failed"),
            NetworkError::ContentSecurityPolicy => write!(f, "Blocked by Content-Security-Policy"),
            NetworkError::Nosniff => write!(f, "Blocked by nosniff"),
            NetworkError::MimeType => write!(f, "Blocked by mime type"),
            NetworkError::SubresourceIntegrity => {
                write!(f, "Subresource integrity validation failed")
            },
            NetworkError::MixedContent => write!(f, "Blocked as mixed content"),
            NetworkError::CacheError => write!(f, "Cache error"),
            NetworkError::InvalidPort => write!(f, "Request attempted on bad port"),
            NetworkError::LocalDirectoryError => write!(f, "Local directory access failed"),
            NetworkError::LoadCancelled => write!(f, "Load cancelled"),
            NetworkError::SslValidation(s, _) => write!(f, "SSL validation error: {}", s),
            NetworkError::Crash(s) => write!(f, "Crash: {}", s),
        }
    }
}

impl NetworkError {
    pub fn from_hyper_error(error: &HyperError, certificate: Option<CertificateDer>) -> Self {
        let error_string = error.to_string();
        match certificate {
            Some(certificate) => NetworkError::SslValidation(error_string, certificate.to_vec()),
            _ => NetworkError::Internal(error_string),
        }
    }

    pub fn from_http_error(error: &HttpError) -> Self {
        NetworkError::Internal(error.to_string())
    }
}

/// Normalize `slice`, as defined by
/// [the Fetch Spec](https://fetch.spec.whatwg.org/#concept-header-value-normalize).

Review comment (performance):
This cache error can use `"Couldn't find response in cache"` instead.

Code after:
            ResourceAttribute::RedirectEnd(val) => match val {
                RedirectEndValue::Zero => self.redirect_end = None,
                RedirectEndValue::ResponseEnd => self.redirect_end = self.response_end,
            },
            ResourceAttribute::FetchStart => self.fetch_start = now,
            ResourceAttribute::ConnectStart(instant) => self.connect_start = Some(instant),
            ResourceAttribute::ConnectEnd(instant) => self.connect_end = Some(instant),
            ResourceAttribute::SecureConnectionStart => self.secure_connection_start = now,
            ResourceAttribute::ResponseEnd => self.response_end = now,
            ResourceAttribute::StartTime(val) => match val {
                ResourceTimeValue::RedirectStart
                    if self.redirect_start.is_none() || !self.timing_check_passed => {},
                _ => self.start_time = self.get_time_value(val),
            },
        }
    }

    fn get_time_value(&self, time: ResourceTimeValue) -> Option<CrossProcessInstant> {
        match time {
            ResourceTimeValue::Zero => None,
            ResourceTimeValue::Now => Some(CrossProcessInstant::now()),
            ResourceTimeValue::FetchStart => self.fetch_start,
            ResourceTimeValue::RedirectStart => self.redirect_start,
        }
    }

    pub fn mark_timing_check_failed(&mut self) {
        self.timing_check_passed = false;
        self.domain_lookup_start = None;
        self.redirect_count = 0;
        self.request_start = None;
        self.response_start = None;
        self.redirect_start = None;
        self.connect_start = None;
        self.connect_end = None;
    }
}

/// Metadata about a loaded resource, such as is obtained from HTTP headers.
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct Metadata {
    /// Final URL after redirects.
    pub final_url: ServoUrl,

    /// Location URL from the response headers.
    pub location_url: Option<Result<ServoUrl, String>>,

    #[ignore_malloc_size_of = "Defined in hyper"]
    /// MIME type / subtype.
    pub content_type: Option<Serde<ContentType>>,