proxying works in a rough first pass

This commit is contained in:
Brandon Thomas
2020-09-07 16:04:26 -04:00
parent 99b6bb3788
commit 35687652e7
2 changed files with 61 additions and 16 deletions
+36 -7
View File
@@ -8,6 +8,7 @@ pub mod speak_proxy;
use anyhow::Result as AnyhowResult; use anyhow::Result as AnyhowResult;
use crate::newrelic_logger::{NewRelicLogger, MaybeNewRelicTransaction}; use crate::newrelic_logger::{NewRelicLogger, MaybeNewRelicTransaction};
use futures::future::{self, Future}; use futures::future::{self, Future};
use crate::speak_proxy::speak_proxy;
use hyper::{Method, StatusCode}; use hyper::{Method, StatusCode};
use hyper::header::HeaderValue; use hyper::header::HeaderValue;
use hyper::http::header::HeaderName; use hyper::http::header::HeaderName;
@@ -133,10 +134,34 @@ pub async fn handle(
{ {
match req.uri().path() { match req.uri().path() {
"/speak" => { "/speak" => {
debug_request(req) let nr_transaction = newrelic_logger.web_transaction("/speak");
let result = speak_proxy(client_ip, req, router, nr_transaction, "/speak").await;
match result {
Ok(response) => {
Ok(response)
},
Err(_error) => {
Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap())
}
}
}, },
"/speak_spectrogram" => { "/speak_spectrogram" => {
debug_request(req) let nr_transaction = newrelic_logger.web_transaction("/speak_spectrogram");
let result = speak_proxy(client_ip, req, router, nr_transaction, "/speak_spectrogram").await;
match result {
Ok(response) => {
Ok(response)
},
Err(_error) => {
Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap())
}
}
}, },
"/proxy_health" => { "/proxy_health" => {
debug_request(req) debug_request(req)
@@ -149,11 +174,15 @@ pub async fn handle(
info!("Forwarding to `{}` random host: {}", &forward, req.uri()); info!("Forwarding to `{}` random host: {}", &forward, req.uri());
match hyper_reverse_proxy::call(client_ip, &forward, req).await { match hyper_reverse_proxy::call(client_ip, &forward, req).await {
Ok(response) => {Ok(response)} Ok(response) => {
Err(error) => {Ok(Response::builder() Ok(response)
.status(StatusCode::INTERNAL_SERVER_ERROR) },
.body(Body::empty()) Err(error) => {
.unwrap())} Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::empty())
.unwrap())
}
} }
}, },
} }
+25 -9
View File
@@ -18,6 +18,7 @@ use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use std::convert::Infallible; use std::convert::Infallible;
use hyper_reverse_proxy::ProxyError; use hyper_reverse_proxy::ProxyError;
use futures::TryStreamExt;
/// NB: This much match the shape of SpeakRequest in the 'voder/tts_service' code. /// NB: This much match the shape of SpeakRequest in the 'voder/tts_service' code.
/// This is used for both /speak and /speak_spectrogram requests. /// This is used for both /speak and /speak_spectrogram requests.
@@ -59,17 +60,22 @@ struct RequestDetails {
.boxed() .boxed()
}*/ }*/
#[derive(Serialize, Debug)]
pub struct ResponseError {
pub reason: String,
}
pub async fn speak_proxy( pub async fn speak_proxy(
remote_addr: SocketAddr, ip_addr: IpAddr,
req: Request<Vec<u8>>, req: Request<Body>,
router: Arc<Router>, router: Arc<Router>,
transaction: MaybeNewRelicTransaction, transaction: MaybeNewRelicTransaction,
endpoint: &'static str) -> Box<Future<Output=Result<Response<Body>, ProxyError>>> endpoint: &'static str) -> Result<Response<Body>, ResponseError>
{ {
let mut headers = req.headers().clone(); let mut headers = req.headers().clone();
// This is the IP of the Digital Ocean load balancer. // This is the IP of the Digital Ocean load balancer.
let gateway_ip = HeaderValue::from_str(&remote_addr.ip().to_string()) let gateway_ip = HeaderValue::from_str(&ip_addr.to_string())
.ok() .ok()
.unwrap_or(HeaderValue::from_static("")); .unwrap_or(HeaderValue::from_static(""));
@@ -89,9 +95,17 @@ pub async fn speak_proxy(
headers.insert(HeaderName::from_static("x-voder-proxy-for"), upstream_client_ip.clone()); headers.insert(HeaderName::from_static("x-voder-proxy-for"), upstream_client_ip.clone());
headers.insert(HeaderName::from_static("x-gateway-ip"), gateway_ip); headers.insert(HeaderName::from_static("x-gateway-ip"), gateway_ip);
let request_bytes = req.body(); let (parts, body) = req.into_parts();
let request = serde_json::from_slice::<SpeakRequest>(request_bytes) let request_bytes = body
.try_fold(Vec::new(), |mut data, chunk| async move {
data.extend_from_slice(&chunk);
Ok(data)
})
.await
.unwrap();
let request = serde_json::from_slice::<SpeakRequest>(&request_bytes)
.unwrap(); .unwrap();
let request_details = RequestDetails { let request_details = RequestDetails {
@@ -119,9 +133,11 @@ pub async fn speak_proxy(
.unwrap(); .unwrap();
//Box::new(future::ok(Vec::new())) //Box::new(future::ok(Vec::new()))
match hyper_reverse_proxy::call(remote_addr.ip(), &proxy_host, new_req).await { match hyper_reverse_proxy::call(ip_addr, &proxy_host, new_req).await {
Ok(result) => Box::new(future::ok(result)), Ok(result) => Ok(result),
Err(result) => Box::new(future::err(result)), Err(_result) => Err(ResponseError {
reason: "Uknown failure".to_string()
}),
} }
} }