Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jupiter = { path = "jupiter" }
venus = { path = "venus" }
ceres = { path = "ceres" }
callisto = { path = "jupiter/callisto" }
gemini = { path = "gemini" }
anyhow = "1.0.83"
serde = "1.0.201"
serde_json = "1.0.117"
Expand Down
1 change: 1 addition & 0 deletions gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ common = { workspace = true }
jupiter = { workspace = true }
callisto = { workspace = true }
ceres = { workspace = true }
gemini = { workspace = true }
venus = { workspace = true }
mercury = { workspace = true }
anyhow = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion gateway/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

mod api_service;
mod git_protocol;
pub mod https_server;
pub mod init;
mod lfs;
mod model;
pub mod relay_server;
pub mod ssh_server;

#[cfg(test)]
Expand Down
100 changes: 100 additions & 0 deletions gateway/src/relay_server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::net::SocketAddr;
use std::str::FromStr;

use axum::body::Body;
use axum::extract::{Query, State};
use axum::http::{Response, StatusCode, Uri};
use axum::routing::get;
use axum::Router;
use clap::Args;
use common::config::Config;
use common::model::{CommonOptions, GetParams};
use jupiter::context::Context;
use regex::Regex;
use tower::ServiceBuilder;
use tower_http::cors::{Any, CorsLayer};
use tower_http::decompression::RequestDecompressionLayer;
use tower_http::trace::TraceLayer;

use crate::api_service;
use crate::api_service::router::ApiServiceState;

#[derive(Args, Clone, Debug)]
pub struct RelayOptions {
#[clap(flatten)]
pub common: CommonOptions,

#[arg(long, default_value_t = 8001)]
pub http_port: u16,
}

pub async fn http_server(config: Config, options: RelayOptions) {
let RelayOptions {
common: CommonOptions { host },
http_port,
} = options;

let app = app(config, host.clone(), http_port).await;

let server_url = format!("{}:{}", host, http_port);

let addr = SocketAddr::from_str(&server_url).unwrap();
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app.into_make_service())
.await
.unwrap();
}

#[derive(Clone)]
pub struct AppState {
pub context: Context,
pub host: String,
pub port: u16,
}

pub async fn app(config: Config, host: String, port: u16) -> Router {
let state = AppState {
host,
port,
context: Context::new(config.clone()).await,
};

let api_state = ApiServiceState {
context: Context::new(config).await,
};

// add RequestDecompressionLayer for handle gzip encode
// add TraceLayer for log record
// add CorsLayer to add cors header
Router::new()
.nest(
"/api/v1",
api_service::router::routers().with_state(api_state),
)
.route(
"/*path",
get(get_method_router), // .post(post_method_router)
// .put(put_method_router),
)
.layer(ServiceBuilder::new().layer(CorsLayer::new().allow_origin(Any)))
.layer(TraceLayer::new_for_http())
.layer(RequestDecompressionLayer::new())
.with_state(state)
}

async fn get_method_router(
_state: State<AppState>,
Query(params): Query<GetParams>,
uri: Uri,
) -> Result<Response<Body>, (StatusCode, String)> {
if Regex::new(r"/hello$").unwrap().is_match(uri.path()) {
return gemini::http::handler::hello_gemini(params).await;
}
Err((
StatusCode::NOT_FOUND,
String::from("Operation not supported\n"),
))
}

#[cfg(test)]
mod tests {}
15 changes: 15 additions & 0 deletions gemini/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "gemini"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
name = "gemini"
path = "src/lib.rs"


[dependencies]
common = { workspace = true }
axum = { workspace = true }
14 changes: 14 additions & 0 deletions gemini/src/http/handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use axum::{
body::Body,
http::{Response, StatusCode},
};
use common::model::GetParams;

pub async fn hello_gemini(_params: GetParams) -> Result<Response<Body>, (StatusCode, String)> {
Ok(Response::builder()
.body(Body::from("hello gemini"))
.unwrap())
}

#[cfg(test)]
mod tests {}
1 change: 1 addition & 0 deletions gemini/src/http/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod handler;
1 change: 1 addition & 0 deletions gemini/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod http;
10 changes: 9 additions & 1 deletion mega/src/commands/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ use common::{config::Config, errors::MegaResult};
mod http;
mod https;
mod multi;
mod relay;
mod ssh;

// This function generates the CLI for the 'service' command.
// It includes subcommands for each server type.
pub fn cli() -> Command {
let subcommands = vec![http::cli(), https::cli(), ssh::cli(), multi::cli()];
let subcommands = vec![
http::cli(),
https::cli(),
ssh::cli(),
multi::cli(),
relay::cli(),
];
Command::new("service")
.about("Start different kinds of server: for example https or ssh")
.subcommands(subcommands)
Expand All @@ -37,6 +44,7 @@ pub(crate) async fn exec(config: Config, args: &ArgMatches) -> MegaResult {
"https" => https::exec(config, subcommand_args).await,
"ssh" => ssh::exec(config, subcommand_args).await,
"multi" => multi::exec(config, subcommand_args).await,
"relay" => relay::exec(config, subcommand_args).await,
_ => Ok(()),
}
}
Expand Down
21 changes: 21 additions & 0 deletions mega/src/commands/service/relay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use clap::{ArgMatches, Args, Command, FromArgMatches};

use common::{config::Config, errors::MegaResult};
use gateway::relay_server::{self, RelayOptions};

pub fn cli() -> Command {
RelayOptions::augment_args_for_update(Command::new("relay").about("Start Mega RELAY server"))
}

pub(crate) async fn exec(config: Config, args: &ArgMatches) -> MegaResult {
let relay_matchers = RelayOptions::from_arg_matches(args)
.map_err(|err| err.exit())
.unwrap();

tracing::info!("{relay_matchers:#?}");
relay_server::http_server(config, relay_matchers).await;
Ok(())
}

#[cfg(test)]
mod tests {}