Skip to content

Commit

Permalink
Implement correct handling of data URLs (#81)
Browse files Browse the repository at this point in the history
* Implement correct handling of data URLs

* Small fixes

* Small fixes
  • Loading branch information
Antony1060 authored Feb 23, 2024
1 parent bc1df65 commit 4ff8b7f
Show file tree
Hide file tree
Showing 16 changed files with 364 additions and 184 deletions.
24 changes: 16 additions & 8 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 18 additions & 4 deletions server/src/routes/header.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::sync::Arc;

use axum::extract::{Path, Query, State};
use axum::response::Redirect;
use axum::http::header::CONTENT_TYPE;
use axum::http::StatusCode;
use axum::response::{AppendHeaders, IntoResponse, Redirect};
use enstate_shared::core::error::ProfileError;
use enstate_shared::core::lookup_data::LookupInfo;
use enstate_shared::models::lookup::ENSLookup;

use crate::routes::{profile_http_error_mapper, FreshQuery, RouteError};
use crate::routes::{FreshQuery, http_simple_status_error, profile_http_error_mapper, RouteError};

// #[utoipa::path(
// get,
Expand All @@ -25,7 +27,7 @@ pub async fn get(
Path(name_or_address): Path<String>,
Query(query): Query<FreshQuery>,
State(state): State<Arc<crate::AppState>>,
) -> Result<Redirect, RouteError> {
) -> Result<impl IntoResponse, RouteError> {
let info = LookupInfo::guess(name_or_address)
.map_err(|_| profile_http_error_mapper(ProfileError::NotFound))?;

Expand All @@ -35,5 +37,17 @@ pub async fn get(
.await
.map_err(profile_http_error_mapper)?;

Ok(Redirect::to(header.as_str()))
if let Some(processed) = enstate_shared::utils::data_url::process_data_url_image(&header) {
let Ok(processed) = processed else {
return Err(http_simple_status_error(StatusCode::UNSUPPORTED_MEDIA_TYPE).into());
};

return Ok((
AppendHeaders([(CONTENT_TYPE, processed.mimetype)]),
processed.data,
)
.into_response());
}

Ok(Redirect::to(header.as_str()).into_response())
}
24 changes: 19 additions & 5 deletions server/src/routes/image.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::sync::Arc;

use axum::extract::{Path, Query, State};
use axum::response::Redirect;
use axum::http::header::CONTENT_TYPE;
use axum::http::StatusCode;
use axum::response::{AppendHeaders, IntoResponse, Redirect};
use enstate_shared::core::error::ProfileError;
use enstate_shared::core::lookup_data::LookupInfo;
use enstate_shared::models::lookup::ENSLookup;

use crate::routes::{profile_http_error_mapper, FreshQuery, RouteError};
use crate::routes::{FreshQuery, http_simple_status_error, profile_http_error_mapper, RouteError};

// #[utoipa::path(
// get,
Expand All @@ -25,15 +27,27 @@ pub async fn get(
Path(name_or_address): Path<String>,
Query(query): Query<FreshQuery>,
State(state): State<Arc<crate::AppState>>,
) -> Result<Redirect, RouteError> {
) -> Result<impl IntoResponse, RouteError> {
let info = LookupInfo::guess(name_or_address)
.map_err(|_| profile_http_error_mapper(ProfileError::NotFound))?;

let avatar = state
.service
.resolve_record_simple(info, ENSLookup::Image("avatar".to_string()), query.fresh)
.resolve_record_simple(info, ENSLookup::StaticImage("avatar"), query.fresh)
.await
.map_err(profile_http_error_mapper)?;

Ok(Redirect::to(avatar.as_str()))
if let Some(processed) = enstate_shared::utils::data_url::process_data_url_image(&avatar) {
let Ok(processed) = processed else {
return Err(http_simple_status_error(StatusCode::UNSUPPORTED_MEDIA_TYPE).into());
};

return Ok((
AppendHeaders([(CONTENT_TYPE, processed.mimetype)]),
processed.data,
)
.into_response());
}

Ok(Redirect::to(avatar.as_str()).into_response())
}
24 changes: 16 additions & 8 deletions shared/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ reqwest = "0.11.22"
ethers-ccip-read = { git = "https://github.com/ensdomains/ethers-ccip-read" }
build-info = "0.0.34"
itertools = "0.12.0"
url = "2.5.0"
data-url = "0.3.1"

# needed to enable the "js" feature for compatibility with wasm,
# see https://docs.rs/getrandom/#webassembly-support
Expand Down
13 changes: 8 additions & 5 deletions shared/src/models/eip155/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ use ethers::middleware::Middleware;
use ethers::providers::ProviderError;
use ethers_core::{
abi::{ParamType, Token},
types::{transaction::eip2718::TypedTransaction, Bytes, H160, U256},
types::{Bytes, H160, transaction::eip2718::TypedTransaction, U256},
};
use thiserror::Error;
use tracing::info;

use crate::models::ipfs::{URLFetchError, OPENSEA_BASE_PREFIX};
use crate::models::eip155::url::{OPENSEA_BASE_PREFIX, URLFetchError, URLParseError, URLUnparsed};
use crate::models::lookup::LookupState;
use crate::models::multicoin::cointype::evm::ChainId;

use super::ipfs::IPFSURLUnparsed;
mod url;

#[derive(Error, Debug)]
pub enum EIP155Error {
Expand All @@ -24,6 +24,9 @@ pub enum EIP155Error {
#[error("Metadata fetch error: {0}")]
MetadataFetchError(#[from] URLFetchError),

#[error("Not a valid URL: {0}")]
InvalidURL(#[from] URLParseError),

#[error("Implementation error: {0}")]
ImplementationError(String),

Expand Down Expand Up @@ -112,15 +115,15 @@ pub async fn resolve_eip155(
info!("Token Metadata URL: {}", token_metadata_url);

// TODO: Validate URL here
let token_metadata_url = IPFSURLUnparsed::from_unparsed(token_metadata_url);
let token_metadata_url = URLUnparsed::from_unparsed(&token_metadata_url)?;

let token_metadata = token_metadata_url.fetch(state).await?;

let image = token_metadata.image.ok_or(EIP155Error::Other)?;

info!("Image: {}", image);

let token_image_url = IPFSURLUnparsed::from_unparsed(image).to_url_or_gateway(state);
let token_image_url = URLUnparsed::from_unparsed(&image)?.to_url_or_ipfs_gateway(state);

Ok(token_image_url)
}
Expand Down
Loading

0 comments on commit 4ff8b7f

Please sign in to comment.