Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http): add remote_addr to logs #945

Merged
merged 1 commit into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions warpgate-protocol-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use async_trait::async_trait;
use common::page_admin_auth;
pub use common::PROTOCOL_NAME;
use http::HeaderValue;
use logging::{log_request_result, span_for_request};
use logging::{get_client_ip, log_request_result, span_for_request};
use poem::endpoint::{EmbeddedFileEndpoint, EmbeddedFilesEndpoint};
use poem::listener::{Listener, RustlsConfig, TcpListener};
use poem::middleware::SetHeader;
Expand Down Expand Up @@ -122,8 +122,11 @@ impl ProtocolServer for HTTPProtocolServer {
.around(move |ep, req| async move {
let method = req.method().clone();
let url = req.original_uri().clone();
let client_ip = get_client_ip(&req).await?;

let response = ep.call(req).await?;
log_request_result(&method, &url, &response.status());

log_request_result(&method, &url, client_ip, &response.status());
Ok(response)
}),
)
Expand Down Expand Up @@ -206,7 +209,9 @@ impl ProtocolServer for HTTPProtocolServer {

async fn test_target(&self, target: Target) -> Result<(), TargetTestError> {
let TargetOptions::Http(options) = target.options else {
return Err(TargetTestError::Misconfigured("Not an HTTP target".to_owned()));
return Err(TargetTestError::Misconfigured(
"Not an HTTP target".to_owned(),
));
};
let request = poem::Request::builder().uri_str("http://host/").finish();
crate::proxy::proxy_normal_request(&request, poem::Body::empty(), &options)
Expand Down
41 changes: 23 additions & 18 deletions warpgate-protocol-http/src/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,8 @@ use crate::session_handle::WarpgateServerHandleFromRequest;

pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
let handle = WarpgateServerHandleFromRequest::from_request_without_body(req).await;
let services: Data<&Services> = <_>::from_request_without_body(req).await?;
let config = services.config.lock().await;

let remote_ip = req
.remote_addr()
.as_socket_addr()
.map(|x| x.ip().to_string())
.unwrap_or("<unknown>".into());

let client_ip = match config.store.http.trust_x_forwarded_headers {
true => req
.header("x-forwarded-for")
.map(|x| x.to_string())
.unwrap_or(remote_ip),
false => remote_ip,
};
let client_ip = get_client_ip(req).await?;

Ok(match handle {
Ok(ref handle) => {
Expand All @@ -40,10 +26,29 @@ pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
})
}

pub fn log_request_result(method: &Method, url: &Uri, status: &StatusCode) {
pub fn log_request_result(method: &Method, url: &Uri, client_ip: String, status: &StatusCode) {
if status.is_server_error() || status.is_client_error() {
warn!(%method, %url, %status, "Request failed");
warn!(%method, %url, %status, %client_ip, "Request failed");
} else {
info!(%method, %url, %status, "Request");
info!(%method, %url, %status, %client_ip, "Request");
}
}

pub async fn get_client_ip(req: &Request) -> poem::Result<String> {
let services: Data<&Services> = <_>::from_request_without_body(&req).await?;
let config = services.config.lock().await;

let remote_ip = req
.remote_addr()
.as_socket_addr()
.map(|x| x.ip().to_string())
.unwrap_or("<unknown>".into());

match config.store.http.trust_x_forwarded_headers {
true => Ok(req
.header("x-forwarded-for")
.map(|x| x.to_string())
.unwrap_or(remote_ip)),
false => Ok(remote_ip),
}
}
9 changes: 7 additions & 2 deletions warpgate-protocol-http/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use url::Url;
use warpgate_common::{try_block, TargetHTTPOptions, TlsMode, WarpgateError};
use warpgate_web::lookup_built_file;

use crate::logging::log_request_result;
use crate::logging::{get_client_ip, log_request_result};

trait SomeResponse {
fn status(&self) -> http::StatusCode;
Expand Down Expand Up @@ -291,7 +291,12 @@ pub async fn proxy_normal_request(
copy_client_response(&client_response, &mut response);
copy_client_body(client_response, &mut response).await?;

log_request_result(req.method(), req.original_uri(), &status);
log_request_result(
req.method(),
req.original_uri(),
get_client_ip(req).await?,
&status,
);

rewrite_response(&mut response, options, &uri)?;
Ok(response)
Expand Down
Loading