hyperium / hyper

An HTTP library for Rust
https://hyper.rs
MIT License
14.07k stars 1.55k forks source link

Hyper-util on xtensa #3684

Open lorenzo-pirchio opened 2 weeks ago

lorenzo-pirchio commented 2 weeks ago

I'm trying to use hyper-util and hyper on esp32s3 but I have these errors, can anyone help me?

error[E0599]: no method named with_interval found for struct TcpKeepalive in the current scope --> C:\Users\lpirc.cargo\registry\src\index.crates.io-6f17d22bba15001f\hyper-util-0.1.5\src\client\legacy\connect\http.rs:114:12 | 114 | ka.with_interval(interval) | ^^^^^^^^^^^^^ method not found in TcpKeepalive

error[E0599]: no method named with_retries found for struct TcpKeepalive in the current scope --> C:\Users\lpirc.cargo\registry\src\index.crates.io-6f17d22bba15001f\hyper-util-0.1.5\src\client\legacy\connect\http.rs:130:12 | 130 | ka.with_retries(retries) | ^^^^^^^^^^^^ help: there is a method with a similar name: with_time

It's due to the fact that are calling two methods defined in socket2 that are not available for xtensa and espidf, as it can be seen below.

#[cfg(any(
    target_os = "android",
    target_os = "dragonfly",
    target_os = "freebsd",
    target_os = "fuchsia",
    target_os = "illumos",
    target_os = "ios",
    target_os = "linux",
    target_os = "macos",
    target_os = "netbsd",
    target_os = "tvos",
    target_os = "watchos",
    target_os = "windows",
))]
#[cfg_attr(
    docsrs,
    doc(cfg(any(
        target_os = "android",
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "fuchsia",
        target_os = "illumos",
        target_os = "ios",
        target_os = "linux",
        target_os = "macos",
        target_os = "netbsd",
        target_os = "tvos",
        target_os = "watchos",
        target_os = "windows"
    )))
)]
pub const fn with_interval(self, interval: Duration) -> Self {
    Self {
        interval: Some(interval),
        ..self
    }
}

/// Set the value of the `TCP_KEEPCNT` option.
///
/// Set the maximum number of TCP keepalive probes that will be sent before
/// dropping a connection, if TCP keepalive is enabled on this socket.
#[cfg(all(
    feature = "all",
    any(
        target_os = "android",
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "fuchsia",
        target_os = "illumos",
        target_os = "ios",
        target_os = "linux",
        target_os = "macos",
        target_os = "netbsd",
        target_os = "tvos",
        target_os = "watchos",
    )
))]
#[cfg_attr(
    docsrs,
    doc(cfg(all(
        feature = "all",
        any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "ios",
            target_os = "linux",
            target_os = "macos",
            target_os = "netbsd",
            target_os = "tvos",
            target_os = "watchos",
        )
    )))
)]
pub const fn with_retries(self, retries: u32) -> Self {
    Self {
        retries: Some(retries),
        ..self
    }
}

}

this is where in http.rs I get errors: impl TcpKeepaliveConfig { /// Converts into a socket2::TcpKeealive if there is any keep alive configuration. fn into_tcpkeepalive(self) -> Option { let mut dirty = false; let mut ka = TcpKeepalive::new(); if let Some(time) = self.time { ka = ka.with_time(time); dirty = true } if let Some(interval) = self.interval { ka = Self::ka_with_interval(ka, interval, &mut dirty) }; if let Some(retries) = self.retries { ka = Self::ka_with_retries(ka, retries, &mut dirty) }; if dirty { Some(ka) } else { None } }

#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris")))]
fn ka_with_interval(ka: TcpKeepalive, interval: Duration, dirty: &mut bool) -> TcpKeepalive {
    *dirty = true;
    ka.with_interval(interval)
}

#[cfg(any(target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
fn ka_with_interval(ka: TcpKeepalive, _: Duration, _: &mut bool) -> TcpKeepalive {
    ka // no-op as keepalive interval is not supported on this platform
}

#[cfg(not(any(
    target_os = "openbsd",
    target_os = "redox",
    target_os = "solaris",
    target_os = "windows",
)))]
fn ka_with_retries(ka: TcpKeepalive, retries: u32, dirty: &mut bool) -> TcpKeepalive {
    *dirty = true;
    ka.with_retries(retries)
}

#[cfg(any(
    target_os = "openbsd",
    target_os = "redox",
    target_os = "solaris",
    target_os = "windows",
))]
fn ka_with_retries(ka: TcpKeepalive, _: u32, _: &mut bool) -> TcpKeepalive {
    ka // no-op as keepalive retries is not supported on this platform
}

}

seanmonstar commented 2 weeks ago

Looks like someone would need to add support however which way to that file. If that platform doesn't support the TCP options, than the cfg could be adjusted appropriately.

jofas commented 2 weeks ago

Corresponding issue in socket2: https://github.com/rust-lang/socket2/issues/516 (looks like they are interested in supporting the platform?)

lorenzo-pirchio commented 2 weeks ago

I changed like this and it's compiling, but I don't know if it's going to work properly. Do you guys think it's correct?

impl TcpKeepaliveConfig { /// Converts into a socket2::TcpKeealive if there is any keep alive configuration. fn into_tcpkeepalive(self) -> Option { let mut dirty = false; let mut ka = TcpKeepalive::new(); if let Some(time) = self.time { ka = ka.with_time(time); dirty = true } if let Some(interval) = self.interval { ka = Self::ka_with_interval(ka, interval, &mut dirty) }; if let Some(retries) = self.retries { ka = Self::ka_with_retries(ka, retries, &mut dirty) }; if dirty { Some(ka) } else { None } }

#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "solaris", targer_os="espidf")))]
fn ka_with_interval(ka: TcpKeepalive, interval: Duration, dirty: &mut bool) -> TcpKeepalive {
    *dirty = true;
    ka.with_interval(interval)
}

#[cfg(any(target_os = "openbsd", target_os = "redox", target_os = "solaris", targer_os="espidf"))]
fn ka_with_interval(ka: TcpKeepalive, _: Duration, _: &mut bool) -> TcpKeepalive {
    ka // no-op as keepalive interval is not supported on this platform
}

#[cfg(not(any(
    target_os = "openbsd",
    target_os = "redox",
    target_os = "solaris",
    target_os = "windows",
    targer_os="espidf"
)))]
fn ka_with_retries(ka: TcpKeepalive, retries: u32, dirty: &mut bool) -> TcpKeepalive {
    *dirty = true;
    ka.with_retries(retries)
}

#[cfg(any(
    target_os = "openbsd",
    target_os = "redox",
    target_os = "solaris",
    target_os = "windows",
    targer_os="espidf"
))]
fn ka_with_retries(ka: TcpKeepalive, _: u32, _: &mut bool) -> TcpKeepalive {
    ka // no-op as keepalive retries is not supported on this platform
}

}

jofas commented 2 weeks ago

That should do the trick for the esp-espidf targets. I think it'd be best to set the same target-os configuration in hyper-util as socket2 has as a general fix though.