Skip to content
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
2 changes: 1 addition & 1 deletion src/middleware.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod authentication_middleware;
pub mod http_request_middleware;
pub mod http_transaction_middleware;
66 changes: 0 additions & 66 deletions src/middleware/http_request_middleware.rs

This file was deleted.

105 changes: 105 additions & 0 deletions src/middleware/http_transaction_middleware.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use std::{net::SocketAddr, sync::Arc};
use axum::{body::Body, extract::{ConnectInfo, Request, State}, middleware::Next, response::{IntoResponse, Response}};
use chrono::{Duration, Utc};
use rust_decimal::prelude::ToPrimitive;
use crate::{AppState, HTTPError, resources::{ResourceError, http_transaction::{EditableHTTPTransactionProperties, HTTPTransaction, InitialHTTPTransactionProperties}, server_log_entry::ServerLogEntry}, utilities::route_handler_utilities::get_configuration_by_name};

pub async fn create_http_transaction(
ConnectInfo(address): ConnectInfo<SocketAddr>,
State(state): State<AppState>,
mut request: Request<Body>,
next: Next
) -> Result<Response, HTTPError> {

// Remove sensitive headers from the stored request.
let client_ip = address.ip();
let method = request.method().to_string();
let url = request.uri().to_string();
let mut safe_headers = request.headers().clone();
safe_headers.remove("authorization");
safe_headers.remove("cookie");
let headers_json_string: serde_json::Value = format!("{:?}", safe_headers).into();

// Create the HTTP request and add it to the request extension.
let mut http_transaction = match HTTPTransaction::create(&InitialHTTPTransactionProperties {
method,
url,
ip_address: client_ip,
headers: headers_json_string.to_string(),
status_code: None,
expiration_timestamp: None
}, &state.database_pool).await {

Ok(http_transaction) => Arc::new(http_transaction),

Err(error) => {

let http_error = match error {

ResourceError::PostgresError(postgres_error) => {

match postgres_error.as_db_error() {

Some(db_error) => HTTPError::InternalServerError(Some(format!("{:?}", db_error))),

None => HTTPError::InternalServerError(Some(format!("{:?}", postgres_error)))

}

},

_ => HTTPError::InternalServerError(Some(error.to_string()))

};
ServerLogEntry::from_http_error(&http_error, None, &state.database_pool).await.ok();
return Err(http_error);

}

};

let should_http_transactions_expire_configuration = get_configuration_by_name("httpTransactions.shouldExpire", &http_transaction, &state.database_pool).await?;
let should_http_transactions_expire = should_http_transactions_expire_configuration.boolean_value.or(should_http_transactions_expire_configuration.default_boolean_value).unwrap_or(false);
if should_http_transactions_expire {

let expiration_duration_milliseconds = match should_http_transactions_expire_configuration.number_value
.or(should_http_transactions_expire_configuration.default_number_value)
.and_then(|decimal| decimal.to_i64())
{

Some(milliseconds) => Some(Duration::milliseconds(milliseconds)),

None => None

};

if let Some(duration) = expiration_duration_milliseconds {

http_transaction = match http_transaction.update(&EditableHTTPTransactionProperties {
expiration_timestamp: Some(Some(Utc::now() + duration)),
..Default::default()
}, &state.database_pool).await {

Ok(updated_http_transaction) => Arc::new(updated_http_transaction),

Err(error) => {

let http_error = HTTPError::InternalServerError(Some(format!("Failed to set HTTP transaction expiration timestamp: {:?}", error)));
ServerLogEntry::from_http_error(&http_error, Some(&http_transaction.id), &state.database_pool).await.ok();
return Err(http_error);

}

}

}

}

request.extensions_mut().insert(http_transaction.clone());

ServerLogEntry::info(&format!("HTTP request handling started."), Some(&http_transaction.id), &state.database_pool).await.ok();
let response = next.run(request).await;
return Ok(response);

}
16 changes: 15 additions & 1 deletion src/predefinitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,21 @@ pub async fn initialize_predefined_configurations(database_pool: &deadpool_postg
value_type: ConfigurationValueType::Number,
default_number_value: Some(Decimal::from(256 as i64)),
..Default::default()
}
},
InitialConfigurationProperties {
name: "httpTransactions.shouldExpire".to_string(),
description: Some("Whether HTTP transactions should expire after a certain amount of time. If true, HTTP transactions will expire after the amount of time specified in the \"httpTransactions.defaultMaximumLifetimeMilliseconds\" configuration.".to_string()),
value_type: ConfigurationValueType::Boolean,
default_boolean_value: Some(true),
..Default::default()
},
InitialConfigurationProperties {
name: "httpTransactions.defaultMaximumLifetimeMilliseconds".to_string(),
description: Some("The default maximum lifetime of HTTP transactions in milliseconds. This configuration only has an effect if the \"httpTransactions.shouldExpire\" configuration is set to true.".to_string()),
value_type: ConfigurationValueType::Number,
default_number_value: Some(Decimal::from(31536000000 as i64)), // 365 days in milliseconds
..Default::default()
},
];

let mut configurations: Vec<Configuration> = Vec::new();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM http_transactions WHERE expiration_timestamp <= now();
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ CREATE TABLE IF NOT EXISTS http_transactions (
ip_address INET NOT NULL,
headers TEXT NOT NULL,
status_code INTEGER,
expiration_date TIMESTAMPTZ NOT NULL DEFAULT NOW() + INTERVAL '14 days' -- TODO: Make this configurable through server policies.
expiration_timestamp TIMESTAMPTZ
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ INSERT INTO http_transactions (
ip_address,
headers,
status_code,
expiration_date
expiration_timestamp
) VALUES (
$1,
$2,
Expand Down
Loading