1 extern crate actix_web
;
4 extern crate percent_encoding
;
6 use listenfd
::ListenFd
;
8 use actix_web
::{web
, middleware
, App
, HttpServer
, HttpResponse
, web
::Query
};
11 use std
::io
::prelude
::*;
12 use ron
::de
::from_reader
;
13 use serde
::Deserialize
;
14 use std
::{fs
::File
, env
::args
};
16 use itertools
::Itertools
;
22 #[template(path = "main.html")]
23 struct MainTemplate
<'a
> {
27 #[derive(Deserialize)]
32 fn main_page(query
: Query
<Request
>, key
: &str) -> HttpResponse
{
36 match crypto
::decrypt(key
, b
) {
38 Err(_e
) => String
::from(consts
::DEFAULT_MESSAGE
) // TODO: log error.
40 None
=> String
::from(consts
::DEFAULT_MESSAGE
)
43 let hello
= MainTemplate
{ sentence
: &m
};
45 let s
= hello
.render().unwrap();
46 HttpResponse
::Ok().content_type("text/html").body(s
)
49 #[derive(Debug, Deserialize)]
54 fn get_exe_name() -> String
{
55 let first_arg
= std
::env
::args().next().unwrap();
56 let sep
: &[_
] = &['
\\'
, '
/'
];
57 first_arg
[first_arg
.rfind(sep
).unwrap()+1..].to_string()
60 fn read_key() -> String
{
61 let mut key
= String
::new();
62 File
::open(consts
::FILE_KEY
)
63 .unwrap_or_else(|_
| panic!("Failed to open key file: {}", consts
::FILE_KEY
))
64 .read_to_string(&mut key
)
65 .unwrap_or_else(|_
| panic!("Failed to read key file: {}", consts
::FILE_KEY
));
68 percent_encoding
::percent_decode(key
.replace('
\n'
, "").as_bytes())
70 .unwrap_or_else(|_
| panic!("Failed to decode key file: {}", consts
::FILE_KEY
))
75 async
fn main() -> std
::io
::Result
<()> {
78 if process_args(&key
) { return Ok(()) }
80 println!("Starting RUP as web server...");
82 let config
: Config
= {
83 let f
= File
::open(consts
::FILE_CONF
).unwrap_or_else(|_
| panic!("Failed to open configuration file {}", consts
::FILE_CONF
));
84 match from_reader(f
) {
86 Err(e
) => panic!("Failed to load config: {}", e
)
90 println!("Configuration: {:?}", config
);
92 let mut listenfd
= ListenFd
::from_env();
96 let key
= key
.clone(); // Is this neccessary??
99 .wrap(middleware
::Compress
::default())
100 .wrap(middleware
::Logger
::default())
101 .service(web
::resource("/").to(move |query
| main_page(query
, &key
)))
102 .service(fs
::Files
::new("/static", "static").show_files_listing())
107 if let Some(l
) = listenfd
.take_tcp_listener(0).unwrap() {
108 server
.listen(l
).unwrap()
110 server
.bind(&format!("0.0.0.0:{}", config
.port
)).unwrap()
116 fn process_args(key
: &str) -> bool
{
119 println!(" {} [--help] [--encrypt <plain-text>|--decrypt <cipher-text>]", get_exe_name());
122 let args
: Vec
<String
> = args().collect();
124 if args
.iter().any(|arg
| arg
== "--help") {
127 } else if let Some((position_arg_encrypt
, _
)) = args
.iter().find_position(|arg
| arg
== &"--encrypt") {
128 match args
.get(position_arg_encrypt
+ 1) {
129 Some(mess_to_encrypt
) => {
130 // Encrypt to version 2 (version 1 is obsolete).
131 match crypto
::encrypt(&key
, mess_to_encrypt
, 2) {
132 Ok(encrypted_mess
) => {
133 let encrypted_mess_encoded
= percent_encoding
::utf8_percent_encode(&encrypted_mess
, percent_encoding
::NON_ALPHANUMERIC
).to_string();
134 println!("Encrypted message percent-encoded: {}", encrypted_mess_encoded
); },
136 println!("Unable to encrypt: {:?}", error
)
139 None
=> print_usage()
143 } else if let Some((position_arg_decrypt
, _
)) = args
.iter().find_position(|arg
| arg
== &"--decrypt") {
144 match args
.get(position_arg_decrypt
+ 1) {
145 Some(cipher_text
) => {
146 let cipher_text_decoded
= percent_encoding
::percent_decode(cipher_text
.as_bytes()).decode_utf8().expect("Unable to decode encoded cipher text");
147 match crypto
::decrypt(&key
, &cipher_text_decoded
) {
149 println!("Decrypted message: {}", plain_text
),
151 println!("Unable to decrypt: {:?}", error
)
154 None
=> print_usage()