Revproxy is working. Added example cgi script
This commit is contained in:
@@ -18,3 +18,6 @@ url = "*"
|
|||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
mime_guess = "2.0.3"
|
mime_guess = "2.0.3"
|
||||||
mime = "0.3.16"
|
mime = "0.3.16"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = [ "cgi-scripts/agena-cgi" ]
|
||||||
|
|||||||
9
cgi-scripts/agena-cgi/Cargo.toml
Normal file
9
cgi-scripts/agena-cgi/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "agena-cgi"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["int 80h <int@80h.dev>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
15
cgi-scripts/agena-cgi/src/main.rs
Normal file
15
cgi-scripts/agena-cgi/src/main.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
// Base url of agena proxy
|
||||||
|
const BASE: &'static str = "gemini://example.com/";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let query = match env::var("QUERY_STRING") {
|
||||||
|
Ok(q) => q,
|
||||||
|
_ => {
|
||||||
|
println!("10\tGopher url:\r\n");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
println!("30\t{}{}\r\n", BASE, query);
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ pub struct Server {
|
|||||||
pub cert: String,
|
pub cert: String,
|
||||||
pub cgi: Option<String>,
|
pub cgi: Option<String>,
|
||||||
pub usrdir: Option<bool>,
|
pub usrdir: Option<bool>,
|
||||||
pub proxy: Option<Vec<String>>,
|
pub proxy: Option<HashMap<String, String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -54,12 +54,7 @@ impl Config {
|
|||||||
};
|
};
|
||||||
let mut pmap = HashMap::new();
|
let mut pmap = HashMap::new();
|
||||||
match &srv.proxy {
|
match &srv.proxy {
|
||||||
Some(pr) => {
|
Some(pr) => pmap = pr.clone(),
|
||||||
for p in pr {
|
|
||||||
let p: Vec<&str> = p.split("=").collect();
|
|
||||||
pmap.insert(p[0].trim().to_string(), p[1].trim().to_string());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {},
|
None => {},
|
||||||
};
|
};
|
||||||
map.insert(srv.hostname.clone(), ServerCfg {
|
map.insert(srv.hostname.clone(), ServerCfg {
|
||||||
@@ -70,7 +65,7 @@ impl Config {
|
|||||||
cgi: cgi,
|
cgi: cgi,
|
||||||
usrdir: usrdir,
|
usrdir: usrdir,
|
||||||
port: self.port.clone(),
|
port: self.port.clone(),
|
||||||
proxy: pmap,
|
proxy: pmap.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
|
|||||||
@@ -124,9 +124,13 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) -
|
|||||||
};
|
};
|
||||||
|
|
||||||
if srv.proxy.len() != 0 {
|
if srv.proxy.len() != 0 {
|
||||||
match srv.proxy.get(url.path()) {
|
let seg = match url.path_segments().map(|c| c.collect::<Vec<_>>()) {
|
||||||
|
Some(s) => s,
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
match srv.proxy.get(seg[0]) {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
revproxy::proxy(p.to_string(), url).await?;
|
revproxy::proxy(p.to_string(), url, con).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
None => {},
|
None => {},
|
||||||
|
|||||||
@@ -1,37 +1,59 @@
|
|||||||
use std::io;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::net::ToSocketAddrs;
|
|
||||||
use std::io::BufReader;
|
|
||||||
use futures_util::future;
|
use futures_util::future;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::net::ToSocketAddrs;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::io::{copy, split, AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::io::{
|
use openssl::ssl::{SslConnector, SslMethod};
|
||||||
AsyncWriteExt,
|
|
||||||
copy, split,
|
|
||||||
};
|
|
||||||
use tokio_rustls::{ TlsConnector, rustls::ClientConfig, webpki::DNSNameRef };
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub async fn proxy(addr: String, _u: url::Url) -> Result<(), io::Error> {
|
use crate::conn;
|
||||||
let addr = addr.to_socket_addrs()?
|
use crate::status;
|
||||||
|
|
||||||
|
pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> {
|
||||||
|
let p: Vec<&str> = u.path().trim_start_matches("/").splitn(2, "/").collect();
|
||||||
|
if p.len() == 1 {
|
||||||
|
con.send_status(status::Status::NotFound, "Not Found").await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if p[1] == "" || p[1] == "/" {
|
||||||
|
con.send_status(status::Status::NotFound, "Not Found").await?;
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
let addr = addr
|
||||||
|
.to_socket_addrs()?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?;
|
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?;
|
||||||
let mut config = ClientConfig::new();
|
|
||||||
|
|
||||||
let mut pem = BufReader::new(File::open("cafile")?);
|
let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
config.root_store.add_pem_file(&mut pem)
|
connector.set_verify(openssl::ssl::SslVerifyMode::NONE);
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?;
|
let config = connector.build().configure().unwrap();
|
||||||
|
|
||||||
let connector = TlsConnector::from(Arc::new(config));
|
|
||||||
let stream = TcpStream::connect(&addr).await?;
|
|
||||||
|
|
||||||
let domain = DNSNameRef::try_from_ascii_str("cbook.lan")
|
|
||||||
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid dnsname"))?;
|
|
||||||
|
|
||||||
println!("Connecting to agena...");
|
|
||||||
let mut stream = connector.connect(domain, stream).await?;
|
|
||||||
//stream.write_all(b"gopher://gopher.club/\r\n").await?;
|
|
||||||
//stream.flush().await?;
|
|
||||||
|
|
||||||
|
let stream = match TcpStream::connect(&addr).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("Error connecting to proxy");
|
||||||
|
con.send_status(status::Status::ProxyError, "Error Connecting to proxy").await?;
|
||||||
|
return Ok(())
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mut stream = match tokio_openssl::connect(config, "localhost", stream).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("Error connecting to proxy");
|
||||||
|
con.send_status(status::Status::ProxyError, "Error Connecting to proxy").await?;
|
||||||
|
return Ok(())
|
||||||
|
},
|
||||||
|
};
|
||||||
|
stream.write_all(p[1].as_bytes()).await?;
|
||||||
|
stream.flush().await?;
|
||||||
|
|
||||||
|
let mut buf = vec![];
|
||||||
|
stream.read_to_end(&mut buf).await?;
|
||||||
|
// let req = String::from_utf8(buf[..].to_vec()).unwrap();
|
||||||
|
con.send_raw(&buf).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user