parent
a4ec4878ea
commit
ebd1026903
|
@ -2,7 +2,9 @@
|
||||||
#![allow (clippy::redundant_closure)]
|
#![allow (clippy::redundant_closure)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::{
|
||||||
|
HashMap,
|
||||||
|
},
|
||||||
convert::{TryFrom},
|
convert::{TryFrom},
|
||||||
net::IpAddr,
|
net::IpAddr,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -23,6 +25,7 @@ use crate::{
|
||||||
|
|
||||||
pub mod machine_editable {
|
pub mod machine_editable {
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,22 +33,25 @@ pub mod machine_editable {
|
||||||
|
|
||||||
use super::file::Server;
|
use super::file::Server;
|
||||||
|
|
||||||
#[derive (Default, Deserialize, Serialize)]
|
#[derive (Deserialize, Serialize)]
|
||||||
pub struct Config {
|
pub struct ConfigFile {
|
||||||
pub servers: Vec <Server>,
|
pub servers: Vec <Server>,
|
||||||
pub debug_toggle: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
#[derive (Default)]
|
||||||
|
pub struct Config {
|
||||||
|
pub servers: BTreeMap <String, Server>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigFile {
|
||||||
pub fn from_file (path: &Path) -> Result <Self, crate::ConfigError>
|
pub fn from_file (path: &Path) -> Result <Self, crate::ConfigError>
|
||||||
{
|
{
|
||||||
let config_s = std::fs::read_to_string (path)?;
|
let config_s = std::fs::read_to_string (path)?;
|
||||||
let new_config: Config = toml::from_str (&config_s)?;
|
Ok (toml::from_str (&config_s)?)
|
||||||
|
|
||||||
Ok (new_config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save (&self, path: &Path) -> Result <(), crate::ConfigError> {
|
pub async fn save (&self, path: &Path) -> Result <(), crate::ConfigError>
|
||||||
|
{
|
||||||
let s = toml::to_string (self)?;
|
let s = toml::to_string (self)?;
|
||||||
// This is way easier in C++ but also not safe
|
// This is way easier in C++ but also not safe
|
||||||
let mut temp_path = path.file_name ().unwrap ().to_os_string ();
|
let mut temp_path = path.file_name ().unwrap ().to_os_string ();
|
||||||
|
@ -56,6 +62,33 @@ pub mod machine_editable {
|
||||||
Ok (())
|
Ok (())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn from_file (path: &Path) -> Result <Self, crate::ConfigError>
|
||||||
|
{
|
||||||
|
let c = ConfigFile::from_file (path)?;
|
||||||
|
|
||||||
|
let servers = c.servers.into_iter ()
|
||||||
|
.map (|s| (s.name.clone (), s))
|
||||||
|
.collect ();
|
||||||
|
|
||||||
|
Ok (Self {
|
||||||
|
servers,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn save (&self, path: &Path) -> Result <(), crate::ConfigError>
|
||||||
|
{
|
||||||
|
let servers = self.servers.values ()
|
||||||
|
.cloned ().into_iter ().collect ();
|
||||||
|
|
||||||
|
let c = ConfigFile {
|
||||||
|
servers,
|
||||||
|
};
|
||||||
|
c.save (path).await?;
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Config fields as they are loaded from the config file
|
/// Config fields as they are loaded from the config file
|
||||||
|
@ -69,7 +102,7 @@ pub mod file {
|
||||||
Valid30Days,
|
Valid30Days,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive (Deserialize, Serialize)]
|
#[derive (Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
/// This is duplicated in the hashmap, but it's not a problem
|
/// This is duplicated in the hashmap, but it's not a problem
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -114,7 +114,7 @@ fn get_user_name (req: &http::request::Parts)
|
||||||
async fn handle_http_request (
|
async fn handle_http_request (
|
||||||
req: http::request::Parts,
|
req: http::request::Parts,
|
||||||
uri: String,
|
uri: String,
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
server_name: &str
|
server_name: &str
|
||||||
)
|
)
|
||||||
-> Result <Response <Body>, RequestError>
|
-> Result <Response <Body>, RequestError>
|
||||||
|
@ -300,7 +300,7 @@ struct AuditEntryPretty {
|
||||||
data_pretty: String,
|
data_pretty: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_server_list_internal (state: &Arc <Relay>)
|
async fn handle_server_list_internal (state: &Relay)
|
||||||
-> ServerListPage <'static>
|
-> ServerListPage <'static>
|
||||||
{
|
{
|
||||||
use LastSeen::*;
|
use LastSeen::*;
|
||||||
|
@ -357,7 +357,7 @@ async fn handle_server_list_internal (state: &Arc <Relay>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_unregistered_servers_internal (state: &Arc <Relay>)
|
async fn handle_unregistered_servers_internal (state: &Relay)
|
||||||
-> UnregisteredServerListPage
|
-> UnregisteredServerListPage
|
||||||
{
|
{
|
||||||
use LastSeen::*;
|
use LastSeen::*;
|
||||||
|
@ -366,6 +366,13 @@ async fn handle_unregistered_servers_internal (state: &Arc <Relay>)
|
||||||
|
|
||||||
let mut server_list = state.unregistered_servers.to_vec ().await;
|
let mut server_list = state.unregistered_servers.to_vec ().await;
|
||||||
|
|
||||||
|
{
|
||||||
|
let me_config = state.me_config.read ().await;
|
||||||
|
server_list = server_list.into_iter ()
|
||||||
|
.filter (|s| ! me_config.servers.contains_key (&s.name))
|
||||||
|
.collect ();
|
||||||
|
}
|
||||||
|
|
||||||
server_list.sort_by_key (|s| {
|
server_list.sort_by_key (|s| {
|
||||||
(s.name.clone (), s.tripcode.as_bytes ().clone (), now - s.seen)
|
(s.name.clone (), s.tripcode.as_bytes ().clone (), now - s.seen)
|
||||||
});
|
});
|
||||||
|
@ -395,7 +402,7 @@ async fn handle_unregistered_servers_internal (state: &Arc <Relay>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_audit_log_internal (state: &Arc <Relay>)
|
async fn handle_audit_log_internal (state: &Relay)
|
||||||
-> AuditLogPage
|
-> AuditLogPage
|
||||||
{
|
{
|
||||||
let utc_now = Utc::now ();
|
let utc_now = Utc::now ();
|
||||||
|
@ -413,7 +420,7 @@ async fn handle_audit_log_internal (state: &Arc <Relay>)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_server_list (
|
async fn handle_server_list (
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
handlebars: Arc <Handlebars <'static>>
|
handlebars: Arc <Handlebars <'static>>
|
||||||
) -> Result <Response <Body>, RequestError>
|
) -> Result <Response <Body>, RequestError>
|
||||||
{
|
{
|
||||||
|
@ -424,7 +431,7 @@ async fn handle_server_list (
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_unregistered_servers (
|
async fn handle_unregistered_servers (
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
handlebars: Arc <Handlebars <'static>>
|
handlebars: Arc <Handlebars <'static>>
|
||||||
) -> Result <Response <Body>, RequestError>
|
) -> Result <Response <Body>, RequestError>
|
||||||
{
|
{
|
||||||
|
@ -435,11 +442,11 @@ async fn handle_unregistered_servers (
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_audit_log (
|
async fn handle_audit_log (
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
handlebars: Arc <Handlebars <'static>>
|
handlebars: Arc <Handlebars <'static>>
|
||||||
) -> Result <Response <Body>, RequestError>
|
) -> Result <Response <Body>, RequestError>
|
||||||
{
|
{
|
||||||
let page = handle_audit_log_internal (&state).await;
|
let page = handle_audit_log_internal (state).await;
|
||||||
|
|
||||||
let s = handlebars.render ("audit_log", &page)?;
|
let s = handlebars.render ("audit_log", &page)?;
|
||||||
Ok (ok_reply (s)?)
|
Ok (ok_reply (s)?)
|
||||||
|
@ -515,7 +522,7 @@ async fn handle_endless_source (gib: usize, throttle: Option <usize>)
|
||||||
.body (Body::wrap_stream (ReceiverStream::new (rx)))
|
.body (Body::wrap_stream (ReceiverStream::new (rx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_gen_scraper_key (_state: Arc <Relay>)
|
async fn handle_gen_scraper_key (_state: &Relay)
|
||||||
-> Result <Response <Body>, http::Error>
|
-> Result <Response <Body>, http::Error>
|
||||||
{
|
{
|
||||||
let key = ptth_core::gen_key ();
|
let key = ptth_core::gen_key ();
|
||||||
|
@ -528,24 +535,25 @@ async fn handle_gen_scraper_key (_state: Arc <Relay>)
|
||||||
.body (Body::from (body))
|
.body (Body::from (body))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_register_server (req: Request <Body>, state: Arc <Relay>)
|
async fn handle_register_server (req: Request <Body>, state: &Relay)
|
||||||
-> Result <(), anyhow::Error>
|
-> Result <(), anyhow::Error>
|
||||||
{
|
{
|
||||||
let (parts, body) = req.into_parts ();
|
let (parts, body) = req.into_parts ();
|
||||||
let user = get_user_name (&parts);
|
let user = get_user_name (&parts);
|
||||||
|
|
||||||
let form_data = read_body_limited (body, 1_024).await?;
|
let form_data = read_body_limited (body, 1_024).await?;
|
||||||
let reg: relay_state::Registration = serde_urlencoded::from_bytes (&form_data)?;
|
let server: crate::config::file::Server = serde_urlencoded::from_bytes (&form_data)?;
|
||||||
|
|
||||||
state.audit_log.push (AuditEvent::new (AuditData::RegisterServer {
|
state.audit_log.push (AuditEvent::new (AuditData::RegisterServer {
|
||||||
user,
|
user,
|
||||||
reg: reg.clone (),
|
server: server.clone (),
|
||||||
})).await;
|
})).await;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut me_config = state.me_config.write ().await;
|
let mut me_config = state.me_config.write ().await;
|
||||||
|
|
||||||
//me_config.servers.
|
me_config.servers.insert (server.name.clone (), server);
|
||||||
|
me_config.save (Path::new ("data/ptth_relay_me_config.toml")).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok (())
|
Ok (())
|
||||||
|
@ -577,6 +585,8 @@ async fn handle_all (
|
||||||
{
|
{
|
||||||
use routing::Route::*;
|
use routing::Route::*;
|
||||||
|
|
||||||
|
let state = &*state;
|
||||||
|
|
||||||
// The path is cloned here, so it's okay to consume the request
|
// The path is cloned here, so it's okay to consume the request
|
||||||
// later.
|
// later.
|
||||||
let path = req.uri ().path ().to_string ();
|
let path = req.uri ().path ().to_string ();
|
||||||
|
@ -592,41 +602,18 @@ async fn handle_all (
|
||||||
} => {
|
} => {
|
||||||
let (parts, _) = req.into_parts ();
|
let (parts, _) = req.into_parts ();
|
||||||
|
|
||||||
handle_http_request (parts, path.to_string (), state, listen_code).await?
|
handle_http_request (parts, path.to_string (), &state, listen_code).await?
|
||||||
},
|
},
|
||||||
ClientServerList => handle_server_list (state, handlebars).await?,
|
ClientServerList => handle_server_list (state, handlebars).await?,
|
||||||
ClientUnregisteredServers => handle_unregistered_servers (state, handlebars).await?,
|
ClientUnregisteredServers => handle_unregistered_servers (state, handlebars).await?,
|
||||||
Debug => {
|
Debug => {
|
||||||
#[derive (Serialize)]
|
let s = handlebars.render ("debug", &())?;
|
||||||
struct DebugPage {
|
|
||||||
persistent_toggle: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
let page;
|
|
||||||
|
|
||||||
{
|
|
||||||
let guard = state.me_config.read ().await;
|
|
||||||
page = DebugPage {
|
|
||||||
persistent_toggle: guard.debug_toggle,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let s = handlebars.render ("debug", &page)?;
|
|
||||||
ok_reply (s)?
|
ok_reply (s)?
|
||||||
},
|
},
|
||||||
DebugEndlessSink => handle_endless_sink (req).await?,
|
DebugEndlessSink => handle_endless_sink (req).await?,
|
||||||
DebugEndlessSource (throttle) => handle_endless_source (1, throttle).await?,
|
DebugEndlessSource (throttle) => handle_endless_source (1, throttle).await?,
|
||||||
DebugGenKey => handle_gen_scraper_key (state).await?,
|
DebugGenKey => handle_gen_scraper_key (state).await?,
|
||||||
DebugMysteriousError => return Err (RequestError::Mysterious),
|
DebugMysteriousError => return Err (RequestError::Mysterious),
|
||||||
DebugToggle => {
|
|
||||||
trace! ("Toggling debug toggle");
|
|
||||||
{
|
|
||||||
let mut guard = state.me_config.write ().await;
|
|
||||||
guard.debug_toggle = ! guard.debug_toggle;
|
|
||||||
guard.save (Path::new ("data/ptth_relay_me_config.toml")).await.unwrap ();
|
|
||||||
}
|
|
||||||
error_reply (StatusCode::OK, "Toggled.")?
|
|
||||||
},
|
|
||||||
ErrorBadUriFormat => error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?,
|
ErrorBadUriFormat => error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?,
|
||||||
ErrorCantPost => {
|
ErrorCantPost => {
|
||||||
error! ("Can't POST {}", path);
|
error! ("Can't POST {}", path);
|
||||||
|
@ -637,7 +624,7 @@ async fn handle_all (
|
||||||
RegisterServer => {
|
RegisterServer => {
|
||||||
match handle_register_server (req, state).await {
|
match handle_register_server (req, state).await {
|
||||||
Ok (_) => Response::builder ()
|
Ok (_) => Response::builder ()
|
||||||
.status (StatusCode::TEMPORARY_REDIRECT)
|
.status (StatusCode::SEE_OTHER)
|
||||||
.header ("location", "unregistered_servers")
|
.header ("location", "unregistered_servers")
|
||||||
.body (Body::from ("Success. Redirecting..."))?,
|
.body (Body::from ("Success. Redirecting..."))?,
|
||||||
Err (e) => error_reply (StatusCode::BAD_REQUEST, &format! ("{:?}", e))?,
|
Err (e) => error_reply (StatusCode::BAD_REQUEST, &format! ("{:?}", e))?,
|
||||||
|
@ -671,6 +658,41 @@ async fn handle_all (
|
||||||
Ok (response)
|
Ok (response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn check_server_api_key (state: &Relay, name: &str, req: &http::request::Parts)
|
||||||
|
-> Result <(), anyhow::Error>
|
||||||
|
{
|
||||||
|
let api_key = req.headers.get ("X-ApiKey");
|
||||||
|
|
||||||
|
let api_key = match api_key {
|
||||||
|
None => bail! ("Can't run server without an API key"),
|
||||||
|
Some (x) => x,
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual_tripcode = blake3::hash (api_key.as_bytes ());
|
||||||
|
|
||||||
|
let expected_tripcode = {
|
||||||
|
let config = state.config.read ().await;
|
||||||
|
|
||||||
|
match config.servers.get (name) {
|
||||||
|
None => {
|
||||||
|
state.unregistered_servers.push (crate::RejectedServer {
|
||||||
|
name: name.to_string (),
|
||||||
|
tripcode: actual_tripcode,
|
||||||
|
seen: Utc::now (),
|
||||||
|
}).await;
|
||||||
|
bail! ("Denied API request for non-existent server name {}", name);
|
||||||
|
},
|
||||||
|
Some (x) => *(*x).tripcode,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if expected_tripcode != actual_tripcode {
|
||||||
|
bail! ("Denied API request for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok (())
|
||||||
|
}
|
||||||
|
|
||||||
fn load_templates (asset_root: &Path)
|
fn load_templates (asset_root: &Path)
|
||||||
-> Result <Handlebars <'static>, RelayError>
|
-> Result <Handlebars <'static>, RelayError>
|
||||||
{
|
{
|
||||||
|
@ -761,6 +783,7 @@ pub async fn run_relay (
|
||||||
|
|
||||||
async {
|
async {
|
||||||
Ok::<_, Infallible> (handle_all (req, state, handlebars).await.unwrap_or_else (|e| {
|
Ok::<_, Infallible> (handle_all (req, state, handlebars).await.unwrap_or_else (|e| {
|
||||||
|
use RequestError::*;
|
||||||
error! ("{}", e);
|
error! ("{}", e);
|
||||||
|
|
||||||
let status_code = match &e {
|
let status_code = match &e {
|
||||||
|
|
|
@ -7,7 +7,6 @@ use std::{
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use serde::Deserialize;
|
|
||||||
use tokio::sync::{
|
use tokio::sync::{
|
||||||
Mutex,
|
Mutex,
|
||||||
RwLock,
|
RwLock,
|
||||||
|
@ -119,7 +118,7 @@ pub struct AuditEvent {
|
||||||
pub enum AuditData {
|
pub enum AuditData {
|
||||||
RegisterServer {
|
RegisterServer {
|
||||||
user: Option <String>,
|
user: Option <String>,
|
||||||
reg: Registration,
|
server: crate::config::file::Server,
|
||||||
},
|
},
|
||||||
RelayStart,
|
RelayStart,
|
||||||
WebClientGet {
|
WebClientGet {
|
||||||
|
@ -130,12 +129,6 @@ pub enum AuditData {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Clone, Debug, Deserialize)]
|
|
||||||
pub struct Registration {
|
|
||||||
name: String,
|
|
||||||
tripcode: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuditEvent {
|
impl AuditEvent {
|
||||||
pub fn new (data: AuditData) -> Self {
|
pub fn new (data: AuditData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -15,7 +15,6 @@ pub enum Route <'a> {
|
||||||
DebugEndlessSource (Option <usize>),
|
DebugEndlessSource (Option <usize>),
|
||||||
DebugGenKey,
|
DebugGenKey,
|
||||||
DebugMysteriousError,
|
DebugMysteriousError,
|
||||||
DebugToggle,
|
|
||||||
ErrorBadUriFormat,
|
ErrorBadUriFormat,
|
||||||
ErrorCantPost,
|
ErrorCantPost,
|
||||||
ErrorMethodNotAllowed,
|
ErrorMethodNotAllowed,
|
||||||
|
@ -43,9 +42,6 @@ pub fn route_url <'a> (method: &Method, path: &'a str) -> Route <'a> {
|
||||||
else if path == "/frontend/debug/endless_sink" {
|
else if path == "/frontend/debug/endless_sink" {
|
||||||
Route::DebugEndlessSink
|
Route::DebugEndlessSink
|
||||||
}
|
}
|
||||||
else if path == "/frontend/debug/toggle" {
|
|
||||||
Route::DebugToggle
|
|
||||||
}
|
|
||||||
else if path == "/frontend/register" {
|
else if path == "/frontend/register" {
|
||||||
Route::RegisterServer
|
Route::RegisterServer
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
@ -65,7 +64,7 @@ pub struct ServerList {
|
||||||
pub servers: Vec <Server>,
|
pub servers: Vec <Server>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn v1_server_list (state: &Arc <Relay>)
|
pub async fn v1_server_list (state: &Relay)
|
||||||
-> ServerList
|
-> ServerList
|
||||||
{
|
{
|
||||||
// name --> display_name
|
// name --> display_name
|
||||||
|
@ -112,7 +111,7 @@ pub async fn v1_server_list (state: &Arc <Relay>)
|
||||||
#[instrument (level = "trace", skip (req, state))]
|
#[instrument (level = "trace", skip (req, state))]
|
||||||
async fn api_v1 (
|
async fn api_v1 (
|
||||||
req: Request <Body>,
|
req: Request <Body>,
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
path_rest: &str
|
path_rest: &str
|
||||||
)
|
)
|
||||||
-> Result <Response <Body>, RequestError>
|
-> Result <Response <Body>, RequestError>
|
||||||
|
@ -170,7 +169,7 @@ async fn api_v1 (
|
||||||
// This is ugly. I don't like having scraper_api know about the
|
// This is ugly. I don't like having scraper_api know about the
|
||||||
// crate root.
|
// crate root.
|
||||||
|
|
||||||
Ok (crate::handle_http_request (parts, path, state, &listen_code).await?)
|
Ok (crate::handle_http_request (parts, path, &state, &listen_code).await?)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok (error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?)
|
Ok (error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?)
|
||||||
|
@ -184,7 +183,7 @@ async fn api_v1 (
|
||||||
#[instrument (level = "trace", skip (req, state))]
|
#[instrument (level = "trace", skip (req, state))]
|
||||||
pub async fn handle (
|
pub async fn handle (
|
||||||
req: Request <Body>,
|
req: Request <Body>,
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
path_rest: &str
|
path_rest: &str
|
||||||
)
|
)
|
||||||
-> Result <Response <Body>, RequestError>
|
-> Result <Response <Body>, RequestError>
|
||||||
|
@ -298,9 +297,7 @@ mod tests {
|
||||||
|
|
||||||
let relay_state = builder.build ().expect ("Can't create relay state");
|
let relay_state = builder.build ().expect ("Can't create relay state");
|
||||||
|
|
||||||
let relay_state = Arc::new (relay_state);
|
let actual = super::handle (input, &relay_state, self.path_rest).await;
|
||||||
|
|
||||||
let actual = super::handle (input, relay_state, self.path_rest).await;
|
|
||||||
let actual = actual.expect ("Relay didn't respond");
|
let actual = actual.expect ("Relay didn't respond");
|
||||||
let (actual_head, actual_body) = actual.into_parts ();
|
let (actual_head, actual_body) = actual.into_parts ();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::{
|
use std::{
|
||||||
sync::Arc,
|
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ use super::{
|
||||||
// Step 1
|
// Step 1
|
||||||
|
|
||||||
pub async fn handle_listen (
|
pub async fn handle_listen (
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
watcher_code: String,
|
watcher_code: String,
|
||||||
api_key: &[u8],
|
api_key: &[u8],
|
||||||
)
|
)
|
||||||
|
@ -140,7 +139,7 @@ pub async fn handle_listen (
|
||||||
|
|
||||||
pub async fn handle_response (
|
pub async fn handle_response (
|
||||||
req: Request <Body>,
|
req: Request <Body>,
|
||||||
state: Arc <Relay>,
|
state: &Relay,
|
||||||
req_id: String,
|
req_id: String,
|
||||||
)
|
)
|
||||||
-> Result <Response <Body>, HandleHttpResponseError>
|
-> Result <Response <Body>, HandleHttpResponseError>
|
||||||
|
|
|
@ -29,7 +29,6 @@ AIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA" rel="icon" type="image/x-icon" />
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
.padded {
|
.padded {
|
||||||
display: block;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
.submit {
|
.submit {
|
||||||
|
@ -62,13 +61,11 @@ AIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA" rel="icon" type="image/x-icon" />
|
||||||
<td><span class="padded">{{this.name}}</span></td>
|
<td><span class="padded">{{this.name}}</span></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="padded">{{this.tripcode}}</span>
|
<span class="padded">{{this.tripcode}}</span>
|
||||||
<!--
|
|
||||||
<form action="register" method="post">
|
<form action="register" method="post">
|
||||||
<input type="hidden" name="name" value="{{this.name}}">
|
<input type="hidden" name="name" value="{{this.name}}">
|
||||||
<input type="hidden" name="tripcode" value="{{this.tripcode}}">
|
<input type="hidden" name="tripcode" value="{{this.tripcode}}">
|
||||||
<input class="submit" type="submit" value="Register">
|
<input class="submit" type="submit" value="Register">
|
||||||
</form>
|
</form>
|
||||||
-->
|
|
||||||
</td>
|
</td>
|
||||||
<td><span class="padded">{{this.last_seen}}</span></td>
|
<td><span class="padded">{{this.last_seen}}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in New Issue