Skip to content

Commit dd4f2c5

Browse files
committedApr 12, 2025··
less individual selects
1 parent 8ab0688 commit dd4f2c5

File tree

4 files changed

+40
-16
lines changed

4 files changed

+40
-16
lines changed
 

‎src/main.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use colored::Colorize;
2020
use sentry_tower::SentryHttpLayer;
2121
use serde_json::json;
2222
use sha1::Digest;
23-
use std::{sync::Arc, time::Instant};
23+
use std::{net::IpAddr, sync::Arc, time::Instant};
2424
use tokio::sync::RwLock;
2525
use tower::Layer;
2626
use tower_http::{
@@ -51,12 +51,9 @@ fn handle_panic(_err: Box<dyn std::any::Any + Send + 'static>) -> Response<Body>
5151
}
5252

5353
fn handle_request(req: &Request<Body>, _span: &tracing::Span) {
54-
let ip = req
55-
.headers()
56-
.get("x-real-ip")
57-
.or_else(|| req.headers().get("x-forwarded-for"))
58-
.map(|ip| ip.to_str().unwrap_or_default())
59-
.unwrap_or_default();
54+
let ip = extract_ip(req.headers())
55+
.map(|ip| ip.to_string())
56+
.unwrap_or_else(|| "unknown".to_string());
6057

6158
logger::log(
6259
logger::LoggerLevel::Info,
@@ -105,6 +102,27 @@ async fn handle_etag(req: Request, next: Next) -> Result<Response, StatusCode> {
105102
Ok(Response::from_parts(parts, Body::from(body_bytes)))
106103
}
107104

105+
#[inline]
106+
pub fn extract_ip(headers: &HeaderMap) -> Option<IpAddr> {
107+
let ip = headers
108+
.get("x-real-ip")
109+
.or_else(|| headers.get("x-forwarded-for"))
110+
.map(|ip| ip.to_str().unwrap_or_default())
111+
.unwrap_or_default();
112+
113+
if ip.is_empty() {
114+
return None;
115+
}
116+
117+
let ip = if ip.contains(',') {
118+
ip.split(',').next().unwrap_or_default().trim().to_string()
119+
} else {
120+
ip.to_string()
121+
};
122+
123+
ip.parse().ok()
124+
}
125+
108126
#[tokio::main]
109127
async fn main() {
110128
let env = env::Env::parse();

‎src/models/extension.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ impl BaseModel for Extension {
8989
format!("{}banner", prefix.unwrap_or_default()),
9090
),
9191
(
92-
format!(
93-
"(SELECT stats FROM mv_extension_stats WHERE mv_extension_stats.id = {}.id)",
94-
table
95-
),
92+
"mv_extension_stats.stats".to_string(),
9693
format!("{}stats", prefix.unwrap_or_default()),
9794
),
9895
(
@@ -135,6 +132,7 @@ impl Extension {
135132
SELECT {}
136133
FROM extensions
137134
JOIN authors ON extensions.author_id = authors.id
135+
LEFT JOIN mv_extension_stats ON extensions.id = mv_extension_stats.id
138136
WHERE
139137
NOT pending
140138
AND NOT hidden
@@ -160,6 +158,7 @@ impl Extension {
160158
SELECT {}
161159
FROM extensions
162160
JOIN authors ON extensions.author_id = authors.id
161+
LEFT JOIN mv_extension_stats ON extensions.id = mv_extension_stats.id
163162
WHERE
164163
extensions.identifier = $1
165164
AND NOT extensions.pending
@@ -181,6 +180,7 @@ impl Extension {
181180
SELECT {}
182181
FROM extensions
183182
JOIN authors ON extensions.author_id = authors.id
183+
LEFT JOIN mv_extension_stats ON extensions.id = mv_extension_stats.id
184184
WHERE
185185
extensions.id = $1
186186
AND NOT extensions.pending

‎src/routes/telemetry.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@ pub fn router(state: &State) -> OpenApiRouter<State> {
1313
"/",
1414
post(
1515
|state: GetState, headers: HeaderMap, axum::Json::<TelemetryData>(data)| async move {
16-
let ip = headers.get("x-real-ip")
17-
.or_else(|| headers.get("x-forwarded-for"))
18-
.map(|ip| ip.to_str().unwrap_or_default())
19-
.unwrap_or_default();
16+
let ip = match crate::extract_ip(&headers) {
17+
Some(ip) => ip,
18+
None => {
19+
return (
20+
StatusCode::BAD_REQUEST,
21+
axum::Json(ApiError::new(&["invalid ip"]).to_value()),
22+
);
23+
}
24+
};
2025

2126
let telemetry = state.telemetry.log(ip, data).await;
2227
if telemetry.is_none() {

‎src/telemetry.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use sha2::Digest;
66
use sqlx::types::Uuid;
77
use std::{
88
collections::{HashMap, HashSet},
9+
net::IpAddr,
910
sync::Arc,
1011
};
1112
use tokio::sync::Mutex;
@@ -98,7 +99,7 @@ impl TelemetryLogger {
9899
}
99100

100101
#[inline]
101-
pub async fn log(&self, ip: &str, telemetry: TelemetryData) -> Option<()> {
102+
pub async fn log(&self, ip: IpAddr, telemetry: TelemetryData) -> Option<()> {
102103
let mut processing = self.processing.lock().await;
103104

104105
let ratelimit_key = format!("blueprint_api::ratelimit::{}", ip);

0 commit comments

Comments
 (0)
Please sign in to comment.