VM Integration: - Add compute module with offloadable operations support - Enable distributed execution for heavy VM operations - Support batch signature verification, merkle proofs, hashing - Add ComputeContext for managing compute cluster connections - Feature-gated behind 'compute' flag Hosting Integration: - Add edge compute module for serverless functions - Support edge functions (WASM, JS, Python runtimes) - Enable server-side rendering and image optimization - Add AI/ML inference at the edge - Feature-gated behind 'compute' flag Docker Deployment: - Add docker-compose.compute.yml for compute layer - Deploy orchestrator, CPU workers, WASM worker, spot market - Include Redis for task queue and Prometheus for metrics - Reserved ports: 17250-17290 for compute services
149 lines
4.5 KiB
Rust
149 lines
4.5 KiB
Rust
//! Synor Hosting - Decentralized Web Hosting
|
|
//!
|
|
//! Provides subdomain-based hosting for web applications on Synor Storage.
|
|
//!
|
|
//! # Components
|
|
//!
|
|
//! - **Name Registry**: On-chain mapping of names to CIDs
|
|
//! - **Domain Verification**: Custom domain ownership proof
|
|
//! - **Gateway Router**: Host-based routing to content
|
|
//!
|
|
//! # Example
|
|
//!
|
|
//! ```rust,ignore
|
|
//! use synor_hosting::{NameRegistry, HostingGateway};
|
|
//!
|
|
//! // Register a name
|
|
//! registry.register("myapp", cid, owner)?;
|
|
//!
|
|
//! // Resolve name to CID
|
|
//! let cid = registry.resolve("myapp")?;
|
|
//!
|
|
//! // Gateway routes myapp.synor.network to CID
|
|
//! gateway.handle_request("myapp.synor.network", "/").await?;
|
|
//! ```
|
|
|
|
pub mod compute;
|
|
pub mod config;
|
|
pub mod domain;
|
|
pub mod error;
|
|
pub mod registry;
|
|
pub mod router;
|
|
|
|
#[cfg(feature = "server")]
|
|
pub mod server;
|
|
|
|
pub use registry::{NameRegistry, NameRecord, RegistrationRequest};
|
|
pub use domain::{DomainVerifier, DomainRecord, VerificationMethod};
|
|
pub use router::{HostingRouter, RouteConfig};
|
|
pub use config::SynorJson;
|
|
pub use error::{Error, Result};
|
|
|
|
#[cfg(feature = "server")]
|
|
pub use server::{HostingGateway, GatewayConfig};
|
|
|
|
/// Reserved names that cannot be registered
|
|
pub const RESERVED_NAMES: &[&str] = &[
|
|
"synor", "admin", "api", "gateway", "www", "mail", "ftp", "ssh",
|
|
"cdn", "static", "assets", "app", "web", "blog", "docs", "help",
|
|
"support", "status", "system", "root", "test", "dev", "staging",
|
|
"prod", "production", "null", "undefined", "localhost", "local",
|
|
];
|
|
|
|
/// Validate a name according to registry rules
|
|
pub fn validate_name(name: &str) -> Result<()> {
|
|
// Length check
|
|
if name.len() < 3 {
|
|
return Err(Error::InvalidName("Name must be at least 3 characters".into()));
|
|
}
|
|
if name.len() > 63 {
|
|
return Err(Error::InvalidName("Name must be at most 63 characters".into()));
|
|
}
|
|
|
|
// Character check
|
|
if !name.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-') {
|
|
return Err(Error::InvalidName(
|
|
"Name must contain only lowercase letters, numbers, and hyphens".into(),
|
|
));
|
|
}
|
|
|
|
// Cannot start or end with hyphen
|
|
if name.starts_with('-') || name.ends_with('-') {
|
|
return Err(Error::InvalidName("Name cannot start or end with hyphen".into()));
|
|
}
|
|
|
|
// Cannot have consecutive hyphens
|
|
if name.contains("--") {
|
|
return Err(Error::InvalidName("Name cannot contain consecutive hyphens".into()));
|
|
}
|
|
|
|
// Reserved name check
|
|
if RESERVED_NAMES.contains(&name) {
|
|
return Err(Error::ReservedName(name.to_string()));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check if a name looks confusingly similar to another
|
|
pub fn is_confusable(name: &str, other: &str) -> bool {
|
|
// Simple homoglyph detection
|
|
let normalize = |s: &str| -> String {
|
|
s.chars()
|
|
.map(|c| match c {
|
|
'0' => 'o',
|
|
'1' | 'l' => 'i',
|
|
'5' => 's',
|
|
'3' => 'e',
|
|
'4' => 'a',
|
|
'7' => 't',
|
|
'8' => 'b',
|
|
'9' => 'g',
|
|
_ => c,
|
|
})
|
|
.collect()
|
|
};
|
|
|
|
normalize(name) == normalize(other)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_validate_name_valid() {
|
|
assert!(validate_name("myapp").is_ok());
|
|
assert!(validate_name("my-app").is_ok());
|
|
assert!(validate_name("app123").is_ok());
|
|
assert!(validate_name("123app").is_ok());
|
|
assert!(validate_name("a-b-c").is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_validate_name_invalid() {
|
|
assert!(validate_name("ab").is_err()); // Too short
|
|
assert!(validate_name("MyApp").is_err()); // Uppercase
|
|
assert!(validate_name("-myapp").is_err()); // Starts with hyphen
|
|
assert!(validate_name("myapp-").is_err()); // Ends with hyphen
|
|
assert!(validate_name("my--app").is_err()); // Consecutive hyphens
|
|
assert!(validate_name("my app").is_err()); // Space
|
|
assert!(validate_name("my_app").is_err()); // Underscore
|
|
}
|
|
|
|
#[test]
|
|
fn test_reserved_names() {
|
|
assert!(validate_name("synor").is_err());
|
|
assert!(validate_name("admin").is_err());
|
|
assert!(validate_name("api").is_err());
|
|
assert!(validate_name("gateway").is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_confusable_names() {
|
|
assert!(is_confusable("g00gle", "google"));
|
|
assert!(is_confusable("paypa1", "paypal"));
|
|
assert!(is_confusable("fac3book", "facebook"));
|
|
assert!(!is_confusable("myapp", "yourapp"));
|
|
}
|
|
}
|