config and tokio

This commit is contained in:
Piyush मिश्रः 2021-05-14 10:47:39 +05:30
parent 23b881c03b
commit 7569e222fc
7 changed files with 104 additions and 48 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/target /target
/.env /config.json

40
Cargo.lock generated
View File

@ -19,7 +19,7 @@ dependencies = [
"parking_lot", "parking_lot",
"pin-project 0.4.27", "pin-project 0.4.27",
"smallvec", "smallvec",
"tokio", "tokio 0.2.25",
"tokio-util 0.3.1", "tokio-util 0.3.1",
"trust-dns-proto", "trust-dns-proto",
"trust-dns-resolver", "trust-dns-resolver",
@ -48,7 +48,7 @@ dependencies = [
"futures-sink", "futures-sink",
"log", "log",
"pin-project 0.4.27", "pin-project 0.4.27",
"tokio", "tokio 0.2.25",
"tokio-util 0.3.1", "tokio-util 0.3.1",
] ]
@ -195,7 +195,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"smallvec", "smallvec",
"tokio", "tokio 0.2.25",
] ]
[[package]] [[package]]
@ -715,12 +715,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]] [[package]]
name = "dtoa" name = "dtoa"
version = "0.4.8" version = "0.4.8"
@ -1016,7 +1010,7 @@ dependencies = [
"http", "http",
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio 0.2.25",
"tokio-util 0.3.1", "tokio-util 0.3.1",
"tracing", "tracing",
"tracing-futures", "tracing-futures",
@ -1210,15 +1204,14 @@ dependencies = [
"actix-web-actors", "actix-web-actors",
"base64", "base64",
"clap", "clap",
"dotenv",
"env_logger", "env_logger",
"futures",
"lazy_static", "lazy_static",
"openssl", "openssl",
"rand 0.8.3", "rand 0.8.3",
"serde", "serde",
"serde_json", "serde_json",
"sha1", "sha1",
"tokio 1.5.0",
] ]
[[package]] [[package]]
@ -1657,7 +1650,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project-lite 0.1.11", "pin-project-lite 0.1.11",
"sha1", "sha1",
"tokio", "tokio 0.2.25",
"tokio-util 0.2.0", "tokio-util 0.2.0",
"url", "url",
] ]
@ -2058,6 +2051,17 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "tokio"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
dependencies = [
"autocfg",
"num_cpus",
"pin-project-lite 0.2.4",
]
[[package]] [[package]]
name = "tokio-openssl" name = "tokio-openssl"
version = "0.4.0" version = "0.4.0"
@ -2065,7 +2069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594"
dependencies = [ dependencies = [
"openssl", "openssl",
"tokio", "tokio 0.2.25",
] ]
[[package]] [[package]]
@ -2079,7 +2083,7 @@ dependencies = [
"futures-sink", "futures-sink",
"log", "log",
"pin-project-lite 0.1.11", "pin-project-lite 0.1.11",
"tokio", "tokio 0.2.25",
] ]
[[package]] [[package]]
@ -2094,7 +2098,7 @@ dependencies = [
"futures-sink", "futures-sink",
"log", "log",
"pin-project-lite 0.1.11", "pin-project-lite 0.1.11",
"tokio", "tokio 0.2.25",
] ]
[[package]] [[package]]
@ -2144,7 +2148,7 @@ dependencies = [
"rand 0.7.3", "rand 0.7.3",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio 0.2.25",
"url", "url",
] ]
@ -2164,7 +2168,7 @@ dependencies = [
"resolv-conf", "resolv-conf",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio 0.2.25",
"trust-dns-proto", "trust-dns-proto",
] ]

View File

@ -5,8 +5,11 @@ description = "Chat app for lupt(लुप्त) users!"
authors = ["Piyush Raj <piyush.raj.kit@gmail.com>"] authors = ["Piyush Raj <piyush.raj.kit@gmail.com>"]
edition = "2018" edition = "2018"
license = "GPL 3.0" license = "GPL 3.0"
license-file = "LICENSE"
readme = "README.md" readme = "README.md"
repository = "https://github.com/PiyushXCoder/lupt" repository = "https://github.com/PiyushXCoder/lupt"
homepage = "luptchat.in"
categories = ["chatting-app"]
keywords = ["chat","Chatting","Talk","Stranger"] keywords = ["chat","Chatting","Talk","Stranger"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -21,14 +24,13 @@ actix-ratelimit = "0.3.1"
env_logger = "0.8.3" env_logger = "0.8.3"
openssl = "0.10.28" openssl = "0.10.28"
dotenv = "0.15.0"
clap = "2.33.3" clap = "2.33.3"
lazy_static = "1.4.0" lazy_static = "1.4.0"
serde = "1.0.123" serde = "1.0.123"
serde_json = "1.0.62" serde_json = "1.0.62"
rand = "0.8.3" rand = "0.8.3"
futures = "0.3.12" tokio = { version = "1.5.0", features = ['rt', 'rt-multi-thread']}
sha1 = "0.6.0" sha1 = "0.6.0"
base64 = "0.13.0" base64 = "0.13.0"

View File

@ -16,23 +16,25 @@
*/ */
use clap::{App, Arg}; use clap::{App, Arg};
use serde::{Deserialize, Serialize};
pub struct Config { pub struct Config {
pub static_path: String, pub static_path: String,
pub bind_address: String pub bind_address: String,
pub config: ConfigFile
}
#[derive(Serialize, Deserialize)]
pub struct ConfigFile {
pub salt: String,
pub tenor_key: String,
pub ssl_cert: String,
pub ssl_key: String,
pub logger_pattern: String
} }
impl Config { impl Config {
pub fn new() -> Self { pub fn new() -> Self {
let bind_address = std::env::var("URL");
let static_path = std::env::var("STATIC_PATH");
if bind_address.is_ok() && static_path.is_ok() {
return Config {
static_path: static_path.unwrap(),
bind_address: bind_address.unwrap()
};
}
let matches = App::new("Lupt (लुप्त)") let matches = App::new("Lupt (लुप्त)")
.version(env!("CARGO_PKG_VERSION")) .version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS")) .author(env!("CARGO_PKG_AUTHORS"))
@ -51,11 +53,34 @@ impl Config {
.help("Address to bind for server") .help("Address to bind for server")
.required(true) .required(true)
.takes_value(true)) .takes_value(true))
.arg(Arg::with_name("config")
.short("c")
.long("config")
.value_name("FILE")
.help("Path to config file")
.required(true)
.takes_value(true))
.get_matches(); .get_matches();
let conf = matches.value_of("config").unwrap().to_owned();
let conf = std::fs::read_to_string(conf).expect("Failed to read config");
let config = serde_json::from_str::<ConfigFile>(&conf).expect(r"
Config File is corrupt.
Config file must have following fields
- salt: Salt for hashing
- tenor_key: Key of tenor gif api
- ssl_cert: Path to certificate of ssl
- ssl_key: Path to private key of ssl
- logger_pattern: Pattern to make log according to Actix Logger
");
Config { Config {
static_path: matches.value_of("static_path").unwrap().to_owned(), static_path: matches.value_of("static_path").unwrap().to_owned(),
bind_address: matches.value_of("bind_address").unwrap().to_owned() bind_address: matches.value_of("bind_address").unwrap().to_owned(),
config
} }
} }
} }

View File

@ -34,8 +34,9 @@ use actix_web::{
use actix_files as fs; use actix_files as fs;
use actix_web_actors::ws; use actix_web_actors::ws;
use actix_ratelimit::{RateLimiter, MemoryStore, MemoryStoreActor}; use actix_ratelimit::{RateLimiter, MemoryStore, MemoryStoreActor};
use openssl::ssl::{SslConnector, SslMethod}; use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslConnector, SslFiletype, SslMethod};
use ws_sansad::WsSansad; use ws_sansad::WsSansad;
use std::sync::RwLock;
mod config; mod config;
mod errors; mod errors;
@ -45,19 +46,24 @@ mod chat_pinnd;
mod validator; mod validator;
lazy_static! { lazy_static! {
pub static ref SALT: String = std::env::var("SALT").unwrap(); pub static ref SALT: RwLock<String> = RwLock::new(String::new());
pub static ref TENOR_API_KEY: String = std::env::var("TENOR_API_KEY").unwrap(); pub static ref TENOR_API_KEY: RwLock<String> = RwLock::new(String::new());
} }
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok();
std::env::set_var("RUST_LOG", "actix_web=info"); std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init(); env_logger::init();
let store = MemoryStore::new(); let store = MemoryStore::new();
let config = config::Config::new(); let config = config::Config::new();
*SALT.write().unwrap() = config.config.salt;
*TENOR_API_KEY.write().unwrap() = config.config.tenor_key;
let ssl_builder = generate_ssl_builder(config.config.ssl_key, config.config.ssl_cert);
let logger_pattern = config.config.logger_pattern;
let static_path = config.static_path; let static_path = config.static_path;
HttpServer::new(move || { let server = HttpServer::new(move || {
App::new() App::new()
.wrap( .wrap(
RateLimiter::new( RateLimiter::new(
@ -65,14 +71,17 @@ async fn main() -> std::io::Result<()> {
.with_interval(std::time::Duration::from_secs(60)) .with_interval(std::time::Duration::from_secs(60))
.with_max_requests(200) .with_max_requests(200)
) )
.wrap(Logger::new("%t [%{x-forwarded-for}i] %s %{User-Agent}i %r")) .wrap(Logger::new(&logger_pattern))
.service(web::resource("/ws/").route(web::get().to(ws_index))) .service(web::resource("/ws/").route(web::get().to(ws_index)))
.service(web::resource("/gif/{pos}/").route(web::get().to(gif))) .service(web::resource("/gif/{pos}/").route(web::get().to(gif)))
.service(web::resource("/gif/{pos}/{query}").route(web::get().to(gif))) .service(web::resource("/gif/{pos}/{query}").route(web::get().to(gif)))
.service(fs::Files::new("/", &static_path).index_file("index.html")) .service(fs::Files::new("/", &static_path).index_file("index.html"))
}) });
.bind(config.bind_address)?
.run() match ssl_builder {
Some(b) => server.bind_openssl(config.bind_address, b),
None => server.bind(config.bind_address)
}?.run()
.await .await
} }
@ -91,7 +100,7 @@ async fn gif(req: HttpRequest) -> Result<HttpResponse, Error> {
.finish(); .finish();
let url = format!("https://g.tenor.com/v1/search?q={}&key={}&limit=20&media_filter=tinygif&pos={}", name.replace(" ", "+"), TENOR_API_KEY.to_owned(), pos); let url = format!("https://g.tenor.com/v1/search?q={}&key={}&limit=20&media_filter=tinygif&pos={}", name.replace(" ", "+"), TENOR_API_KEY.read().unwrap(), pos);
let response = client.get(url) let response = client.get(url)
.header("User-Agent", "actix-web/3.0") .header("User-Agent", "actix-web/3.0")
.send() .send()
@ -101,3 +110,16 @@ async fn gif(req: HttpRequest) -> Result<HttpResponse, Error> {
Ok(HttpResponse::Ok().content_type("application/json").body(response)) Ok(HttpResponse::Ok().content_type("application/json").body(response))
} }
fn generate_ssl_builder(key: String, cert: String) -> Option<SslAcceptorBuilder> {
if key != "" && cert != "" {
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file(key, SslFiletype::PEM)
.unwrap();
builder.set_certificate_chain_file(cert).unwrap();
Some(builder)
} else {
None
}
}

View File

@ -58,7 +58,8 @@ impl Actor for WsSansad {
} }
fn stopping(&mut self, _: &mut Self::Context) -> Running { fn stopping(&mut self, _: &mut Self::Context) -> Running {
futures::executor::block_on(self.leave_kaksh()); // notify leaving tokio::runtime::Runtime::new().unwrap()
.block_on(self.leave_kaksh());// notify leaving
Running::Stop Running::Stop
} }
} }
@ -74,7 +75,8 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsSansad {
}, Ok(ws::Message::Pong(_)) => { }, Ok(ws::Message::Pong(_)) => {
self.hb = Instant::now(); self.hb = Instant::now();
}, Ok(ws::Message::Text(msg)) => { }, Ok(ws::Message::Text(msg)) => {
futures::executor::block_on(self.parse_text_handle(msg)); tokio::runtime::Runtime::new().unwrap()
.block_on(self.parse_text_handle(msg));
}, Ok(ws::Message::Close(msg)) => { }, Ok(ws::Message::Close(msg)) => {
ctx.close(msg); ctx.close(msg);
ctx.stop(); ctx.stop();
@ -105,7 +107,8 @@ impl WsSansad {
// heartbeat timed out // heartbeat timed out
// stop actor // stop actor
futures::executor::block_on(act.leave_kaksh()); // notify leaving tokio::runtime::Runtime::new().unwrap()
.block_on(act.leave_kaksh());
ctx.stop(); ctx.stop();
// don't try to send a ping // don't try to send a ping
return; return;

View File

@ -46,7 +46,7 @@ impl WsSansad {
} }
let mut m = sha1::Sha1::new(); let mut m = sha1::Sha1::new();
m.update(format!("{}{}",kunjika, m.update(format!("{}{}",kunjika,
crate::SALT.to_owned()).as_bytes()); crate::SALT.read().unwrap()).as_bytes());
let kunjika = base64::encode(m.digest().bytes())[..8].to_owned(); let kunjika = base64::encode(m.digest().bytes())[..8].to_owned();
// Name // Name
@ -131,7 +131,7 @@ impl WsSansad {
} }
let mut m = sha1::Sha1::new(); let mut m = sha1::Sha1::new();
m.update(format!("{}{}",kunjika, m.update(format!("{}{}",kunjika,
crate::SALT.to_owned()).as_bytes()); crate::SALT.read().unwrap()).as_bytes());
let kunjika = base64::encode(m.digest().bytes())[..8].to_owned(); let kunjika = base64::encode(m.digest().bytes())[..8].to_owned();
// Name // Name