Skip to content

Commit 4e89e30

Browse files
committed
Return errors with a long TTL for invalid requests
To mitigate the hammering of crawlers such as the Facebook mad crawler.
1 parent 6b5977c commit 4e89e30

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

src/libdoh/src/lib.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ fn http_error(status_code: StatusCode) -> Result<Response<Body>, http::Error> {
7777
Ok(response)
7878
}
7979

80+
#[allow(clippy::unnecessary_wraps)]
81+
fn http_error_with_cache(status_code: StatusCode) -> Result<Response<Body>, http::Error> {
82+
// Return error with very long cache time (1 year) to prevent crawler bots from retrying
83+
let response = Response::builder()
84+
.status(status_code)
85+
.header(
86+
hyper::header::CACHE_CONTROL,
87+
"max-age=31536000, immutable"
88+
)
89+
.body(Body::empty())
90+
.unwrap();
91+
Ok(response)
92+
}
93+
8094
#[derive(Clone, Debug)]
8195
pub struct LocalExecutor {
8296
runtime_handle: runtime::Handle,
@@ -198,7 +212,7 @@ impl DoH {
198212

199213
let query = match self.query_from_query_string(req) {
200214
Some(query) => query,
201-
_ => return http_error(StatusCode::BAD_REQUEST),
215+
_ => return http_error_with_cache(StatusCode::BAD_REQUEST),
202216
};
203217
self.serve_doh_query(query, client_ip).await
204218
}
@@ -245,7 +259,7 @@ impl DoH {
245259
async fn serve_odoh_get(&self, req: Request<Body>) -> Result<Response<Body>, http::Error> {
246260
let encrypted_query = match self.query_from_query_string(req) {
247261
Some(encrypted_query) => encrypted_query,
248-
_ => return http_error(StatusCode::BAD_REQUEST),
262+
_ => return http_error_with_cache(StatusCode::BAD_REQUEST),
249263
};
250264
self.serve_odoh(encrypted_query).await
251265
}
@@ -420,8 +434,13 @@ impl DoH {
420434
Self::acceptable_content_type(headers, &[CT_DOH, CT_ODOH, CT_JSON]);
421435
match acceptable_content_type {
422436
None => {
437+
// Return NOT_ACCEPTABLE with long cache time for crawler bots
423438
let response = Response::builder()
424439
.status(StatusCode::NOT_ACCEPTABLE)
440+
.header(
441+
hyper::header::CACHE_CONTROL,
442+
"max-age=31536000, immutable"
443+
)
425444
.body(Body::empty())
426445
.unwrap();
427446
return Err(response);
@@ -431,8 +450,13 @@ impl DoH {
431450
}
432451
Some(content_type) => match content_type.to_str() {
433452
Err(_) => {
453+
// Return BAD_REQUEST with long cache time for invalid content type
434454
let response = Response::builder()
435455
.status(StatusCode::BAD_REQUEST)
456+
.header(
457+
hyper::header::CACHE_CONTROL,
458+
"max-age=31536000, immutable"
459+
)
436460
.body(Body::empty())
437461
.unwrap();
438462
return Err(response);
@@ -446,8 +470,13 @@ impl DoH {
446470
CT_ODOH => Ok(DoHType::Oblivious),
447471
CT_JSON => Ok(DoHType::Json),
448472
_ => {
473+
// Return UNSUPPORTED_MEDIA_TYPE with long cache time
449474
let response = Response::builder()
450475
.status(StatusCode::UNSUPPORTED_MEDIA_TYPE)
476+
.header(
477+
hyper::header::CACHE_CONTROL,
478+
"max-age=31536000, immutable"
479+
)
451480
.body(Body::empty())
452481
.unwrap();
453482
Err(response)

0 commit comments

Comments
 (0)