@@ -13,7 +13,6 @@ use crate::{
13
13
encode_url_path,
14
14
error:: { AxumNope , AxumResult } ,
15
15
file:: File ,
16
- headers:: CanonicalUrl ,
17
16
match_version_axum,
18
17
metrics:: RenderingTimesRecorder ,
19
18
page:: TemplateData ,
@@ -25,8 +24,7 @@ use anyhow::{anyhow, Context as _};
25
24
use axum:: {
26
25
extract:: { Extension , Path , Query } ,
27
26
http:: { StatusCode , Uri } ,
28
- response:: { Html , IntoResponse , Response as AxumResponse } ,
29
- TypedHeader ,
27
+ response:: { AppendHeaders , Html , IntoResponse , Response as AxumResponse } ,
30
28
} ;
31
29
use lol_html:: errors:: RewritingError ;
32
30
use once_cell:: sync:: Lazy ;
@@ -289,7 +287,6 @@ pub(crate) async fn rustdoc_redirector_handler(
289
287
#[ derive( Debug , Clone , Serialize ) ]
290
288
struct RustdocPage {
291
289
latest_path : String ,
292
- canonical_url : CanonicalUrl ,
293
290
permalink_path : String ,
294
291
latest_version : String ,
295
292
target : String ,
@@ -315,7 +312,6 @@ impl RustdocPage {
315
312
file_path : & str ,
316
313
) -> AxumResult < AxumResponse > {
317
314
let is_latest_url = self . is_latest_url ;
318
- let canonical_url = self . canonical_url . clone ( ) ;
319
315
320
316
// Build the page of documentation
321
317
let ctx = tera:: Context :: from_serialize ( self ) . context ( "error creating tera context" ) ?;
@@ -336,9 +332,10 @@ impl RustdocPage {
336
332
result => result. context ( "error rewriting HTML" ) ?,
337
333
} ;
338
334
335
+ let robots = if is_latest_url { "" } else { "noindex" } ;
339
336
Ok ( (
340
337
StatusCode :: OK ,
341
- TypedHeader ( canonical_url ) ,
338
+ AppendHeaders ( [ ( "X-Robots-Tag" , robots ) ] ) ,
342
339
Extension ( if is_latest_url {
343
340
CachePolicy :: ForeverInCdn
344
341
} else {
@@ -640,18 +637,6 @@ pub(crate) async fn rustdoc_html_server_handler(
640
637
params. name, target_redirect, query_string
641
638
) ;
642
639
643
- // Set the canonical URL for search engines to the `/latest/` page on docs.rs.
644
- // Note: The URL this points to may not exist. For instance, if we're rendering
645
- // `struct Foo` in version 0.1.0 of a crate, and version 0.2.0 of that crate removes
646
- // `struct Foo`, this will point at a 404. That's fine: search engines will crawl
647
- // the target and will not canonicalize to a URL that doesn't exist.
648
- // Don't include index.html in the canonical URL.
649
- let canonical_url = CanonicalUrl :: from_path ( format ! (
650
- "/{}/latest/{}" ,
651
- params. name,
652
- inner_path. replace( "index.html" , "" ) ,
653
- ) ) ;
654
-
655
640
metrics
656
641
. recently_accessed_releases
657
642
. record ( krate. crate_id , krate. release_id , target) ;
@@ -671,7 +656,6 @@ pub(crate) async fn rustdoc_html_server_handler(
671
656
move || {
672
657
Ok ( RustdocPage {
673
658
latest_path,
674
- canonical_url,
675
659
permalink_path,
676
660
latest_version,
677
661
target,
@@ -2394,90 +2378,35 @@ mod test {
2394
2378
}
2395
2379
2396
2380
#[ test]
2397
- fn canonical_url ( ) {
2381
+ fn noindex_nonlatest ( ) {
2398
2382
wrapper ( |env| {
2399
2383
env. fake_release ( )
2400
- . name ( "dummy-dash" )
2401
- . version ( "0.1.0" )
2402
- . documentation_url ( Some ( "http://example.com" . to_string ( ) ) )
2403
- . rustdoc_file ( "dummy_dash/index.html" )
2404
- . create ( ) ?;
2405
-
2406
- let utf8_filename = "序.html" ;
2407
- env. fake_release ( )
2408
- . name ( "dummy-docs" )
2409
- . version ( "0.1.0" )
2410
- . documentation_url ( Some ( "https://docs.rs/foo" . to_string ( ) ) )
2411
- . rustdoc_file ( "dummy_docs/index.html" )
2412
- . rustdoc_file ( & format ! ( "dummy_docs/{utf8_filename}" ) )
2413
- . create ( ) ?;
2414
-
2415
- env. fake_release ( )
2416
- . name ( "dummy-nodocs" )
2384
+ . name ( "dummy" )
2417
2385
. version ( "0.1.0" )
2418
- . documentation_url ( None )
2419
- . rustdoc_file ( "dummy_nodocs/index.html" )
2420
- . rustdoc_file ( "dummy_nodocs/struct.Foo.html" )
2386
+ . rustdoc_file ( "dummy/index.html" )
2421
2387
. create ( ) ?;
2422
2388
2423
2389
let web = env. frontend ( ) ;
2424
2390
2425
2391
assert ! ( web
2426
- . get( "/dummy-dash /0.1.0/dummy_dash /" )
2392
+ . get( "/dummy/0.1.0/dummy /" )
2427
2393
. send( ) ?
2428
2394
. headers( )
2429
- . get( "link " )
2395
+ . get( "x-robots-tag " )
2430
2396
. unwrap( )
2431
2397
. to_str( )
2432
2398
. unwrap( )
2433
- . contains( "rel= \" canonical \" " ) , ) ;
2399
+ . contains( "noindex" ) ) ;
2434
2400
2435
- assert_eq ! (
2436
- web. get( "/dummy-docs/0.1.0/dummy_docs/" )
2437
- . send( ) ?
2438
- . headers( )
2439
- . get( "link" )
2440
- . unwrap( )
2441
- . to_str( )
2442
- . unwrap( ) ,
2443
- "<https://docs.rs/dummy-docs/latest/dummy_docs/>; rel=\" canonical\" "
2444
- ) ;
2445
-
2446
- assert_eq ! (
2447
- web. get( & format!( "/dummy-docs/0.1.0/dummy_docs/{utf8_filename}" ) )
2448
- . send( ) ?
2449
- . headers( )
2450
- . get( "link" )
2451
- . unwrap( )
2452
- . to_str( )
2453
- . unwrap( ) ,
2454
- "<https://docs.rs/dummy-docs/latest/dummy_docs/%E5%BA%8F.html>; rel=\" canonical\" " ,
2455
- ) ;
2456
-
2457
- assert ! ( web
2458
- . get( "/dummy-nodocs/0.1.0/dummy_nodocs/" )
2401
+ assert ! ( !web
2402
+ . get( "/dummy/latest/dummy/" )
2459
2403
. send( ) ?
2460
2404
. headers( )
2461
- . get( "link " )
2405
+ . get( "x-robots-tag " )
2462
2406
. unwrap( )
2463
2407
. to_str( )
2464
2408
. unwrap( )
2465
- . contains(
2466
- "<https://docs.rs/dummy-nodocs/latest/dummy_nodocs/>; rel=\" canonical\" "
2467
- ) , ) ;
2468
-
2469
- assert_eq ! (
2470
- web
2471
- . get( "/dummy-nodocs/0.1.0/dummy_nodocs/struct.Foo.html" )
2472
- . send( ) ?
2473
- . headers( )
2474
- . get( "link" )
2475
- . unwrap( )
2476
- . to_str( )
2477
- . unwrap( ) ,
2478
- "<https://docs.rs/dummy-nodocs/latest/dummy_nodocs/struct.Foo.html>; rel=\" canonical\" " ,
2479
- ) ;
2480
-
2409
+ . contains( "noindex" ) ) ;
2481
2410
Ok ( ( ) )
2482
2411
} )
2483
2412
}
0 commit comments