mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 13:29:21 +00:00
Start to wrap incoming stream
This commit is contained in:
parent
c551c2d764
commit
32b6c95e9f
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -91,6 +91,25 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-multipart"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4397935fca2a37a5353f94faa758fb176712806f605466b5a60373b204f0d836"
|
||||||
|
dependencies = [
|
||||||
|
"actix-service",
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"bytes",
|
||||||
|
"derive_more",
|
||||||
|
"futures",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"time",
|
||||||
|
"twoway",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@ -507,6 +526,7 @@ dependencies = [
|
|||||||
name = "comunic_server"
|
name = "comunic_server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"actix-multipart",
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1901,6 +1921,16 @@ dependencies = [
|
|||||||
"trust-dns-proto",
|
"trust-dns-proto",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "twoway"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"unchecked-index",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twox-hash"
|
name = "twox-hash"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -1916,6 +1946,12 @@ version = "1.12.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unchecked-index"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
|
@ -11,6 +11,7 @@ yaml-rust = "0.4.3"
|
|||||||
mysql = "18.2.0"
|
mysql = "18.2.0"
|
||||||
actix-web = "2.0.0"
|
actix-web = "2.0.0"
|
||||||
actix-rt = "1.1.1"
|
actix-rt = "1.1.1"
|
||||||
|
actix-multipart = "0.2.0"
|
||||||
serde = "1.0.110"
|
serde = "1.0.110"
|
||||||
serde_json = "1.0.53"
|
serde_json = "1.0.53"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
|
@ -37,4 +37,7 @@ pub mod database_tables_names {
|
|||||||
pub const DEFAULT_ACCOUNT_IMAGE: &str = "avatars/0Reverse.png";
|
pub const DEFAULT_ACCOUNT_IMAGE: &str = "avatars/0Reverse.png";
|
||||||
|
|
||||||
/// The account image to show for users who are not allowed to access other users account images
|
/// The account image to show for users who are not allowed to access other users account images
|
||||||
pub const ERROR_ACCOUNT_IMAGE: &str = "avatars/0Red.png";
|
pub const ERROR_ACCOUNT_IMAGE: &str = "avatars/0Red.png";
|
||||||
|
|
||||||
|
/// Maximum requests size (50 Mo)
|
||||||
|
pub const MAX_REQUEST_SIZE: u64 = 50000000;
|
@ -1,24 +1,42 @@
|
|||||||
use actix_web::{App, HttpResponse, HttpServer, web, http, FromRequest, HttpRequest, HttpMessage};
|
|
||||||
|
|
||||||
use crate::controllers::routes::{get_routes, Route, RequestResult};
|
|
||||||
use crate::data::config::Config;
|
|
||||||
use crate::controllers::routes::Method::{GET, POST};
|
|
||||||
use crate::data::http_request_handler::{HttpRequestHandler, RequestValue};
|
|
||||||
use actix_web::dev::{PayloadStream, Payload, Decompress};
|
|
||||||
use actix_web::web::{BytesMut};
|
|
||||||
use futures::future::{LocalBoxFuture};
|
|
||||||
use futures::{FutureExt, StreamExt};
|
|
||||||
use actix_web::error::{ErrorBadRequest};
|
|
||||||
use encoding_rs::UTF_8;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use percent_encoding::{percent_decode_str};
|
use std::io::Take;
|
||||||
use crate::api_data::http_error::HttpError;
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use actix_web::{App, FromRequest, http, HttpMessage, HttpRequest, HttpResponse, HttpServer, web};
|
||||||
|
use actix_web::dev::{Decompress, Payload, PayloadStream};
|
||||||
|
use actix_web::error::{ErrorBadRequest, PayloadError};
|
||||||
|
use actix_web::web::{Bytes, BytesMut};
|
||||||
|
use encoding_rs::UTF_8;
|
||||||
|
use futures::{FutureExt, Stream, StreamExt};
|
||||||
|
use futures::future::LocalBoxFuture;
|
||||||
|
use futures::task::{Context, Poll};
|
||||||
|
use percent_encoding::percent_decode_str;
|
||||||
|
|
||||||
|
use crate::api_data::http_error::HttpError;
|
||||||
|
use crate::constants::MAX_REQUEST_SIZE;
|
||||||
|
use crate::controllers::routes::{get_routes, RequestResult, Route};
|
||||||
|
use crate::controllers::routes::Method::{GET, POST};
|
||||||
|
use crate::data::config::Config;
|
||||||
|
use crate::data::http_request_handler::{HttpRequestHandler, RequestValue};
|
||||||
|
|
||||||
/// Main server functions
|
/// Main server functions
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
/// Custom stream to give it a limit
|
||||||
|
struct LimitedStream {
|
||||||
|
stream: Box<dyn Stream<Item=Result<Bytes, PayloadError>> + Unpin + 'static>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Stream for LimitedStream
|
||||||
|
{
|
||||||
|
type Item = Result<Bytes, PayloadError>;
|
||||||
|
|
||||||
|
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||||
|
Pin::new(self.stream.as_mut()).poll_next(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Custom request value
|
/// Custom request value
|
||||||
struct CustomRequest {
|
struct CustomRequest {
|
||||||
req: web::HttpRequest,
|
req: web::HttpRequest,
|
||||||
@ -33,9 +51,25 @@ impl FromRequest for CustomRequest {
|
|||||||
|
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload<PayloadStream>) -> Self::Future {
|
fn from_request(req: &HttpRequest, payload: &mut Payload<PayloadStream>) -> Self::Future {
|
||||||
let req = req.clone();
|
let req = req.clone();
|
||||||
let payload = payload.take();
|
let payload = Box::new(payload.take());
|
||||||
|
|
||||||
|
let payload = LimitedStream {
|
||||||
|
stream: payload
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
|
|
||||||
|
// Check the size, if provided
|
||||||
|
if req.headers().contains_key("Content-Length") {
|
||||||
|
if let Some(v) = req.headers().get("Content-Length") {
|
||||||
|
if String::from_utf8_lossy(v.as_bytes()).parse::<u64>().unwrap_or(0) > MAX_REQUEST_SIZE {
|
||||||
|
return Err(actix_web::error::ErrorBadRequest("Request too big!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let mut body_args = HashMap::new();
|
let mut body_args = HashMap::new();
|
||||||
|
|
||||||
// Process "application/x-www-form-urlencoded" requests
|
// Process "application/x-www-form-urlencoded" requests
|
||||||
@ -88,12 +122,21 @@ impl FromRequest for CustomRequest {
|
|||||||
// Add the value to the body
|
// Add the value to the body
|
||||||
body_args.insert(
|
body_args.insert(
|
||||||
percent_decode_str(args[0]).decode_utf8_lossy().to_string(),
|
percent_decode_str(args[0]).decode_utf8_lossy().to_string(),
|
||||||
RequestValue::string(percent_decode_str(args[1]).decode_utf8_lossy().to_string())
|
RequestValue::string(percent_decode_str(args[1]).decode_utf8_lossy().to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process "multipart/form-data" request
|
||||||
|
else if req.content_type().starts_with("multipart/form-data") {
|
||||||
|
let mut req = actix_multipart::Multipart::new(req.headers(), payload);
|
||||||
|
|
||||||
|
while let Some(el) = req.next().await {
|
||||||
|
let mut field = el?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(CustomRequest {
|
Ok(CustomRequest {
|
||||||
req: req.clone(),
|
req: req.clone(),
|
||||||
body: body_args,
|
body: body_args,
|
||||||
@ -153,8 +196,7 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
|
|||||||
|
|
||||||
// Set default error response if required
|
// Set default error response if required
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
let err_msg = e.to_string();
|
||||||
let err_msg= e.to_string();
|
|
||||||
|
|
||||||
if !request.has_response() {
|
if !request.has_response() {
|
||||||
request.internal_error(e).unwrap_err();
|
request.internal_error(e).unwrap_err();
|
||||||
|
Loading…
Reference in New Issue
Block a user