mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
refactor: move events into controller files
This commit is contained in:
@@ -5,20 +5,105 @@ use crate::http::dto_v2::{
|
||||
use crate::http::server::collect_to_json::CollectToJson;
|
||||
use crate::http::server::controller::check_pin;
|
||||
use crate::http::server::error::AppError;
|
||||
use crate::http::server::event::{PrepareUploadDecisionV2, ServerEventV2, SessionEndReasonV2};
|
||||
use crate::http::server::query::parse_query;
|
||||
use crate::http::server::response::{empty_body, BoxedBody, JsonResponse};
|
||||
use crate::http::server::session::{FileStatusV2, SessionFileV2, SessionStateV2, UploadSessionV2};
|
||||
use crate::http::server::{AppState, RequestClientInfo, V2State};
|
||||
use crate::model::transfer::FileDto;
|
||||
use bytes::Bytes;
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::{Request, Response, StatusCode};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::net::IpAddr;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Events emitted by the v2 HTTP server that must be handled by the application.
|
||||
#[derive(Debug)]
|
||||
pub enum ServerEventV2 {
|
||||
/// A device registered itself via `POST /api/localsend/v2/register`.
|
||||
Register {
|
||||
/// The IP address of the remote device.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The device information sent by the remote device.
|
||||
info: RegisterDtoV2,
|
||||
},
|
||||
|
||||
/// A sender requests to upload files via `POST /api/localsend/v2/prepare-upload`.
|
||||
///
|
||||
/// The application must answer on `decision_tx`.
|
||||
/// Dropping `decision_tx` results in a 500 response.
|
||||
PrepareUpload {
|
||||
/// The IP address of the sender.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The device information of the sender.
|
||||
info: RegisterDtoV2,
|
||||
|
||||
/// The offered files, mapped by file ID.
|
||||
files: HashMap<String, FileDto>,
|
||||
|
||||
/// Channel to send the decision (accept all, a subset, or decline).
|
||||
decision_tx: oneshot::Sender<PrepareUploadDecisionV2>,
|
||||
},
|
||||
|
||||
/// An accepted file is being uploaded via `POST /api/localsend/v2/upload`.
|
||||
///
|
||||
/// Binary chunks arrive on `binary_rx` until the channel is closed.
|
||||
/// The application should compare the number of received bytes with `file.size`
|
||||
/// and report the result on `result_tx` which determines the HTTP response
|
||||
/// (200 on `Ok`, 500 on `Err` or when `result_tx` is dropped).
|
||||
FileUpload {
|
||||
/// The session ID of the upload session.
|
||||
session_id: String,
|
||||
|
||||
/// The ID of the file being uploaded.
|
||||
file_id: String,
|
||||
|
||||
/// The metadata of the file being uploaded.
|
||||
file: FileDto,
|
||||
|
||||
/// Channel receiving the binary chunks of the file.
|
||||
binary_rx: mpsc::Receiver<Bytes>,
|
||||
|
||||
/// Channel to report whether the file was processed successfully.
|
||||
result_tx: oneshot::Sender<Result<(), String>>,
|
||||
},
|
||||
|
||||
/// An upload session ended.
|
||||
SessionEnd {
|
||||
/// The session ID of the ended session.
|
||||
session_id: String,
|
||||
|
||||
/// Why the session ended.
|
||||
reason: SessionEndReasonV2,
|
||||
},
|
||||
}
|
||||
|
||||
/// The application's decision for a prepare-upload request.
|
||||
#[derive(Debug)]
|
||||
pub enum PrepareUploadDecisionV2 {
|
||||
/// Accept the given file IDs (a subset of the offered files).
|
||||
/// An empty set responds with 204 (no file transfer needed).
|
||||
Accept(HashSet<String>),
|
||||
|
||||
/// Decline the request (403).
|
||||
Decline,
|
||||
}
|
||||
|
||||
/// Why an upload session ended.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum SessionEndReasonV2 {
|
||||
/// All accepted files reached a final state (finished or failed).
|
||||
Finished,
|
||||
|
||||
/// The sender cancelled the session via `POST /api/localsend/v2/cancel`.
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
/// Channel capacity for file upload chunks (provides backpressure).
|
||||
const UPLOAD_CHANNEL_CAPACITY: usize = 16;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ use crate::http::dto_v2::{
|
||||
};
|
||||
use crate::http::server::controller::check_pin;
|
||||
use crate::http::server::error::AppError;
|
||||
use crate::http::server::event::WebSendEvent;
|
||||
use crate::http::server::query::parse_query;
|
||||
use crate::http::server::response::{full_body, BoxedBody, JsonResponse};
|
||||
use crate::http::server::{AppState, RequestClientInfo};
|
||||
@@ -23,6 +22,51 @@ use tokio::sync::{mpsc, oneshot, Mutex};
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
/// Events emitted by the web send (download API) endpoints that must be handled
|
||||
/// by the application. Web send can be enabled independently of the v2 endpoints.
|
||||
#[derive(Debug)]
|
||||
pub enum WebSendEvent {
|
||||
/// A web client requests to download the shared files
|
||||
/// via `POST /api/localsend/v2/prepare-download`.
|
||||
///
|
||||
/// The application must answer on `decision_tx`.
|
||||
/// Dropping `decision_tx` results in a 500 response.
|
||||
PrepareDownload {
|
||||
/// The IP address of the web client.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The ID of the download session that is created when accepted.
|
||||
session_id: String,
|
||||
|
||||
/// The `User-Agent` header of the web client.
|
||||
user_agent: Option<String>,
|
||||
|
||||
/// Channel to send the decision (`true` to accept, `false` to decline).
|
||||
decision_tx: oneshot::Sender<bool>,
|
||||
},
|
||||
|
||||
/// An accepted web client downloads a file via `GET /api/localsend/v2/download`.
|
||||
///
|
||||
/// The application must respond on `content_tx` with a channel receiving
|
||||
/// the binary chunks of the file. The response body advertises `file.size`
|
||||
/// bytes, so the application should send exactly that many bytes before
|
||||
/// closing the channel (closing it earlier aborts the download).
|
||||
/// Dropping `content_tx` results in a 500 response.
|
||||
FileDownload {
|
||||
/// The ID of the download session.
|
||||
session_id: String,
|
||||
|
||||
/// The ID of the file being downloaded.
|
||||
file_id: String,
|
||||
|
||||
/// The metadata of the file being downloaded.
|
||||
file: FileDto,
|
||||
|
||||
/// Channel to provide the receiver on which the file content arrives.
|
||||
content_tx: oneshot::Sender<mpsc::Receiver<Bytes>>,
|
||||
},
|
||||
}
|
||||
|
||||
const INDEX_HTML: &str = include_str!("../../../../assets/web/index.html");
|
||||
const MAIN_JS: &str = include_str!("../../../../assets/web/main.js");
|
||||
const ERROR_403_HTML: &str = include_str!("../../../../assets/web/error-403.html");
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
use crate::http::dto_v2::RegisterDtoV2;
|
||||
use crate::model::transfer::FileDto;
|
||||
use bytes::Bytes;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::net::IpAddr;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
/// Events emitted by the v2 HTTP server that must be handled by the application.
|
||||
#[derive(Debug)]
|
||||
pub enum ServerEventV2 {
|
||||
/// A device registered itself via `POST /api/localsend/v2/register`.
|
||||
Register {
|
||||
/// The IP address of the remote device.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The device information sent by the remote device.
|
||||
info: RegisterDtoV2,
|
||||
},
|
||||
|
||||
/// A sender requests to upload files via `POST /api/localsend/v2/prepare-upload`.
|
||||
///
|
||||
/// The application must answer on `decision_tx`.
|
||||
/// Dropping `decision_tx` results in a 500 response.
|
||||
PrepareUpload {
|
||||
/// The IP address of the sender.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The device information of the sender.
|
||||
info: RegisterDtoV2,
|
||||
|
||||
/// The offered files, mapped by file ID.
|
||||
files: HashMap<String, FileDto>,
|
||||
|
||||
/// Channel to send the decision (accept all, a subset, or decline).
|
||||
decision_tx: oneshot::Sender<PrepareUploadDecisionV2>,
|
||||
},
|
||||
|
||||
/// An accepted file is being uploaded via `POST /api/localsend/v2/upload`.
|
||||
///
|
||||
/// Binary chunks arrive on `binary_rx` until the channel is closed.
|
||||
/// The application should compare the number of received bytes with `file.size`
|
||||
/// and report the result on `result_tx` which determines the HTTP response
|
||||
/// (200 on `Ok`, 500 on `Err` or when `result_tx` is dropped).
|
||||
FileUpload {
|
||||
/// The session ID of the upload session.
|
||||
session_id: String,
|
||||
|
||||
/// The ID of the file being uploaded.
|
||||
file_id: String,
|
||||
|
||||
/// The metadata of the file being uploaded.
|
||||
file: FileDto,
|
||||
|
||||
/// Channel receiving the binary chunks of the file.
|
||||
binary_rx: mpsc::Receiver<Bytes>,
|
||||
|
||||
/// Channel to report whether the file was processed successfully.
|
||||
result_tx: oneshot::Sender<Result<(), String>>,
|
||||
},
|
||||
|
||||
/// An upload session ended.
|
||||
SessionEnd {
|
||||
/// The session ID of the ended session.
|
||||
session_id: String,
|
||||
|
||||
/// Why the session ended.
|
||||
reason: SessionEndReasonV2,
|
||||
},
|
||||
}
|
||||
|
||||
/// Events emitted by the web send (download API) endpoints that must be handled
|
||||
/// by the application. Web send can be enabled independently of the v2 endpoints.
|
||||
#[derive(Debug)]
|
||||
pub enum WebSendEvent {
|
||||
/// A web client requests to download the shared files
|
||||
/// via `POST /api/localsend/v2/prepare-download`.
|
||||
///
|
||||
/// The application must answer on `decision_tx`.
|
||||
/// Dropping `decision_tx` results in a 500 response.
|
||||
PrepareDownload {
|
||||
/// The IP address of the web client.
|
||||
ip: IpAddr,
|
||||
|
||||
/// The ID of the download session that is created when accepted.
|
||||
session_id: String,
|
||||
|
||||
/// The `User-Agent` header of the web client.
|
||||
user_agent: Option<String>,
|
||||
|
||||
/// Channel to send the decision (`true` to accept, `false` to decline).
|
||||
decision_tx: oneshot::Sender<bool>,
|
||||
},
|
||||
|
||||
/// An accepted web client downloads a file via `GET /api/localsend/v2/download`.
|
||||
///
|
||||
/// The application must respond on `content_tx` with a channel receiving
|
||||
/// the binary chunks of the file. The response body advertises `file.size`
|
||||
/// bytes, so the application should send exactly that many bytes before
|
||||
/// closing the channel (closing it earlier aborts the download).
|
||||
/// Dropping `content_tx` results in a 500 response.
|
||||
FileDownload {
|
||||
/// The ID of the download session.
|
||||
session_id: String,
|
||||
|
||||
/// The ID of the file being downloaded.
|
||||
file_id: String,
|
||||
|
||||
/// The metadata of the file being downloaded.
|
||||
file: FileDto,
|
||||
|
||||
/// Channel to provide the receiver on which the file content arrives.
|
||||
content_tx: oneshot::Sender<mpsc::Receiver<Bytes>>,
|
||||
},
|
||||
}
|
||||
|
||||
/// The application's decision for a prepare-upload request.
|
||||
#[derive(Debug)]
|
||||
pub enum PrepareUploadDecisionV2 {
|
||||
/// Accept the given file IDs (a subset of the offered files).
|
||||
/// An empty set responds with 204 (no file transfer needed).
|
||||
Accept(HashSet<String>),
|
||||
|
||||
/// Decline the request (403).
|
||||
Decline,
|
||||
}
|
||||
|
||||
/// Why an upload session ended.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum SessionEndReasonV2 {
|
||||
/// All accepted files reached a final state (finished or failed).
|
||||
Finished,
|
||||
|
||||
/// The sender cancelled the session via `POST /api/localsend/v2/cancel`.
|
||||
Cancelled,
|
||||
}
|
||||
@@ -2,18 +2,19 @@ mod client_cert_verifier;
|
||||
mod collect_to_json;
|
||||
mod controller;
|
||||
mod error;
|
||||
pub mod event;
|
||||
mod query;
|
||||
mod response;
|
||||
mod session;
|
||||
|
||||
pub use crate::http::server::controller::web::{WebSendConfig, WebSendI18n};
|
||||
pub use crate::http::server::controller::v2::{
|
||||
PrepareUploadDecisionV2, ServerEventV2, SessionEndReasonV2,
|
||||
};
|
||||
pub use crate::http::server::controller::web::{WebSendConfig, WebSendEvent, WebSendI18n};
|
||||
|
||||
use crate::crypto::cert::public_key_from_cert_der;
|
||||
use crate::http::server::client_cert_verifier::CustomClientCertVerifier;
|
||||
use crate::http::server::controller::web::WebPageState;
|
||||
use crate::http::server::error::AppError;
|
||||
use crate::http::server::event::ServerEventV2;
|
||||
use crate::http::server::response::BoxedBody;
|
||||
use crate::http::server::session::SessionStateV2;
|
||||
use crate::http::state::ClientInfo;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ mod webrtc;
|
||||
use crate::crypto::token;
|
||||
use crate::http::client::LsHttpClientV3;
|
||||
use crate::http::dto::{PrepareUploadRequestDto, ProtocolType, RegisterDto};
|
||||
use crate::http::server::event::{PrepareUploadDecisionV2, ServerEventV2};
|
||||
use crate::http::server::{PrepareUploadDecisionV2, ServerEventV2};
|
||||
use crate::http::server::{ServerConfigV2, TlsConfig};
|
||||
use crate::model::discovery::DeviceType;
|
||||
use crate::webrtc::signaling::{ClientInfo, WsServerMessage};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use localsend::http::client::{ClientError, LsHttpClientV2};
|
||||
use localsend::http::dto::ProtocolType;
|
||||
use localsend::http::dto_v2::{PrepareUploadRequestDtoV2, ProtocolTypeV2, RegisterDtoV2};
|
||||
use localsend::http::server::event::{PrepareUploadDecisionV2, ServerEventV2, SessionEndReasonV2};
|
||||
use localsend::http::server::{PrepareUploadDecisionV2, ServerEventV2, SessionEndReasonV2};
|
||||
use localsend::http::server::{start_with_port, ServerConfigV2};
|
||||
use localsend::http::state::ClientInfo;
|
||||
use localsend::model::transfer::FileDto;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use bytes::Bytes;
|
||||
use localsend::http::client::{ClientError, LsHttpClientV2};
|
||||
use localsend::http::dto::ProtocolType;
|
||||
use localsend::http::server::event::{ServerEventV2, WebSendEvent};
|
||||
use localsend::http::server::{ServerEventV2, WebSendEvent};
|
||||
use localsend::http::server::{start_with_port, ServerConfigV2, WebSendConfig, WebSendI18n};
|
||||
use localsend::http::state::ClientInfo;
|
||||
use localsend::model::transfer::FileDto;
|
||||
|
||||
Reference in New Issue
Block a user