fix(oauth): catch network policy violation and rate limit (#233)

This commit is contained in:
Matthew Esposito 2024-09-16 16:16:08 -04:00 committed by GitHub
parent 408ebe6ef1
commit 0b15250cc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -4,6 +4,7 @@ use futures_lite::future::block_on;
use futures_lite::{future::Boxed, FutureExt}; use futures_lite::{future::Boxed, FutureExt};
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
use hyper::header::HeaderValue; use hyper::header::HeaderValue;
use hyper::StatusCode;
use hyper::{body, body::Buf, client, header, Body, Client, Method, Request, Response, Uri}; use hyper::{body, body::Buf, client, header, Body, Client, Method, Request, Response, Uri};
use hyper_rustls::HttpsConnector; use hyper_rustls::HttpsConnector;
use libflate::gzip; use libflate::gzip;
@ -60,10 +61,9 @@ pub static OAUTH_IS_ROLLING_OVER: AtomicBool = AtomicBool::new(false);
pub async fn canonical_path(path: String) -> Result<Option<String>, String> { pub async fn canonical_path(path: String) -> Result<Option<String>, String> {
let res = reddit_head(path.clone(), true).await?; let res = reddit_head(path.clone(), true).await?;
let status = res.status().as_u16(); let status = res.status().as_u16();
let policy_error = res.headers().get(header::RETRY_AFTER).is_some();
match status { match status {
429 => Err("Too many requests.".to_string()),
// If Reddit responds with a 2xx, then the path is already canonical. // If Reddit responds with a 2xx, then the path is already canonical.
200..=299 => Ok(Some(path)), 200..=299 => Ok(Some(path)),
@ -94,6 +94,12 @@ pub async fn canonical_path(path: String) -> Result<Option<String>, String> {
// as above), return a None. // as above), return a None.
300..=399 => Ok(None), 300..=399 => Ok(None),
// Rate limiting
429 => Err("Too many requests.".to_string()),
// Special condition rate limiting - https://github.com/redlib-org/redlib/issues/229
403 if policy_error => Err("Too many requests.".to_string()),
_ => Ok( _ => Ok(
res res
.headers() .headers()
@ -257,6 +263,12 @@ fn request(method: &'static Method, path: String, redirect: bool, quarantine: bo
.await; .await;
}; };
// Special condition rate limiting - https://github.com/redlib-org/redlib/issues/229
if response.status() == StatusCode::FORBIDDEN && response.headers().get("retry-after").unwrap_or(&HeaderValue::from_static("0")).to_str().unwrap_or("0") == "0" {
force_refresh_token().await;
return Err("Rate limit - try refreshing soon".to_string());
}
match response.headers().get(header::CONTENT_ENCODING) { match response.headers().get(header::CONTENT_ENCODING) {
// Content not compressed. // Content not compressed.
None => Ok(response), None => Ok(response),