Compare commits

...
Author SHA1 Message Date
Brandon Thomas 27e911d46b don't serve bad traffic 2026-07-06 16:51:42 -04:00
Brandon Thomas 977cd933f7 another bad path 2026-07-06 16:49:30 -04:00
Brandon Thomas 89f20d9452 black hole these requests 2026-07-06 16:31:01 -04:00
2 changed files with 25 additions and 8 deletions
@@ -4,6 +4,7 @@ use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::common_responses::media::media_domain::MediaDomain;
use crate::http_server::common_responses::media::media_links_builder::MediaLinksBuilder;
use crate::http_server::endpoints::inference_job::utils::estimates::estimate_job_progress::estimate_job_progress;
use crate::http_server::endpoints::tts::enqueue_infer_tts_handler::enqueue_infer_tts_handler::SYNTHETIC_INFERENCE_JOB_TOKEN;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_lipsync_details::extract_lipsync_details;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_live_portrait_details::extract_live_portrait_details;
use crate::http_server::endpoints::inference_job::utils::extractors::extract_polymorphic_inference_args::extract_polymorphic_inference_args;
@@ -154,12 +155,9 @@ pub async fn get_inference_job_status_handler(
path: Path<GetInferenceJobStatusPathInfo>,
server_state: web::Data<Arc<ServerState>>,
) -> Result<Json<GetInferenceJobStatusSuccessResponse>, CommonWebError> {
if path.token.as_str().trim() == "None" {
// NB: A bunch of Python clients use our API and can fail in this manner.
// This was a large traffic driver during the 2023-03-08 outage.
// Presumably, it's this client: https://github.com/shards-7/fakeyou.py
return Err(CommonWebError::NotFound);
}
// Don't serve bad traffic
blackhole_jobs(&path.token)?;
// NB: Since this is publicly exposed, we don't query sensitive data.
let maybe_status = get_inference_job_status(
@@ -233,6 +231,24 @@ pub async fn get_inference_job_status_handler(
}))
}
/// Reject junk job tokens that abusive or broken clients poll in high volume, before they reach
/// MySQL or Redis. Deliberately not logged — the whole point is to make these requests as cheap
/// as possible.
fn blackhole_jobs(token: &InferenceJobToken) -> Result<(), CommonWebError> {
match token.as_str().trim() {
// NB: The shut-down legacy TTS enqueue endpoint hands this sentinel token to old clients,
// and some of them poll it forever.
SYNTHETIC_INFERENCE_JOB_TOKEN => Err(CommonWebError::TooManyRequests),
// NB: A bunch of Python clients use our API and can fail in this manner.
// This was a large traffic driver during the 2023-03-08 outage.
// Presumably, it's this client: https://github.com/shards-7/fakeyou.py
"None" => Err(CommonWebError::NotFound),
// NB: Broken Javascript clients poll with a stringified `undefined` token.
"undefined" => Err(CommonWebError::NotFound),
_ => Ok(()),
}
}
fn record_to_payload(
record: GenericInferenceJobStatus,
maybe_extra_status_description: Option<String>,
@@ -2,8 +2,9 @@ use actix_web::web::Json;
use utoipa::ToSchema;
/// Sentinel job token returned to legacy clients now that TTS inference is shut down.
/// There is no real job behind it; status polls for it will never complete.
const SYNTHETIC_INFERENCE_JOB_TOKEN: &str = "synthetic_too_many_requests";
/// There is no real job behind it; status polls for it are rejected with a 429 before
/// touching the database (see `get_inference_job_status_handler`).
pub const SYNTHETIC_INFERENCE_JOB_TOKEN: &str = "synthetic_too_many_requests";
#[derive(Serialize, ToSchema)]
pub struct InferTtsSuccessResponse {