fix: redis, /get & /post parsing #15
6 changed files with 46 additions and 38 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -113,12 +113,6 @@ version = "1.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arcstr"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
|
@ -127,9 +121,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-broadcast"
|
name = "async-broadcast"
|
||||||
version = "0.7.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "258b52a1aa741b9f09783b2d86cf0aeeb617bbf847f6933340a39644227acbdb"
|
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"event-listener",
|
"event-listener",
|
||||||
"event-listener-strategy",
|
"event-listener-strategy",
|
||||||
|
@ -434,12 +428,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie-factory"
|
name = "cookie-factory"
|
||||||
version = "0.3.3"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2"
|
checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b"
|
||||||
dependencies = [
|
|
||||||
"futures 0.3.30",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
|
@ -468,6 +459,15 @@ version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
|
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]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.20"
|
version = "0.8.20"
|
||||||
|
@ -646,30 +646,29 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fred"
|
name = "fred"
|
||||||
version = "6.3.2"
|
version = "9.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a15cc18b56395b8b15ffcdcea7fe8586e3a3ccb3d9dc3b9408800d9814efb08e"
|
checksum = "915e065b377f6e16d5c01eae96bf31eeaf81e1e300b76f938761b3c21307cad8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"arcstr",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes 1.6.0",
|
"bytes 1.6.0",
|
||||||
"bytes-utils",
|
"bytes-utils",
|
||||||
"cfg-if",
|
"crossbeam-queue",
|
||||||
"float-cmp",
|
"float-cmp",
|
||||||
"futures 0.3.30",
|
"futures 0.3.30",
|
||||||
"lazy_static",
|
|
||||||
"log",
|
"log",
|
||||||
"nom",
|
"nom",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rand",
|
"rand",
|
||||||
"redis-protocol",
|
"redis-protocol",
|
||||||
"semver",
|
"semver",
|
||||||
"sha-1",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"url",
|
"url",
|
||||||
|
"urlencoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1675,9 +1674,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.84"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
|
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
@ -1749,9 +1748,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redis-protocol"
|
name = "redis-protocol"
|
||||||
version = "4.1.0"
|
version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c31deddf734dc0a39d3112e73490e88b61a05e83e074d211f348404cee4d2c6"
|
checksum = "65deb7c9501fbb2b6f812a30d59c0253779480853545153a51d8e9e444ddc99f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.6.0",
|
"bytes 1.6.0",
|
||||||
"bytes-utils",
|
"bytes-utils",
|
||||||
|
@ -2441,6 +2440,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlencoding"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
|
@ -13,7 +13,7 @@ chrono = { version = "0.4.26", features = ["serde"] }
|
||||||
clap = { version = "4.3.8", features = ["derive", "env"] }
|
clap = { version = "4.3.8", features = ["derive", "env"] }
|
||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
dotenvy = "0.15.7"
|
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"] }
|
heapless = { version = "0.7.16", features = ["ufmt-impl"] }
|
||||||
hex = { version = "0.4.3", default-features = false, features = ["std", "alloc"] }
|
hex = { version = "0.4.3", default-features = false, features = ["std", "alloc"] }
|
||||||
hifitime = "3.8.2"
|
hifitime = "3.8.2"
|
||||||
|
|
|
@ -13,6 +13,8 @@ use crate::web_server::old_device_sensor_api::qs_parser::QSParserError;
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
use super::old_device_sensor_api::qs_parser;
|
||||||
|
|
||||||
/// Главный объект ошибки [std::error::Error] для всего Web API.
|
/// Главный объект ошибки [std::error::Error] для всего Web API.
|
||||||
///
|
///
|
||||||
/// В целом, все Result у Web сервера должны использовать этот Error.
|
/// В целом, все Result у Web сервера должны использовать этот Error.
|
||||||
|
@ -42,10 +44,13 @@ pub enum AppError {
|
||||||
min: Option<Decimal>,
|
min: Option<Decimal>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[display(fmt = "UTF8")]
|
||||||
|
Utf8Error(#[from] std::str::Utf8Error),
|
||||||
|
|
||||||
#[display(fmt = "IDK")]
|
#[display(fmt = "IDK")]
|
||||||
UnknownBody {
|
UnknownBody {
|
||||||
json_err: Option<serde_json::Error>,
|
json_err: Option<serde_json::Error>,
|
||||||
query_error: Option<serde_qs::Error>,
|
query_error: Option<qs_parser::QSParserError>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[display(fmt = "IDK")]
|
#[display(fmt = "IDK")]
|
||||||
|
@ -61,6 +66,7 @@ impl web::error::WebResponseError for AppError {
|
||||||
AppError::RequestTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
AppError::RequestTooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
||||||
AppError::ServerRedisError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
AppError::ServerRedisError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
AppError::ApiKeyInvalid { .. } => StatusCode::BAD_REQUEST,
|
AppError::ApiKeyInvalid { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
AppError::Utf8Error(_) => StatusCode::BAD_REQUEST,
|
||||||
AppError::UnknownBody { .. } => StatusCode::BAD_REQUEST,
|
AppError::UnknownBody { .. } => StatusCode::BAD_REQUEST,
|
||||||
AppError::QSError(..) => StatusCode::BAD_REQUEST,
|
AppError::QSError(..) => StatusCode::BAD_REQUEST,
|
||||||
AppError::DeviceNotFound(..) => 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::RequestTooLarge => "Request is too large",
|
||||||
AppError::ServerRedisError(_) => "Internal server error",
|
AppError::ServerRedisError(_) => "Internal server error",
|
||||||
AppError::ApiKeyInvalid { .. } => "API Key invalid",
|
AppError::ApiKeyInvalid { .. } => "API Key invalid",
|
||||||
|
AppError::Utf8Error(_) => "Invalid UTF8 sequence",
|
||||||
AppError::UnknownBody { .. } => {
|
AppError::UnknownBody { .. } => {
|
||||||
"Can't figure out where and in what encoding the main data is"
|
"Can't figure out where and in what encoding the main data is"
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,8 @@ use crate::web_server::old_device_sensor_api::device_handler;
|
||||||
use ntex::web;
|
use ntex::web;
|
||||||
|
|
||||||
pub async fn server_main() {
|
pub async fn server_main() {
|
||||||
let config = RedisConfig::default();
|
let client = RedisClient::default();
|
||||||
let perf = PerformanceConfig::default();
|
client.init().await.unwrap();
|
||||||
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 asd: Str = client.ping().await.unwrap();
|
let asd: Str = client.ping().await.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
pub mod qs_parser;
|
pub mod qs_parser;
|
||||||
|
|
||||||
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket};
|
use crate::ingest_protocol::NMJsonPacket;
|
||||||
use crate::web_server::app_error::AppError;
|
use crate::web_server::app_error::AppError;
|
||||||
|
|
||||||
use ntex::http::{HttpMessage, StatusCode};
|
use ntex::http::{HttpMessage, StatusCode};
|
||||||
|
@ -12,7 +12,6 @@ use ntex::{http, web};
|
||||||
use qs_parser::QSParserError;
|
use qs_parser::QSParserError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
||||||
use super::NMAppState;
|
use super::NMAppState;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
@ -50,7 +49,8 @@ pub async fn device_handler<'a>(
|
||||||
Err(error) => json_error = Some(error),
|
Err(error) => json_error = Some(error),
|
||||||
},
|
},
|
||||||
"application/x-www-form-urlencoded" => {
|
"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
|
|||||||
Ok(qs_body) => {
|
Ok(qs_body) => {
|
||||||
real_body = Some(NMJsonPacket {
|
real_body = Some(NMJsonPacket {
|
||||||
devices: Vec::from([qs_body]),
|
devices: Vec::from([qs_body]),
|
||||||
|
@ -62,7 +62,7 @@ pub async fn device_handler<'a>(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else if request.method() == http::Method::GET {
|
} 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) => {
|
Ok(qs_body) => {
|
||||||
real_body = Some(NMJsonPacket {
|
real_body = Some(NMJsonPacket {
|
||||||
devices: Vec::from([qs_body]),
|
devices: Vec::from([qs_body]),
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl From<serde_qs::Error> for QSParserError {
|
||||||
/// [SensorValue].
|
/// [SensorValue].
|
||||||
///
|
///
|
||||||
/// Формат: `<SENSOR_MAC>=<SENSOR_VALUE>`.
|
/// Формат: `<SENSOR_MAC>=<SENSOR_VALUE>`.
|
||||||
/// Других данных на подобии названия и времени нет.
|
/// Других данных наподобие названия и времени нет.
|
||||||
pub fn qs_rest_to_values(
|
pub fn qs_rest_to_values(
|
||||||
parsed: HashMap<String, String>,
|
parsed: HashMap<String, String>,
|
||||||
) -> Result<HashSet<SensorValue>, QSParserError> {
|
) -> Result<HashSet<SensorValue>, QSParserError> {
|
||||||
|
@ -96,6 +96,8 @@ pub async fn parse_nm_qs_format(input: &str) -> Result<NMDeviceDataPacket, QSPar
|
||||||
return Err(QSParserError::NoMAC);
|
return Err(QSParserError::NoMAC);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
parsed.remove("ID");
|
||||||
|
|
||||||
let device_data = NMDeviceDataPacket {
|
let device_data = NMDeviceDataPacket {
|
||||||
mac: device_mac,
|
mac: device_mac,
|
||||||
name: parsed.remove("name").map(|v| v.to_owned()),
|
name: parsed.remove("name").map(|v| v.to_owned()),
|
||||||
|
|
Loading…
Reference in a new issue
Может быть всё-таки
std::str::from_utf8
используешь? Я не хочу работать с не utf-8 данными, так что заменять невалидные вещи на � не лучшее решение.