@@ -163,19 +163,42 @@ impl Handler for MainHandler {
163163            } 
164164        } 
165165
166-         // This is kind of a mess. 
166+         // Some versions of rustdoc in 2018 did not respect the shared static root 
167+         // (--static-root-path) and so emitted HTML that linked to shared static files via a local 
168+         // path. For instance, `<script src="../main-20181217-1.33.0-nightly-adbfec229.js">` instead 
169+         // of (correct) `<script src="/main-20181217-1.33.0-nightly-adbfec229.js">`. Since docs.rs 
170+         // removes the shared static files from individual builds to save space, the "../mainXXX.js" 
171+         // path doesn't really exist in storage for any particular build. The appropriate main file 
172+         // *does* exist in the storage root, which is where the shared static files are put for each 
173+         // new rustdoc version. So here we give SharedResourceHandler a chance to handle all URLs 
174+         // before they go to the router. SharedResourceHandler looks at the last component of the 
175+         // request path ("main-20181217-1.33.0-nightly-adbfec229.js") and tries to fetch it from 
176+         // the storage root (if it's JS, CSS, etc). If the file doesn't exist, we fall through to 
177+         // the normal router, which may wind up serving an invocation-specific file from the crate 
178+         // itself. For instance, a request for "/crate/foo/search-index-XYZ.js" will get a 404 from 
179+         // the SharedResourceHandler because "search-index-XYZ.js" doesn't exist in the storage root 
180+         // (it's not a shared static file), but it will get a 200 from rustdoc_html_server_handler 
181+         // because it exists in a specific crate. 
167182        // 
168-         // Almost all files should be served through the `router_handler`; eventually 
169-         // `shared_resource_handler` should go through the router too. 
183+         // See #1181. 
170184        // 
171-         // Unfortunately, combining `shared_resource_handler` with the `router_handler` breaks 
172-         // things, because right now `shared_resource_handler` allows requesting files from *any* 
173-         // subdirectory and the router requires us to give a specific path. Changing them to a 
174-         // specific path means that buggy docs from 2018 will have missing CSS (#1181) so until 
175-         // that's fixed, we need to keep the current (buggy) behavior. 
185+         // Note that this causes a counterintuitive and arguably buggy behavior: files that exist in 
186+         // the storage root can be requested with any path. For instance: 
176187        // 
177-         // It's important that `shared_resource_handler` comes first so that global rustdoc files take 
178-         // precedence over local ones (see #1327). 
188+         // https://docs.rs/this.path.does.not.exist/main-20181217-1.33.0-nightly-adbfec229.js 
189+         // 
190+         // If those 2018 crates get rebuilt, we won't have this problem anymore, and 
191+         // SharedResourceHandler can receive dispatch from the router, as other handlers do. That 
192+         // will also allow SharedResourceHandler to look up full paths in storage rather than just 
193+         // the last component of the requested path. 
194+         // 
195+         // Also note: this approach means that a request for a given JS/CSS may serve from two 
196+         // different places in storage: the storage root, or the full requested path. If the same 
197+         // filename exists in both places, we serve that filename from the storage root, because 
198+         // shared_resource_handler is called before the router. This works around a different bug 
199+         // that existed in certain versions of rustdoc around 2021, where an invocation specific 
200+         // file (cratesXXX.js) was referenced using the --static-root-path rather than the crate 
201+         // root. See #1340 and https://github.com/rust-lang/rust/pull/83094. 
179202        self . shared_resource_handler 
180203            . handle ( req) 
181204            . or_else ( |e| if_404 ( e,  || self . router_handler . handle ( req) ) ) 
0 commit comments