@@ -33,11 +33,10 @@ pub static CLIENT: LazyLock<WreqClient> = LazyLock::new(build_client);
3333
3434/// A separate wreq client used only for media proxying (images, videos, HLS).
3535/// Unlike CLIENT (which uses Policy::none() + browser emulation for the Reddit
36- /// OAuth API), this client:
37- /// - follows redirects (Policy::limited(10)) so CDN 302s are resolved server-side
38- /// - has NO browser emulation — Reddit's image CDN (i.redd.it, preview.redd.it)
39- /// detects BoringSSL/Chrome fingerprints and serves its HTML website instead
40- /// of the image bytes. A plain TLS client gets the actual image.
36+ /// OAuth API), this client follows redirects (Policy::limited(10)) and has no
37+ /// browser emulation. Reddit's image CDN (i.redd.it, preview.redd.it) detects
38+ /// BoringSSL/Chrome fingerprints and serves its HTML website instead of the
39+ /// image bytes; a plain TLS client gets the actual image.
4140pub static MEDIA_CLIENT : LazyLock < WreqClient > = LazyLock :: new ( || {
4241 WreqClient :: builder ( )
4342 . redirect ( Policy :: limited ( 10 ) )
@@ -96,7 +95,7 @@ trait IntoHyperResponse {
9695
9796impl IntoHyperResponse for wreq:: Response {
9897 async fn into_hyper ( self ) -> Result < Response < Body > , String > {
99- // wreq uses http v1.x, hyper uses http v0.2.x — convert via primitives
98+ // wreq uses http v1.x; hyper uses http v0.2.x. Convert via primitives.
10099 let status_u16 = self . status ( ) . as_u16 ( ) ;
101100 let status = hyper:: StatusCode :: from_u16 ( status_u16) . map_err ( |e| e. to_string ( ) ) ?;
102101
@@ -166,7 +165,6 @@ pub async fn canonical_path(path: String, tries: i8) -> Result<Option<String>, S
166165
167166 let res = res. ok_or_else ( || "Unable to make HEAD request to Reddit." . to_string ( ) ) ?;
168167 let status = res. status ( ) . as_u16 ( ) ;
169- // Use string literals: wreq uses http v1.x, hyper::header constants are http v0.2
170168 let policy_error = res. headers ( ) . get ( "retry-after" ) . is_some ( ) ;
171169
172170 match status {
@@ -217,12 +215,12 @@ pub async fn proxy(req: hyper::Request<Body>, format: &str) -> Result<Response<B
217215}
218216
219217async fn stream ( url : & str , req : & hyper:: Request < Body > ) -> Result < Response < Body > , String > {
220- // Use MEDIA_CLIENT ( Policy::limited(10)) so CDN 302 redirects are followed
221- // server-side. CLIENT uses Policy::none() for Reddit API redirect handling .
218+ // MEDIA_CLIENT follows CDN redirects; CLIENT keeps Policy::none() for the
219+ // Reddit API redirect logic in request() .
222220 let mut builder = MEDIA_CLIENT . get ( url) ;
223221
224- // Copy useful headers from original request
225- // Convert hyper header values (http v0.2) to bytes for wreq (http v1.x)
222+ // Forward caching/range headers from the browser request. hyper header
223+ // values (http v0.2) are passed as bytes so wreq (http v1.x) accepts them.
226224 for & key in & [ "Range" , "If-Modified-Since" , "Cache-Control" ] {
227225 if let Some ( value) = req. headers ( ) . get ( key) {
228226 builder = builder. header ( key, value. as_bytes ( ) ) ;
@@ -235,10 +233,7 @@ async fn stream(url: &str, req: &hyper::Request<Body>) -> Result<Response<Body>,
235233 builder = builder. header ( "User-Agent" , client. user_agent ( ) ) ;
236234 }
237235
238- let resp = builder. send ( ) . await . map_err ( |e| e. to_string ( ) ) ?;
239-
240- let status = resp. status ( ) ;
241- let mut hyper_resp = resp. into_hyper ( ) . await ?;
236+ let mut hyper_resp = builder. send ( ) . await . map_err ( |e| e. to_string ( ) ) ?. into_hyper ( ) . await ?;
242237
243238 // Strip tracking/CDN headers
244239 {
@@ -261,7 +256,6 @@ async fn stream(url: &str, req: &hyper::Request<Body>) -> Result<Response<Body>,
261256 }
262257 }
263258
264- let _ = status; // used implicitly via hyper_resp
265259 Ok ( hyper_resp)
266260}
267261
@@ -320,7 +314,8 @@ fn request(method: Method, path: String, redirect: bool, quarantine: bool, base_
320314 return resp. into_hyper ( ) . await ;
321315 }
322316
323- // Use string literal: wreq uses http v1.x, hyper::header constants are http v0.2
317+ // Use a string key: wreq (http v1.x) header names are not compatible
318+ // with hyper::header constants (http v0.2).
324319 let location = resp. headers ( ) . get ( "location" ) . map ( |v| v. to_str ( ) . unwrap_or_default ( ) . to_string ( ) ) ;
325320
326321 if location. as_deref ( ) == Some ( ALTERNATIVE_REDDIT_URL_BASE ) {
0 commit comments