Organized Code
This commit is contained in:
parent
a879755865
commit
9a83d0c7bc
5 changed files with 476 additions and 471 deletions
|
|
@ -6,4 +6,4 @@ edition = "2018"
|
||||||
# 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
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sslrelay = {path = "../SSLRelay-lib"}
|
sslrelay = {path = "../../"}
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,22 @@ struct Handler;
|
||||||
impl HandlerCallbacks for Handler {
|
impl HandlerCallbacks for Handler {
|
||||||
|
|
||||||
// Request non blocking callback
|
// Request non blocking callback
|
||||||
fn req_nb_callback(&self, _in_data: Vec<u8>) {
|
fn ds_nb_callback(&self, _in_data: Vec<u8>) {
|
||||||
println!("[+] Request Non Blocking CallBack!");
|
println!("[+] Request Non Blocking CallBack!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request blocking callback
|
// Request blocking callback
|
||||||
fn req_b_callback(&self, _in_data: &mut Vec<u8>) {
|
fn ds_b_callback(&self, _in_data: &mut Vec<u8>) {
|
||||||
println!("[+] Request Blocking CallBack!");
|
println!("[+] Request Blocking CallBack!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response non blocking callback
|
// Response non blocking callback
|
||||||
fn res_nb_callback(&self, _in_data: Vec<u8>) {
|
fn us_nb_callback(&self, _in_data: Vec<u8>) {
|
||||||
println!("[+] Response Non Blocking CallBack!");
|
println!("[+] Response Non Blocking CallBack!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response blocking callback
|
// Response blocking callback
|
||||||
fn res_b_callback(&self, _in_data: &mut Vec<u8>) {
|
fn us_b_callback(&self, _in_data: &mut Vec<u8>) {
|
||||||
println!("[+] Response Blocking CallBack!");
|
println!("[+] Response Blocking CallBack!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
139
src/data.rs
Normal file
139
src/data.rs
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
|
||||||
|
use std::net::TcpStream;
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum StreamDirection {
|
||||||
|
Upstream,// Data coming from remote host
|
||||||
|
DownStream,// Data coming from origin host
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DataHandler {
|
||||||
|
pub tcp_stream: Option<SslStream<TcpStream>>,
|
||||||
|
relay_stream: Option<SslStream<TcpStream>>,
|
||||||
|
remote_host: String,
|
||||||
|
pub stream_direction: StreamDirection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataHandler {
|
||||||
|
|
||||||
|
pub fn new(tcp_stream: SslStream<TcpStream>, remote_host: String) -> Self {
|
||||||
|
let _ = tcp_stream.get_ref().set_read_timeout(Some(Duration::from_millis(100)));
|
||||||
|
DataHandler {
|
||||||
|
tcp_stream: Some(tcp_stream),
|
||||||
|
relay_stream: None,
|
||||||
|
remote_host,
|
||||||
|
stream_direction: StreamDirection::DownStream,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_data_stream(&mut self, data: &mut Vec<u8>) -> usize {
|
||||||
|
|
||||||
|
let mut data_length: usize = 0;
|
||||||
|
if self.stream_direction == StreamDirection::DownStream {
|
||||||
|
loop {
|
||||||
|
|
||||||
|
let mut r_buf = [0; 1024];
|
||||||
|
|
||||||
|
match self.tcp_stream.as_mut().unwrap().read(&mut r_buf) {
|
||||||
|
|
||||||
|
Ok(bytes_read) => {
|
||||||
|
|
||||||
|
if bytes_read == 0 {
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if bytes_read != 0 && bytes_read <= 1024 {
|
||||||
|
|
||||||
|
let mut tmp_buf = r_buf.to_vec();
|
||||||
|
tmp_buf.truncate(bytes_read);
|
||||||
|
|
||||||
|
let _bw = data.write(&tmp_buf).unwrap();
|
||||||
|
data_length += bytes_read;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
println!("[+] Else hit!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
match e.kind() {
|
||||||
|
io::ErrorKind::WouldBlock => {
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => {println!("[!!!] Got error: {}",e);}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if self.stream_direction == StreamDirection::Upstream {
|
||||||
|
loop {
|
||||||
|
|
||||||
|
let mut r_buf = [0; 1024];
|
||||||
|
|
||||||
|
match self.relay_stream.as_mut().unwrap().read(&mut r_buf) {
|
||||||
|
|
||||||
|
Ok(bytes_read) => {
|
||||||
|
|
||||||
|
if bytes_read == 0 {
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if bytes_read != 0 && bytes_read <= 1024 {
|
||||||
|
|
||||||
|
let mut tmp_buf = r_buf.to_vec();
|
||||||
|
tmp_buf.truncate(bytes_read);
|
||||||
|
|
||||||
|
let _bw = data.write(&tmp_buf).unwrap();
|
||||||
|
data_length += bytes_read;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
println!("[+] Else hit!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
match e.kind() {
|
||||||
|
io::ErrorKind::WouldBlock => {
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => {println!("[!!!] Got error: {}",e);}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn relay_data(&mut self, data: &Vec<u8>) -> Option<i8> {
|
||||||
|
|
||||||
|
let mut retries = 3;
|
||||||
|
loop {
|
||||||
|
|
||||||
|
let mut sslbuild = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
|
sslbuild.set_verify(SslVerifyMode::NONE);
|
||||||
|
let connector = sslbuild.build();
|
||||||
|
let stream = TcpStream::connect(&self.remote_host).unwrap();
|
||||||
|
let _ = stream.set_read_timeout(Some(Duration::from_millis(500)));
|
||||||
|
let mut stream = match connector.connect(&self.remote_host, stream) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
println!("[Error] {}", e);
|
||||||
|
if retries == 0 {
|
||||||
|
println!("[!] Request relay retries: 0");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
retries -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
stream.write_all(&data).unwrap();
|
||||||
|
let _ = stream.flush();
|
||||||
|
//println!("[+] Relayed -> {}", host);
|
||||||
|
|
||||||
|
//return Some(stream); Instead of returning we will now set stream object
|
||||||
|
self.relay_stream = Some(stream);
|
||||||
|
return Some(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // DataHandler
|
||||||
314
src/http.rs
Normal file
314
src/http.rs
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
use httparse::{self, Header};
|
||||||
|
use chunked_transfer::Decoder;
|
||||||
|
use flate2::read::GzDecoder;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
pub struct RelayedResponse<'a> {
|
||||||
|
http_version: Option<u8>,
|
||||||
|
http_code: Option<u16>,
|
||||||
|
http_reason: Option<String>,
|
||||||
|
http_headers: Option<Vec<Header<'a>>>,
|
||||||
|
http_body: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RelayRequest<'a> {
|
||||||
|
http_method: Option<String>,
|
||||||
|
http_path: Option<String>,
|
||||||
|
http_version: Option<u8>,
|
||||||
|
http_headers: Option<Vec<Header<'a>>>,
|
||||||
|
http_body: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn get_req_headers<'a>(&self, data: &'a Vec<u8>) -> Option<Vec<Header<'a>>> {
|
||||||
|
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
let mut request = httparse::Request::new(&mut headers);
|
||||||
|
|
||||||
|
let req = request.parse(data).unwrap();
|
||||||
|
|
||||||
|
if req.is_complete() {
|
||||||
|
return Some(headers.to_vec());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_res_headers(data: &Vec<u8>) -> Option<Vec<Header>> {
|
||||||
|
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
let mut response = httparse::Response::new(&mut headers);
|
||||||
|
|
||||||
|
let res = response.parse(data).unwrap();
|
||||||
|
|
||||||
|
if res.is_complete() {
|
||||||
|
return Some(headers.to_vec());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_host(&self, data: &Vec<u8>) -> Option<String> {
|
||||||
|
|
||||||
|
return Some("137.220.37.67".to_string());
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
|
||||||
|
let mut request = httparse::Request::new(&mut headers);
|
||||||
|
|
||||||
|
let req = request.parse(data).unwrap();
|
||||||
|
|
||||||
|
if req.is_complete() {
|
||||||
|
for header in headers.iter() {
|
||||||
|
if header.name == "Host" || header.name == "host" {
|
||||||
|
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
} else if req.is_partial() {
|
||||||
|
for header in headers.iter() {
|
||||||
|
if header.name == "Host" || header.name == "host" {
|
||||||
|
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cookie(&self, data: &Vec<u8>) -> Option<String> {
|
||||||
|
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
|
||||||
|
let mut request = httparse::Request::new(&mut headers);
|
||||||
|
|
||||||
|
let req = request.parse(data).unwrap();
|
||||||
|
|
||||||
|
if req.is_complete() {
|
||||||
|
for header in headers.iter() {
|
||||||
|
if header.name == "Cookie" || header.name == "cookie" {
|
||||||
|
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
} else if req.is_partial() {
|
||||||
|
for header in headers.iter() {
|
||||||
|
if header.name == "Cookie" || header.name == "cookie" {
|
||||||
|
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub fn http_req_verbose(data: &Vec<u8>, mode: u8) {
|
||||||
|
|
||||||
|
let req_info = get_request(&data);
|
||||||
|
let req_header_list = req_info.http_headers.unwrap();
|
||||||
|
let mut req_header_string = String::new();
|
||||||
|
|
||||||
|
for header in req_header_list {
|
||||||
|
if header.value.to_vec().len() == 0 {continue;}
|
||||||
|
req_header_string.push_str(format!("[-->] {}: {}\n", header.name, String::from_utf8(header.value.to_vec()).unwrap()).as_str());
|
||||||
|
}
|
||||||
|
if mode == 1 {
|
||||||
|
println!("================================\n[-->] HTTP Version: {}\n[-->] HTTP Method: {} {}\n[-->] HTTP Headers:\n{}\n[-->] HTTP Body:\n{}\n"
|
||||||
|
,req_info.http_version.unwrap()
|
||||||
|
,req_info.http_method.unwrap()
|
||||||
|
,req_info.http_path.unwrap()
|
||||||
|
,req_header_string
|
||||||
|
,req_info.http_body.unwrap()
|
||||||
|
);
|
||||||
|
} else if mode == 2 {
|
||||||
|
println!("[Req] {} {}", req_info.http_method.unwrap(), req_info.http_path.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn http_res_verbose(response_data: &Vec<u8>, mode: u8) {
|
||||||
|
|
||||||
|
let res_info = get_response(&response_data);
|
||||||
|
let header_list = res_info.http_headers.unwrap();
|
||||||
|
let mut header_string = String::new();
|
||||||
|
|
||||||
|
for header in header_list {
|
||||||
|
if header.value.to_vec().len() == 0 {continue;}
|
||||||
|
header_string.push_str(format!("[<--] {}: {}\n", header.name, String::from_utf8(header.value.to_vec()).unwrap()).as_str());
|
||||||
|
}
|
||||||
|
if mode == 1 {
|
||||||
|
println!("\n[<--] HTTP Version: {}\n[<--] HTTP Code: {} {}\n[<--] HTTP Headers:\n{}\n[<--] HTTP Body:\n{}\n================================\n"
|
||||||
|
,res_info.http_version.unwrap()
|
||||||
|
,res_info.http_code.unwrap()
|
||||||
|
,res_info.http_reason.unwrap()
|
||||||
|
,header_string
|
||||||
|
,res_info.http_body.unwrap()
|
||||||
|
);
|
||||||
|
} else if mode == 2 {
|
||||||
|
println!("[Res] {} {}", res_info.http_code.unwrap(), res_info.http_reason.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_response<'a>(data: &'a Vec<u8>) -> RelayedResponse<'a> {
|
||||||
|
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
let mut res = httparse::Response::new(&mut headers);
|
||||||
|
|
||||||
|
let res_chk = res.parse(data);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
|
||||||
|
if !res_chk.unwrap().is_complete() {
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let reason = match res.reason {
|
||||||
|
Some(r) => Some(r.to_string()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let header_vec = res.headers.to_vec();
|
||||||
|
|
||||||
|
let body = get_http_body(&data, header_vec).unwrap_or(String::from("[-] Failed to get http response body!").into_bytes());
|
||||||
|
let string_body = String::from_utf8(body).unwrap();
|
||||||
|
|
||||||
|
return RelayedResponse {
|
||||||
|
http_version: res.version,
|
||||||
|
http_code: res.code,
|
||||||
|
http_reason: reason,
|
||||||
|
http_headers: Some(headers.to_vec()),
|
||||||
|
http_body: Some(string_body),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_request<'a>(data: &'a Vec<u8>) -> RelayRequest<'a> {
|
||||||
|
|
||||||
|
let mut headers = [httparse::EMPTY_HEADER; 128];
|
||||||
|
let mut req = httparse::Request::new(&mut headers);
|
||||||
|
|
||||||
|
let req_chk = req.parse(data);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
|
||||||
|
if !req_chk.unwrap().is_complete() {
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let method = match req.method {
|
||||||
|
Some(r) => Some(r.to_string()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = match req.path {
|
||||||
|
Some(p) => Some(p.to_string()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let header_vec = req.headers.to_vec();
|
||||||
|
|
||||||
|
let body = get_http_body(&data, header_vec).unwrap_or(String::from("[-] Failed to get http request body!").into_bytes());
|
||||||
|
let string_body = String::from_utf8(body).unwrap();
|
||||||
|
|
||||||
|
return RelayRequest {
|
||||||
|
http_method: method,
|
||||||
|
http_path: path,
|
||||||
|
http_version: req.version,
|
||||||
|
http_headers: Some(headers.to_vec()),
|
||||||
|
http_body: Some(string_body),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_http_body(data: &Vec<u8>, headers: Vec<Header>) -> Option<Vec<u8>> {
|
||||||
|
|
||||||
|
let mut cl: u64 = 0;
|
||||||
|
let encoding_check = headers.clone();
|
||||||
|
for header in headers {
|
||||||
|
|
||||||
|
if header.name == "Content-Length" || header.name == "content-length" {
|
||||||
|
let length = match String::from_utf8(header.value.to_vec()) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
println!("[!] ERROR: {}",e);
|
||||||
|
return None;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
cl += length.parse::<u64>().unwrap();
|
||||||
|
let mut r_body = data.to_vec();
|
||||||
|
r_body.reverse();
|
||||||
|
r_body.truncate(cl as usize);
|
||||||
|
r_body.reverse();
|
||||||
|
|
||||||
|
return Some(r_body);
|
||||||
|
|
||||||
|
} else if header.name == "Transfer-Encoding" || header.name == "transfer-encoding" {
|
||||||
|
|
||||||
|
let te_string = String::from_utf8(header.value.to_vec()).unwrap();
|
||||||
|
|
||||||
|
if te_string == "chunked" {
|
||||||
|
|
||||||
|
let mut new_vec = data.to_vec();
|
||||||
|
let new_vec_iter = new_vec.to_vec();
|
||||||
|
let mut new_vec_iter = new_vec_iter.iter();
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Some(&0x0d) = new_vec_iter.next() {
|
||||||
|
i += 1;
|
||||||
|
if let Some(&0x0a) = new_vec_iter.next() {
|
||||||
|
i += 1;
|
||||||
|
if let Some(&0x0d) = new_vec_iter.next() {
|
||||||
|
i += 1;
|
||||||
|
if let Some(&0x0a) = new_vec_iter.next() {
|
||||||
|
i += 1;
|
||||||
|
break;
|
||||||
|
} else {i += 1;}
|
||||||
|
} else {i += 1;}
|
||||||
|
} else {i += 1;}
|
||||||
|
} else {i += 1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_vec.reverse();
|
||||||
|
new_vec.truncate(data.len() - i);
|
||||||
|
new_vec.reverse();
|
||||||
|
|
||||||
|
let mut decoder = Decoder::new(new_vec.as_slice());
|
||||||
|
let mut blob = Vec::new();
|
||||||
|
let _ = decoder.read_to_end(&mut blob);
|
||||||
|
|
||||||
|
let mut g_encoded = false;
|
||||||
|
for header in encoding_check {
|
||||||
|
if header.name == "Content-Encoding" || header.name == "content-encoding" {
|
||||||
|
let s = String::from_utf8(header.value.to_vec()).unwrap();
|
||||||
|
if s == "gzip" {
|
||||||
|
g_encoded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if g_encoded {
|
||||||
|
let mut gzd = GzDecoder::new(&blob[..]);
|
||||||
|
let mut unzipped = Vec::new();
|
||||||
|
match gzd.read_to_end(&mut unzipped) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(_) => return None,
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(unzipped);
|
||||||
|
} else {
|
||||||
|
return Some(blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(String::from("None").into_bytes());
|
||||||
|
}
|
||||||
484
src/lib.rs
484
src/lib.rs
|
|
@ -1,35 +1,18 @@
|
||||||
use openssl::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod, SslStream, SslVerifyMode};
|
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslStream};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::Write;
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use toml::Value as TValue;
|
use toml::Value as TValue;
|
||||||
|
|
||||||
use chunked_transfer::Decoder;
|
mod data;
|
||||||
|
use data::{DataHandler, StreamDirection};
|
||||||
|
|
||||||
use flate2::read::GzDecoder;
|
mod http;
|
||||||
|
use http as http_helper;
|
||||||
use httparse::{self, Header};
|
|
||||||
|
|
||||||
struct RelayedResponse<'a> {
|
|
||||||
http_version: Option<u8>,
|
|
||||||
http_code: Option<u16>,
|
|
||||||
http_reason: Option<String>,
|
|
||||||
http_headers: Option<Vec<Header<'a>>>,
|
|
||||||
http_body: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RelayRequest<'a> {
|
|
||||||
http_method: Option<String>,
|
|
||||||
http_path: Option<String>,
|
|
||||||
http_version: Option<u8>,
|
|
||||||
http_headers: Option<Vec<Header<'a>>>,
|
|
||||||
http_body: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct RelayConfig {
|
struct RelayConfig {
|
||||||
|
|
@ -44,10 +27,10 @@ struct RelayConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HandlerCallbacks {
|
pub trait HandlerCallbacks {
|
||||||
fn req_b_callback(&self, _in_data: &mut Vec<u8>){}
|
fn ds_b_callback(&self, _in_data: &mut Vec<u8>){}
|
||||||
fn req_nb_callback(&self, _in_data: Vec<u8>){}
|
fn ds_nb_callback(&self, _in_data: Vec<u8>){}
|
||||||
fn res_b_callback(&self, _in_data: &mut Vec<u8>){}
|
fn us_b_callback(&self, _in_data: &mut Vec<u8>){}
|
||||||
fn res_nb_callback(&self, _in_data: Vec<u8>){}
|
fn us_nb_callback(&self, _in_data: Vec<u8>){}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ConfigType<T> {
|
pub enum ConfigType<T> {
|
||||||
|
|
@ -169,437 +152,8 @@ impl<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + 'static> SSLR
|
||||||
acceptor.check_private_key().unwrap();
|
acceptor.check_private_key().unwrap();
|
||||||
Arc::new(acceptor.build())
|
Arc::new(acceptor.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}// SSLRelay
|
}// SSLRelay
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
enum StreamDirection {
|
|
||||||
Upstream,// Data coming from remote host
|
|
||||||
DownStream,// Data coming from origin host
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DataHandler {
|
|
||||||
tcp_stream: Option<SslStream<TcpStream>>,
|
|
||||||
relay_stream: Option<SslStream<TcpStream>>,
|
|
||||||
remote_host: String,
|
|
||||||
stream_direction: StreamDirection,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataHandler {
|
|
||||||
|
|
||||||
fn new(tcp_stream: SslStream<TcpStream>, remote_host: String) -> Self {
|
|
||||||
let _ = tcp_stream.get_ref().set_read_timeout(Some(Duration::from_millis(100)));
|
|
||||||
DataHandler {
|
|
||||||
tcp_stream: Some(tcp_stream),
|
|
||||||
relay_stream: None,
|
|
||||||
remote_host,
|
|
||||||
stream_direction: StreamDirection::DownStream,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data_stream(&mut self, data: &mut Vec<u8>) -> usize {
|
|
||||||
|
|
||||||
let mut data_length: usize = 0;
|
|
||||||
if self.stream_direction == StreamDirection::DownStream {
|
|
||||||
loop {
|
|
||||||
|
|
||||||
let mut r_buf = [0; 1024];
|
|
||||||
|
|
||||||
match self.tcp_stream.as_mut().unwrap().read(&mut r_buf) {
|
|
||||||
|
|
||||||
Ok(bytes_read) => {
|
|
||||||
|
|
||||||
if bytes_read == 0 {
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else if bytes_read != 0 && bytes_read <= 1024 {
|
|
||||||
|
|
||||||
let mut tmp_buf = r_buf.to_vec();
|
|
||||||
tmp_buf.truncate(bytes_read);
|
|
||||||
|
|
||||||
let _bw = data.write(&tmp_buf).unwrap();
|
|
||||||
data_length += bytes_read;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
println!("[+] Else hit!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
match e.kind() {
|
|
||||||
io::ErrorKind::WouldBlock => {
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
_ => {println!("[!!!] Got error: {}",e);}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if self.stream_direction == StreamDirection::Upstream {
|
|
||||||
loop {
|
|
||||||
|
|
||||||
let mut r_buf = [0; 1024];
|
|
||||||
|
|
||||||
match self.relay_stream.as_mut().unwrap().read(&mut r_buf) {
|
|
||||||
|
|
||||||
Ok(bytes_read) => {
|
|
||||||
|
|
||||||
if bytes_read == 0 {
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else if bytes_read != 0 && bytes_read <= 1024 {
|
|
||||||
|
|
||||||
let mut tmp_buf = r_buf.to_vec();
|
|
||||||
tmp_buf.truncate(bytes_read);
|
|
||||||
|
|
||||||
let _bw = data.write(&tmp_buf).unwrap();
|
|
||||||
data_length += bytes_read;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
println!("[+] Else hit!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
match e.kind() {
|
|
||||||
io::ErrorKind::WouldBlock => {
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
_ => {println!("[!!!] Got error: {}",e);}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn http_req_verbose(&self, data: &Vec<u8>, mode: u8) {
|
|
||||||
|
|
||||||
let req_info = self.get_request(&data);
|
|
||||||
let req_header_list = req_info.http_headers.unwrap();
|
|
||||||
let mut req_header_string = String::new();
|
|
||||||
|
|
||||||
for header in req_header_list {
|
|
||||||
if header.value.to_vec().len() == 0 {continue;}
|
|
||||||
req_header_string.push_str(format!("[-->] {}: {}\n", header.name, String::from_utf8(header.value.to_vec()).unwrap()).as_str());
|
|
||||||
}
|
|
||||||
if mode == 1 {
|
|
||||||
println!("================================\n[-->] HTTP Version: {}\n[-->] HTTP Method: {} {}\n[-->] HTTP Headers:\n{}\n[-->] HTTP Body:\n{}\n"
|
|
||||||
,req_info.http_version.unwrap()
|
|
||||||
,req_info.http_method.unwrap()
|
|
||||||
,req_info.http_path.unwrap()
|
|
||||||
,req_header_string
|
|
||||||
,req_info.http_body.unwrap()
|
|
||||||
);
|
|
||||||
} else if mode == 2 {
|
|
||||||
println!("[Req] {} {}", req_info.http_method.unwrap(), req_info.http_path.unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn http_res_verbose(&self, response_data: &Vec<u8>, mode: u8) {
|
|
||||||
|
|
||||||
let res_info = self.get_response(&response_data);
|
|
||||||
let header_list = res_info.http_headers.unwrap();
|
|
||||||
let mut header_string = String::new();
|
|
||||||
|
|
||||||
for header in header_list {
|
|
||||||
if header.value.to_vec().len() == 0 {continue;}
|
|
||||||
header_string.push_str(format!("[<--] {}: {}\n", header.name, String::from_utf8(header.value.to_vec()).unwrap()).as_str());
|
|
||||||
}
|
|
||||||
if mode == 1 {
|
|
||||||
println!("\n[<--] HTTP Version: {}\n[<--] HTTP Code: {} {}\n[<--] HTTP Headers:\n{}\n[<--] HTTP Body:\n{}\n================================\n"
|
|
||||||
,res_info.http_version.unwrap()
|
|
||||||
,res_info.http_code.unwrap()
|
|
||||||
,res_info.http_reason.unwrap()
|
|
||||||
,header_string
|
|
||||||
,res_info.http_body.unwrap()
|
|
||||||
);
|
|
||||||
} else if mode == 2 {
|
|
||||||
println!("[Res] {} {}", res_info.http_code.unwrap(), res_info.http_reason.unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relay_data(&mut self, data: &Vec<u8>) -> Option<i8> {
|
|
||||||
|
|
||||||
let mut retries = 3;
|
|
||||||
loop {
|
|
||||||
|
|
||||||
let mut sslbuild = SslConnector::builder(SslMethod::tls()).unwrap();
|
|
||||||
sslbuild.set_verify(SslVerifyMode::NONE);
|
|
||||||
let connector = sslbuild.build();
|
|
||||||
let stream = TcpStream::connect(&self.remote_host).unwrap();
|
|
||||||
let _ = stream.set_read_timeout(Some(Duration::from_millis(500)));
|
|
||||||
let mut stream = match connector.connect(&self.remote_host, stream) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => {
|
|
||||||
println!("[Error] {}", e);
|
|
||||||
if retries == 0 {
|
|
||||||
println!("[!] Request relay retries: 0");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
retries -= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
stream.write_all(&data).unwrap();
|
|
||||||
let _ = stream.flush();
|
|
||||||
//println!("[+] Relayed -> {}", host);
|
|
||||||
|
|
||||||
//return Some(stream); Instead of returning we will now set stream object
|
|
||||||
self.relay_stream = Some(stream);
|
|
||||||
return Some(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
fn get_req_headers<'a>(&self, data: &'a Vec<u8>) -> Option<Vec<Header<'a>>> {
|
|
||||||
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
let mut request = httparse::Request::new(&mut headers);
|
|
||||||
|
|
||||||
let req = request.parse(data).unwrap();
|
|
||||||
|
|
||||||
if req.is_complete() {
|
|
||||||
return Some(headers.to_vec());
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_res_headers(data: &Vec<u8>) -> Option<Vec<Header>> {
|
|
||||||
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
let mut response = httparse::Response::new(&mut headers);
|
|
||||||
|
|
||||||
let res = response.parse(data).unwrap();
|
|
||||||
|
|
||||||
if res.is_complete() {
|
|
||||||
return Some(headers.to_vec());
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_host(&self, data: &Vec<u8>) -> Option<String> {
|
|
||||||
|
|
||||||
return Some("137.220.37.67".to_string());
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
|
|
||||||
let mut request = httparse::Request::new(&mut headers);
|
|
||||||
|
|
||||||
let req = request.parse(data).unwrap();
|
|
||||||
|
|
||||||
if req.is_complete() {
|
|
||||||
for header in headers.iter() {
|
|
||||||
if header.name == "Host" || header.name == "host" {
|
|
||||||
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
} else if req.is_partial() {
|
|
||||||
for header in headers.iter() {
|
|
||||||
if header.name == "Host" || header.name == "host" {
|
|
||||||
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cookie(&self, data: &Vec<u8>) -> Option<String> {
|
|
||||||
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
|
|
||||||
let mut request = httparse::Request::new(&mut headers);
|
|
||||||
|
|
||||||
let req = request.parse(data).unwrap();
|
|
||||||
|
|
||||||
if req.is_complete() {
|
|
||||||
for header in headers.iter() {
|
|
||||||
if header.name == "Cookie" || header.name == "cookie" {
|
|
||||||
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
} else if req.is_partial() {
|
|
||||||
for header in headers.iter() {
|
|
||||||
if header.name == "Cookie" || header.name == "cookie" {
|
|
||||||
//println!("Host -> {}", String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
return Some(String::from_utf8(header.value.to_vec()).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
fn get_response<'a>(&self, data: &'a Vec<u8>) -> RelayedResponse<'a> {
|
|
||||||
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
let mut res = httparse::Response::new(&mut headers);
|
|
||||||
|
|
||||||
let res_chk = res.parse(data);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
|
|
||||||
if !res_chk.unwrap().is_complete() {
|
|
||||||
thread::sleep(Duration::from_millis(100));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let reason = match res.reason {
|
|
||||||
Some(r) => Some(r.to_string()),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let header_vec = res.headers.to_vec();
|
|
||||||
|
|
||||||
let body = self.get_http_body(&data, header_vec).unwrap_or(String::from("[-] Failed to get http response body!").into_bytes());
|
|
||||||
let string_body = String::from_utf8(body).unwrap();
|
|
||||||
|
|
||||||
return RelayedResponse {
|
|
||||||
http_version: res.version,
|
|
||||||
http_code: res.code,
|
|
||||||
http_reason: reason,
|
|
||||||
http_headers: Some(headers.to_vec()),
|
|
||||||
http_body: Some(string_body),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_request<'a>(&self, data: &'a Vec<u8>) -> RelayRequest<'a> {
|
|
||||||
|
|
||||||
let mut headers = [httparse::EMPTY_HEADER; 128];
|
|
||||||
let mut req = httparse::Request::new(&mut headers);
|
|
||||||
|
|
||||||
let req_chk = req.parse(data);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
|
|
||||||
if !req_chk.unwrap().is_complete() {
|
|
||||||
thread::sleep(Duration::from_millis(100));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let method = match req.method {
|
|
||||||
Some(r) => Some(r.to_string()),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let path = match req.path {
|
|
||||||
Some(p) => Some(p.to_string()),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let header_vec = req.headers.to_vec();
|
|
||||||
|
|
||||||
let body = self.get_http_body(&data, header_vec).unwrap_or(String::from("[-] Failed to get http request body!").into_bytes());
|
|
||||||
let string_body = String::from_utf8(body).unwrap();
|
|
||||||
|
|
||||||
return RelayRequest {
|
|
||||||
http_method: method,
|
|
||||||
http_path: path,
|
|
||||||
http_version: req.version,
|
|
||||||
http_headers: Some(headers.to_vec()),
|
|
||||||
http_body: Some(string_body),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_http_body(&self, data: &Vec<u8>, headers: Vec<Header>) -> Option<Vec<u8>> {
|
|
||||||
|
|
||||||
let mut cl: u64 = 0;
|
|
||||||
let encoding_check = headers.clone();
|
|
||||||
for header in headers {
|
|
||||||
|
|
||||||
if header.name == "Content-Length" || header.name == "content-length" {
|
|
||||||
let length = match String::from_utf8(header.value.to_vec()) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => {
|
|
||||||
println!("[!] ERROR: {}",e);
|
|
||||||
return None;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cl += length.parse::<u64>().unwrap();
|
|
||||||
let mut r_body = data.to_vec();
|
|
||||||
r_body.reverse();
|
|
||||||
r_body.truncate(cl as usize);
|
|
||||||
r_body.reverse();
|
|
||||||
|
|
||||||
return Some(r_body);
|
|
||||||
|
|
||||||
} else if header.name == "Transfer-Encoding" || header.name == "transfer-encoding" {
|
|
||||||
|
|
||||||
let te_string = String::from_utf8(header.value.to_vec()).unwrap();
|
|
||||||
|
|
||||||
if te_string == "chunked" {
|
|
||||||
|
|
||||||
let mut new_vec = data.to_vec();
|
|
||||||
let new_vec_iter = new_vec.to_vec();
|
|
||||||
let mut new_vec_iter = new_vec_iter.iter();
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if let Some(&0x0d) = new_vec_iter.next() {
|
|
||||||
i += 1;
|
|
||||||
if let Some(&0x0a) = new_vec_iter.next() {
|
|
||||||
i += 1;
|
|
||||||
if let Some(&0x0d) = new_vec_iter.next() {
|
|
||||||
i += 1;
|
|
||||||
if let Some(&0x0a) = new_vec_iter.next() {
|
|
||||||
i += 1;
|
|
||||||
break;
|
|
||||||
} else {i += 1;}
|
|
||||||
} else {i += 1;}
|
|
||||||
} else {i += 1;}
|
|
||||||
} else {i += 1;}
|
|
||||||
}
|
|
||||||
|
|
||||||
new_vec.reverse();
|
|
||||||
new_vec.truncate(data.len() - i);
|
|
||||||
new_vec.reverse();
|
|
||||||
|
|
||||||
let mut decoder = Decoder::new(new_vec.as_slice());
|
|
||||||
let mut blob = Vec::new();
|
|
||||||
let _ = decoder.read_to_end(&mut blob);
|
|
||||||
|
|
||||||
let mut g_encoded = false;
|
|
||||||
for header in encoding_check {
|
|
||||||
if header.name == "Content-Encoding" || header.name == "content-encoding" {
|
|
||||||
let s = String::from_utf8(header.value.to_vec()).unwrap();
|
|
||||||
if s == "gzip" {
|
|
||||||
g_encoded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if g_encoded {
|
|
||||||
let mut gzd = GzDecoder::new(&blob[..]);
|
|
||||||
let mut unzipped = Vec::new();
|
|
||||||
match gzd.read_to_end(&mut unzipped) {
|
|
||||||
Ok(_) => {},
|
|
||||||
Err(_) => return None,
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(unzipped);
|
|
||||||
} else {
|
|
||||||
return Some(blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Some(String::from("None").into_bytes());
|
|
||||||
}
|
|
||||||
} // DataHandler
|
|
||||||
|
|
||||||
|
|
||||||
/* Rewrite this to handle TCP connections until TCP connection is dropped instead of dropping it */
|
/* Rewrite this to handle TCP connections until TCP connection is dropped instead of dropping it */
|
||||||
fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + 'static>(tcp_stream: SslStream<TcpStream>, rc_config: Arc<Mutex<RelayConfig>>, handlers: Arc<Mutex<H>>) {
|
fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + 'static>(tcp_stream: SslStream<TcpStream>, rc_config: Arc<Mutex<RelayConfig>>, handlers: Arc<Mutex<H>>) {
|
||||||
|
|
||||||
|
|
@ -619,9 +173,9 @@ fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + '
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if verbose_mode == 1 {
|
if verbose_mode == 1 {
|
||||||
datahandler.http_req_verbose(&data, 1);
|
http_helper::http_req_verbose(&data, 1);
|
||||||
} else if verbose_mode == 2 {
|
} else if verbose_mode == 2 {
|
||||||
datahandler.http_req_verbose(&data, 2);
|
http_helper::http_req_verbose(&data, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
let handlers_p = handlers.clone();
|
let handlers_p = handlers.clone();
|
||||||
|
|
@ -629,17 +183,15 @@ fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + '
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let handlers_lock = handlers_p.lock().unwrap();
|
let handlers_lock = handlers_p.lock().unwrap();
|
||||||
handlers_lock.req_nb_callback(d);
|
handlers_lock.ds_nb_callback(d);
|
||||||
drop(handlers_lock);
|
drop(handlers_lock);
|
||||||
});
|
});
|
||||||
|
|
||||||
let handlers_p = handlers.clone();
|
let handlers_p = handlers.clone();
|
||||||
let handlers_lock = handlers_p.lock().unwrap();
|
let handlers_lock = handlers_p.lock().unwrap();
|
||||||
handlers_lock.req_b_callback(&mut data);
|
handlers_lock.ds_b_callback(&mut data);
|
||||||
drop(handlers_lock);
|
drop(handlers_lock);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
match datahandler.relay_data(&data) {
|
match datahandler.relay_data(&data) {
|
||||||
Some(_relay_success) => {},
|
Some(_relay_success) => {},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -653,9 +205,9 @@ fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + '
|
||||||
let _response_size = datahandler.get_data_stream(&mut response_data);
|
let _response_size = datahandler.get_data_stream(&mut response_data);
|
||||||
|
|
||||||
if verbose_mode == 1 {
|
if verbose_mode == 1 {
|
||||||
datahandler.http_res_verbose(&response_data, 1);
|
http_helper::http_res_verbose(&response_data, 1);
|
||||||
} else if verbose_mode == 2 {
|
} else if verbose_mode == 2 {
|
||||||
datahandler.http_res_verbose(&response_data, 2);
|
http_helper::http_res_verbose(&response_data, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch back to DownStream mode to relay data from remote host back to origin host
|
// Switch back to DownStream mode to relay data from remote host back to origin host
|
||||||
|
|
@ -666,13 +218,13 @@ fn handle_stream<H: HandlerCallbacks + std::marker::Sync + std::marker::Send + '
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let handlers_lock = handlers_p.lock().unwrap();
|
let handlers_lock = handlers_p.lock().unwrap();
|
||||||
handlers_lock.res_nb_callback(d);
|
handlers_lock.us_nb_callback(d);
|
||||||
drop(handlers_lock);
|
drop(handlers_lock);
|
||||||
});
|
});
|
||||||
|
|
||||||
let handlers_p = handlers.clone();
|
let handlers_p = handlers.clone();
|
||||||
let handlers_lock = handlers_p.lock().unwrap();
|
let handlers_lock = handlers_p.lock().unwrap();
|
||||||
handlers_lock.res_b_callback(&mut response_data);
|
handlers_lock.us_b_callback(&mut response_data);
|
||||||
drop(handlers_lock);
|
drop(handlers_lock);
|
||||||
|
|
||||||
datahandler.tcp_stream.as_mut().unwrap().write_all(&response_data).unwrap();
|
datahandler.tcp_stream.as_mut().unwrap().write_all(&response_data).unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue