~vpzom/lotide

4bfe07aa805e1c09f45ddb2d1e9e4d0aab67f4e8 — Colin Reeder a month ago c549b7b
Probably fix issues with root-level host_url_apub
3 files changed, 50 insertions(+), 36 deletions(-)

M src/apub_util.rs
M src/routes/apub/mod.rs
M src/routes/well_known.rs
M src/apub_util.rs => src/apub_util.rs +21 -9
@@ 99,6 99,19 @@ pub struct PublicKeyExtension<'a> {
    pub public_key: Option<PublicKey<'a>>,
}

pub fn try_strip_host<'a>(url: &'a impl AsRef<str>, host_url: &url::Url) -> Option<&'a str> {
    let host_url = host_url.as_str();
    let host_url = host_url.strip_suffix('/').unwrap_or(host_url);

    let url = url.as_ref();

    if url.starts_with(host_url) {
        Some(&url[host_url.len()..])
    } else {
        None
    }
}

pub fn get_local_shared_inbox(host_url_apub: &BaseURL) -> BaseURL {
    let mut res = host_url_apub.clone();
    res.path_segments_mut().push("inbox");


@@ 445,9 458,9 @@ pub async fn get_or_fetch_user_local_id(
    host_url_apub: &BaseURL,
    http_client: &crate::HttpClient,
) -> Result<UserLocalID, crate::Error> {
    if ap_id.as_str().starts_with(host_url_apub.as_str()) {
        if ap_id.as_str()[host_url_apub.as_str().len()..].starts_with("/users/") {
            Ok(ap_id.as_str()[(host_url_apub.as_str().len() + 7)..].parse()?)
    if let Some(remaining) = try_strip_host(ap_id, host_url_apub) {
        if remaining.starts_with("/users/") {
            Ok(remaining[7..].parse()?)
        } else {
            Err(crate::Error::InternalStr(format!(
                "Unrecognized local AP ID: {:?}",


@@ 1361,8 1374,7 @@ pub fn maybe_get_local_community_id_from_uri(
    uri: &url::Url,
    host_url_apub: &BaseURL,
) -> Option<CommunityLocalID> {
    if uri.as_str().starts_with(&host_url_apub.as_str()) {
        let path = &uri.as_str()[host_url_apub.as_str().len()..];
    if let Some(path) = try_strip_host(uri, host_url_apub) {
        if path.starts_with("/communities/") {
            if let Ok(local_community_id) = path[13..].parse() {
                Some(local_community_id)


@@ 1675,8 1687,7 @@ async fn handle_recieved_reply(
                },
            }

            let target = if term_ap_id.as_str().starts_with(&ctx.host_url_apub.as_str()) {
                let remaining = &term_ap_id.as_str()[ctx.host_url_apub.as_str().len()..];
            let target = if let Some(remaining) = try_strip_host(&term_ap_id, &ctx.host_url_apub) {
                if remaining.starts_with("/posts/") {
                    if let Ok(local_post_id) = remaining[7..].parse() {
                        Some(ReplyTarget::Post { id: local_post_id })


@@ 1777,8 1788,9 @@ pub async fn handle_like(
            get_or_fetch_user_local_id(actor_id, &db, &ctx.host_url_apub, &ctx.http_client).await?;

        if let Some(object_id) = activity.object().as_single_id() {
            let thing_local_ref = if object_id.as_str().starts_with(&ctx.host_url_apub.as_str()) {
                let remaining = &object_id.as_str()[ctx.host_url_apub.as_str().len()..];
            let thing_local_ref = if let Some(remaining) =
                try_strip_host(&object_id, &ctx.host_url_apub)
            {
                if remaining.starts_with("/posts/") {
                    if let Ok(local_post_id) = remaining[7..].parse() {
                        Some(ThingLocalRef::Post(local_post_id))

M src/routes/apub/mod.rs => src/routes/apub/mod.rs +6 -4
@@ 257,8 257,9 @@ async fn inbox_common(
                    .as_single_id()
                    .ok_or(crate::Error::InternalStrStatic("Missing object for Accept"))?;

                if object_id.as_str().starts_with(&ctx.host_url_apub.as_str()) {
                    let remaining = &object_id.as_str()[ctx.host_url_apub.as_str().len()..];
                if let Some(remaining) =
                    crate::apub_util::try_strip_host(&object_id, &ctx.host_url_apub)
                {
                    if remaining.starts_with("/communities/") {
                        let remaining = &remaining[13..];
                        let next_expected = format!("{}/followers/", community_local_id);


@@ 298,8 299,9 @@ async fn inbox_common(
                let object_id = activity.object().as_single_id();

                if let Some(object_id) = object_id {
                    if object_id.as_str().starts_with(&ctx.host_url_apub.as_str()) {
                        let remaining = &object_id.as_str()[ctx.host_url_apub.as_str().len()..];
                    if let Some(remaining) =
                        crate::apub_util::try_strip_host(&object_id, &ctx.host_url_apub)
                    {
                        if remaining.starts_with("/posts/") {
                            let remaining = &remaining[7..];
                            if let Ok(local_post_id) = remaining.parse::<PostLocalID>() {

M src/routes/well_known.rs => src/routes/well_known.rs +23 -23
@@ 72,34 72,34 @@ async fn handler_webfinger_get(
        Name(&'a str),
    }

    let found_ref = if query.resource.starts_with(&ctx.host_url_apub.as_str()) {
        let rest = &query.resource[ctx.host_url_apub.as_str().len()..];
        if rest.starts_with("/users/") {
            if let Ok(id) = rest[7..].parse() {
                Some(LocalRef::UserID(id))
            } else {
                None
            }
        } else if rest.starts_with("/communities/") {
            if let Ok(id) = rest[13..].parse() {
                Some(LocalRef::CommunityID(id))
    let found_ref =
        if let Some(rest) = crate::apub_util::try_strip_host(&query.resource, &ctx.host_url_apub) {
            if rest.starts_with("/users/") {
                if let Ok(id) = rest[7..].parse() {
                    Some(LocalRef::UserID(id))
                } else {
                    None
                }
            } else if rest.starts_with("/communities/") {
                if let Ok(id) = rest[13..].parse() {
                    Some(LocalRef::CommunityID(id))
                } else {
                    None
                }
            } else {
                None
            }
        } else if query.resource.starts_with("acct:")
            && query
                .resource
                .ends_with(&format!("@{}", ctx.local_hostname))
        {
            let name = &query.resource[5..(query.resource.len() - (ctx.local_hostname.len() + 1))];

            Some(LocalRef::Name(name))
        } else {
            None
        }
    } else if query.resource.starts_with("acct:")
        && query
            .resource
            .ends_with(&format!("@{}", ctx.local_hostname))
    {
        let name = &query.resource[5..(query.resource.len() - (ctx.local_hostname.len() + 1))];

        Some(LocalRef::Name(name))
    } else {
        None
    };
        };

    let db = ctx.db_pool.get().await?;