Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Improve data-uri support
Sebastian Martinez committed 2 years ago
commit da7258d2bf01418c61701c7fdc059a53c127a0c4
parent b47609a06e350bae05a1349b704ec81da985740a
2 files changed +41 -29
modified radicle-httpd/src/api.rs
@@ -10,13 +10,14 @@ use axum::http::Method;
use axum::response::{IntoResponse, Json};
use axum::routing::get;
use axum::Router;
+
use base64::prelude::{Engine, BASE64_STANDARD};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::sync::RwLock;
use tower_http::cors::{self, CorsLayer};

-
use radicle::cob::issue;
use radicle::cob::patch;
+
use radicle::cob::{issue, Uri};
use radicle::identity::Id;
use radicle::node::routing::Store;
use radicle::storage::{ReadRepository, ReadStorage};
@@ -204,3 +205,29 @@ mod project {
        pub trackings: usize,
    }
}
+

+
/// A `data:` URI.
+
#[derive(Debug, Clone)]
+
pub struct DataUri(Vec<u8>);
+

+
impl From<DataUri> for Vec<u8> {
+
    fn from(value: DataUri) -> Self {
+
        value.0
+
    }
+
}
+

+
impl TryFrom<&Uri> for DataUri {
+
    type Error = Uri;
+

+
    fn try_from(value: &Uri) -> Result<Self, Self::Error> {
+
        if let Some(data_uri) = value.as_str().strip_prefix("data:") {
+
            let (_, uri_data) = data_uri.split_once(',').ok_or(value.clone())?;
+
            let uri_data = BASE64_STANDARD
+
                .decode(uri_data)
+
                .map_err(|_| value.clone())?;
+

+
            return Ok(DataUri(uri_data));
+
        }
+
        Err(value.clone())
+
    }
+
}
modified radicle-httpd/src/api/v1/projects.rs
@@ -7,7 +7,6 @@ use axum::response::IntoResponse;
use axum::routing::{get, patch, post};
use axum::{Json, Router};
use axum_auth::AuthBearer;
-
use base64::prelude::{Engine, BASE64_STANDARD};
use hyper::StatusCode;
use radicle_surf::blob::{Blob, BlobRef};
use serde::{Deserialize, Serialize};
@@ -25,7 +24,7 @@ use radicle_surf::{diff, Glob, Oid, Repository};

use crate::api::error::Error;
use crate::api::project::Info;
-
use crate::api::{self, CobsQuery, Context, PaginationQuery};
+
use crate::api::{self, CobsQuery, Context, DataUri, PaginationQuery};
use crate::axum_extra::{Path, Query};

const CACHE_1_HOUR: &str = "public, max-age=3600, must-revalidate";
@@ -534,18 +533,11 @@ async fn issue_create_handler(
        .embeds
        .into_iter()
        .filter_map(|embed| {
-
            if let Some(content) = embed
-
                .content
-
                .as_str()
-
                .strip_prefix("data:content/type;base64,")
-
            {
-
                return BASE64_STANDARD.decode(content).ok().map(|content| Embed {
-
                    name: embed.name,
-
                    content,
-
                });
-
            }
-

-
            None
+
            let content = TryInto::<DataUri>::try_into(&embed.content).ok()?;
+
            Some(Embed {
+
                name: embed.name,
+
                content: content.into(),
+
            })
        })
        .collect();

@@ -604,18 +596,11 @@ async fn issue_update_handler(
            let embeds: Vec<Embed> = embeds
                .into_iter()
                .filter_map(|embed| {
-
                    if let Some(content) = embed
-
                        .content
-
                        .as_str()
-
                        .strip_prefix("data:content/type;base64,")
-
                    {
-
                        return BASE64_STANDARD.decode(content).ok().map(|content| Embed {
-
                            name: embed.name,
-
                            content,
-
                        });
-
                    }
-

-
                    None
+
                    let content = TryInto::<DataUri>::try_into(&embed.content).ok()?;
+
                    Some(Embed {
+
                        name: embed.name,
+
                        content: content.into(),
+
                    })
                })
                .collect();
            if let Some(to) = reply_to {
@@ -1848,7 +1833,7 @@ mod routes {
            "embeds": [
              {
                "name": "example.html",
-
                "content": "data:content/type;base64,PGh0bWw+SGVsbG8gV29ybGQhPC9odG1sPg=="
+
                "content": "data:image/png;base64,PGh0bWw+SGVsbG8gV29ybGQhPC9odG1sPg=="
              }
            ],
            "assignees": [],
@@ -1924,7 +1909,7 @@ mod routes {
          "embeds": [
            {
              "name": "image.jpg",
-
              "content": "data:content/type;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC"
+
              "content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC"
            }
          ],
          "replyTo": CONTRIBUTOR_ISSUE_ID,