62 lines
2.1 KiB
Rust
62 lines
2.1 KiB
Rust
use std::sync::Arc;
|
|
|
|
use anyhow::{Context, Result};
|
|
use axum::extract::Request;
|
|
use axum::http::{Uri, header};
|
|
use axum::response::IntoResponse;
|
|
use axum::routing::{get, post};
|
|
use axum::{Extension, Router, ServiceExt, middleware};
|
|
use reqwest::StatusCode;
|
|
use rust_embed::Embed;
|
|
use sea_orm::DatabaseConnection;
|
|
use utoipa::OpenApi;
|
|
use utoipa_swagger_ui::{Config, SwaggerUi};
|
|
|
|
use crate::api::auth;
|
|
use crate::api::handler::{ApiDoc, get_video, get_video_sources, get_videos, reset_video};
|
|
use crate::config::CONFIG;
|
|
|
|
#[derive(Embed)]
|
|
#[folder = "../../web/build"]
|
|
struct Asset;
|
|
|
|
pub async fn http_server(database_connection: Arc<DatabaseConnection>) -> Result<()> {
|
|
let app = Router::new()
|
|
.route("/api/video-sources", get(get_video_sources))
|
|
.route("/api/videos", get(get_videos))
|
|
.route("/api/videos/{id}", get(get_video))
|
|
.route("/api/videos/{id}/reset", post(reset_video))
|
|
.merge(
|
|
SwaggerUi::new("/swagger-ui/")
|
|
.url("/api-docs/openapi.json", ApiDoc::openapi())
|
|
.config(
|
|
Config::default()
|
|
.try_it_out_enabled(true)
|
|
.persist_authorization(true)
|
|
.validator_url("none"),
|
|
),
|
|
)
|
|
.fallback_service(get(frontend_files))
|
|
.layer(Extension(database_connection))
|
|
.layer(middleware::from_fn(auth::auth));
|
|
let listener = tokio::net::TcpListener::bind(&CONFIG.bind_address)
|
|
.await
|
|
.context("bind address failed")?;
|
|
info!("开始监听 http 服务: http://{}", CONFIG.bind_address);
|
|
Ok(axum::serve(listener, ServiceExt::<Request>::into_make_service(app)).await?)
|
|
}
|
|
|
|
async fn frontend_files(uri: Uri) -> impl IntoResponse {
|
|
let mut path = uri.path().trim_start_matches('/');
|
|
if path.is_empty() {
|
|
path = "index.html";
|
|
}
|
|
match Asset::get(path) {
|
|
Some(content) => {
|
|
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
|
([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response()
|
|
}
|
|
None => (StatusCode::NOT_FOUND, "404 Not Found").into_response(),
|
|
}
|
|
}
|