This commit is contained in:
2023-08-12 13:19:30 +02:00
parent bd9121aa63
commit 8b87e71351
4 changed files with 30 additions and 39 deletions

1
Cargo.lock generated
View File

@@ -294,6 +294,7 @@ dependencies = [
"async-tempfile", "async-tempfile",
"axum", "axum",
"axum-prometheus", "axum-prometheus",
"futures-util",
"sentry", "sentry",
"tokio", "tokio",
"tokio-util", "tokio-util",

View File

@@ -8,6 +8,7 @@ edition = "2021"
[dependencies] [dependencies]
tokio = { version = "1.28.2", features = ["full"] } tokio = { version = "1.28.2", features = ["full"] }
tokio-util = { version = "0.7.8", features = ["compat", "io"] } tokio-util = { version = "0.7.8", features = ["compat", "io"] }
futures-util = "0.3.28"
axum = { version = "0.6.18", features = ["multipart"] } axum = { version = "0.6.18", features = ["multipart"] }
axum-prometheus = "0.4.0" axum-prometheus = "0.4.0"

View File

@@ -6,7 +6,7 @@ RUN apt-get update \
# Get converter bin # Get converter bin
WORKDIR /root/fb2converter WORKDIR /root/fb2converter
ADD https://github.com/rupor-github/fb2converter/releases/download/v1.70.0/fb2c_linux_amd64.zip ./ ADD https://github.com/rupor-github/fb2converter/releases/download/v1.71.0/fb2c_linux_amd64.zip ./
RUN unzip fb2c_linux_amd64.zip RUN unzip fb2c_linux_amd64.zip

View File

@@ -1,6 +1,7 @@
use std::{net::SocketAddr, time::{SystemTime, Duration}, str::FromStr}; use std::{net::SocketAddr, time::{SystemTime, Duration}, str::FromStr};
use axum::{Router, routing::{post, get}, extract::Multipart, response::{IntoResponse, AppendHeaders, Response}, http::{StatusCode, header, Request, self}, body::StreamBody, middleware::{Next, self}}; use axum::{Router, routing::{post, get}, extract::{Multipart, Path, BodyStream}, response::{IntoResponse, AppendHeaders, Response}, http::{StatusCode, header, Request, self}, body::StreamBody, middleware::{Next, self}};
use axum_prometheus::PrometheusMetricLayer; use axum_prometheus::PrometheusMetricLayer;
use futures_util::StreamExt;
use sentry::{ClientOptions, types::Dsn, integrations::debug_images::DebugImagesIntegration}; use sentry::{ClientOptions, types::Dsn, integrations::debug_images::DebugImagesIntegration};
use tokio::{fs::{remove_file, read_dir, remove_dir, File}, io::{AsyncWriteExt, copy}, process::Command, time::sleep}; use tokio::{fs::{remove_file, read_dir, remove_dir, File}, io::{AsyncWriteExt, copy}, process::Command, time::sleep};
use tower_http::trace::{TraceLayer, self}; use tower_http::trace::{TraceLayer, self};
@@ -35,10 +36,9 @@ async fn remove_temp_files() -> Result<(), Box<dyn std::error::Error + Send + Sy
async fn convert_file( async fn convert_file(
mut multipart: Multipart Path(file_format): Path<String>,
mut stream: BodyStream
) -> impl IntoResponse { ) -> impl IntoResponse {
let mut file_format: Option<String> = None;
let prefix = uuid::Uuid::new_v4().to_string(); let prefix = uuid::Uuid::new_v4().to_string();
let tempfile = match TempFile::new_with_name( let tempfile = match TempFile::new_with_name(
@@ -51,14 +51,6 @@ async fn convert_file(
}, },
}; };
while let Some(mut field) = multipart.next_field().await.unwrap() {
let name = field.name().unwrap().to_string();
match name.as_str() {
"format" => {
file_format = Some(field.text().await.unwrap());
},
"file" => {
let mut tempfile_rw = match tempfile.open_rw().await { let mut tempfile_rw = match tempfile.open_rw().await {
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
@@ -67,10 +59,13 @@ async fn convert_file(
}, },
}; };
while let Ok(result) = field.chunk().await { while let Some(chunk) = stream.next().await {
let data = match result { let data = match chunk {
Some(v) => v, Ok(v) => v,
None => break, Err(err) => {
log::error!("{:?}", err);
return StatusCode::INTERNAL_SERVER_ERROR.into_response()
},
}; };
match tempfile_rw.write(data.as_ref()).await { match tempfile_rw.write(data.as_ref()).await {
@@ -83,12 +78,6 @@ async fn convert_file(
} }
let _ = tempfile_rw.flush().await; let _ = tempfile_rw.flush().await;
},
_ => panic!("unknown field")
};
}
let file_format = file_format.unwrap();
let allowed_formats = vec!["epub".to_string(), "mobi".to_string()]; let allowed_formats = vec!["epub".to_string(), "mobi".to_string()];
if !allowed_formats.contains(&file_format.clone().to_lowercase()) { if !allowed_formats.contains(&file_format.clone().to_lowercase()) {
@@ -191,7 +180,7 @@ fn get_router() -> Router {
let (prometheus_layer, metric_handle) = PrometheusMetricLayer::pair(); let (prometheus_layer, metric_handle) = PrometheusMetricLayer::pair();
let app_router = Router::new() let app_router = Router::new()
.route("/", post(convert_file)) .route("/:file_format", post(convert_file))
.layer(middleware::from_fn(auth)) .layer(middleware::from_fn(auth))
.layer(prometheus_layer); .layer(prometheus_layer);