fix: redis, /get & /post parsing #15

Merged
nm17 merged 4 commits from dev/dc09 into master 2024-06-03 16:23:02 +03:00
6 changed files with 46 additions and 38 deletions

51
Cargo.lock generated
View file

@ -113,12 +113,6 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arcstr"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d"
[[package]]
name = "arrayvec"
version = "0.7.4"
@ -127,9 +121,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "async-broadcast"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258b52a1aa741b9f09783b2d86cf0aeeb617bbf847f6933340a39644227acbdb"
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
dependencies = [
"event-listener",
"event-listener-strategy",
@ -434,12 +428,9 @@ dependencies = [
[[package]]
name = "cookie-factory"
version = "0.3.3"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2"
dependencies = [
"futures 0.3.30",
]
checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b"
[[package]]
name = "core-foundation-sys"
@ -468,6 +459,15 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
@ -646,30 +646,29 @@ dependencies = [
[[package]]
name = "fred"
version = "6.3.2"
version = "9.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a15cc18b56395b8b15ffcdcea7fe8586e3a3ccb3d9dc3b9408800d9814efb08e"
checksum = "915e065b377f6e16d5c01eae96bf31eeaf81e1e300b76f938761b3c21307cad8"
dependencies = [
"arc-swap",
"arcstr",
"async-trait",
"bytes 1.6.0",
"bytes-utils",
"cfg-if",
"crossbeam-queue",
"float-cmp",
"futures 0.3.30",
"lazy_static",
"log",
"nom",
"parking_lot",
"rand",
"redis-protocol",
"semver",
"sha-1",
"socket2",
"tokio",
"tokio-stream",
"tokio-util",
"url",
"urlencoding",
]
[[package]]
@ -1675,9 +1674,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.84"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
dependencies = [
"unicode-ident",
]
@ -1749,9 +1748,9 @@ dependencies = [
[[package]]
name = "redis-protocol"
version = "4.1.0"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c31deddf734dc0a39d3112e73490e88b61a05e83e074d211f348404cee4d2c6"
checksum = "65deb7c9501fbb2b6f812a30d59c0253779480853545153a51d8e9e444ddc99f"
dependencies = [
"bytes 1.6.0",
"bytes-utils",
@ -2441,6 +2440,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf8parse"
version = "0.2.1"

View file

@ -13,7 +13,7 @@ chrono = { version = "0.4.26", features = ["serde"] }
clap = { version = "4.3.8", features = ["derive", "env"] }
derive_more = "0.99.17"
dotenvy = "0.15.7"
fred = { version = "6.3.0", features = ["nom"] }
fred = { version = "9.0.3", features = ["nom"] }
heapless = { version = "0.7.16", features = ["ufmt-impl"] }
hex = { version = "0.4.3", default-features = false, features = ["std", "alloc"] }
hifitime = "3.8.2"

View file

@ -13,6 +13,8 @@ use crate::web_server::old_device_sensor_api::qs_parser::QSParserError;
use rust_decimal::Decimal;
use serde_json::json;
use super::old_device_sensor_api::qs_parser;
/// Главный объект ошибки [std::error::Error] для всего Web API.
///
/// В целом, все Result у Web сервера должны использовать этот Error.
@ -42,10 +44,13 @@ pub enum AppError {
min: Option<Decimal>,
},
#[display(fmt = "UTF8")]
Utf8Error(#[from] std::str::Utf8Error),
#[display(fmt = "IDK")]
UnknownBody {
json_err: Option<serde_json::Error>,
query_error: Option<serde_qs::Error>,
query_error: Option<qs_parser::QSParserError>,
},
#[display(fmt = "IDK")]
@ -61,6 +66,7 @@ impl web::error::WebResponseError for AppError {
AppError::RequestTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
AppError::ServerRedisError(_) => StatusCode::INTERNAL_SERVER_ERROR,
AppError::ApiKeyInvalid { .. } => StatusCode::BAD_REQUEST,
AppError::Utf8Error(_) => StatusCode::BAD_REQUEST,
AppError::UnknownBody { .. } => StatusCode::BAD_REQUEST,
AppError::QSError(..) => StatusCode::BAD_REQUEST,
AppError::DeviceNotFound(..) => StatusCode::BAD_REQUEST,
@ -75,6 +81,7 @@ impl web::error::WebResponseError for AppError {
AppError::RequestTooLarge => "Request is too large",
AppError::ServerRedisError(_) => "Internal server error",
AppError::ApiKeyInvalid { .. } => "API Key invalid",
AppError::Utf8Error(_) => "Invalid UTF8 sequence",
AppError::UnknownBody { .. } => {
"Can't figure out where and in what encoding the main data is"
}

View file

@ -24,14 +24,8 @@ use crate::web_server::old_device_sensor_api::device_handler;
use ntex::web;
pub async fn server_main() {
let config = RedisConfig::default();
let perf = PerformanceConfig::default();
let policy = ReconnectPolicy::default();
let client = RedisClient::new(config, Some(perf), Some(policy));
// connect to the server, returning a handle to the task that drives the connection
client.connect().await.unwrap().unwrap();
client.wait_for_connect().await.unwrap();
let client = RedisClient::default();
client.init().await.unwrap();
let asd: Str = client.ping().await.unwrap();

View file

@ -2,7 +2,7 @@
pub mod qs_parser;
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket};
use crate::ingest_protocol::NMJsonPacket;
use crate::web_server::app_error::AppError;
use ntex::http::{HttpMessage, StatusCode};
@ -12,7 +12,6 @@ use ntex::{http, web};
use qs_parser::QSParserError;
use thiserror::Error;
use super::NMAppState;
#[derive(Error, Debug)]
@ -50,7 +49,8 @@ pub async fn device_handler<'a>(
Err(error) => json_error = Some(error),
},
"application/x-www-form-urlencoded" => {
match serde_qs::from_bytes::<NMDeviceDataPacket>(body.as_ref()) {
let body = std::str::from_utf8(body.as_ref())?;
match qs_parser::parse_nm_qs_format(body).await {
DarkCat09 marked this conversation as resolved Outdated
Outdated
Review

Может быть всё-таки std::str::from_utf8 используешь? Я не хочу работать с не utf-8 данными, так что заменять невалидные вещи на � не лучшее решение.

Может быть всё-таки `std::str::from_utf8` используешь? Я не хочу работать с не utf-8 данными, так что заменять невалидные вещи на � не лучшее решение.
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),
@ -62,7 +62,7 @@ pub async fn device_handler<'a>(
_ => {}
}
} else if request.method() == http::Method::GET {
match serde_qs::from_str::<NMDeviceDataPacket>(request.query_string()) {
match qs_parser::parse_nm_qs_format(request.query_string()).await {
Ok(qs_body) => {
real_body = Some(NMJsonPacket {
devices: Vec::from([qs_body]),

View file

@ -45,7 +45,7 @@ impl From<serde_qs::Error> for QSParserError {
/// [SensorValue].
///
/// Формат: `<SENSOR_MAC>=<SENSOR_VALUE>`.
/// Других данных на подобии названия и времени нет.
/// Других данных наподобие названия и времени нет.
pub fn qs_rest_to_values(
parsed: HashMap<String, String>,
) -> Result<HashSet<SensorValue>, QSParserError> {
@ -96,6 +96,8 @@ pub async fn parse_nm_qs_format(input: &str) -> Result<NMDeviceDataPacket, QSPar
return Err(QSParserError::NoMAC);
};
parsed.remove("ID");
let device_data = NMDeviceDataPacket {
mac: device_mac,
name: parsed.remove("name").map(|v| v.to_owned()),