@@ -109,7 +109,7 @@ use iron::{
109
109
} ;
110
110
use page:: TemplateData ;
111
111
use postgres:: Client ;
112
- use router:: NoRoute ;
112
+ use router:: { NoRoute , TrailingSlash } ;
113
113
use semver:: { Version , VersionReq } ;
114
114
use serde:: Serialize ;
115
115
use std:: { borrow:: Cow , fmt, net:: SocketAddr , sync:: Arc } ;
@@ -167,6 +167,18 @@ impl Handler for MainHandler {
167
167
}
168
168
}
169
169
170
+ fn pass_iron_errors_with_redirect ( e : IronError ) -> IronResult < Response > {
171
+ // in some cases the iron router will return a redirect as an `IronError`.
172
+ // Here we convert these into an `Ok(Response)`.
173
+ if e. error . downcast_ref :: < TrailingSlash > ( ) . is_some ( )
174
+ || e. response . status == Some ( status:: MovedPermanently )
175
+ {
176
+ Ok ( e. response )
177
+ } else {
178
+ Err ( e)
179
+ }
180
+ }
181
+
170
182
// This is kind of a mess.
171
183
//
172
184
// Almost all files should be served through the `router_handler`; eventually
@@ -183,6 +195,7 @@ impl Handler for MainHandler {
183
195
self . shared_resource_handler
184
196
. handle ( req)
185
197
. or_else ( |e| if_404 ( e, || self . router_handler . handle ( req) ) )
198
+ . or_else ( pass_iron_errors_with_redirect)
186
199
. or_else ( |e| {
187
200
let err = if let Some ( err) = e. error . downcast_ref :: < error:: Nope > ( ) {
188
201
* err
@@ -740,6 +753,20 @@ mod test {
740
753
} )
741
754
}
742
755
756
+ #[ test]
757
+ fn double_slash_does_redirect_and_remove_slash ( ) {
758
+ wrapper ( |env| {
759
+ env. fake_release ( )
760
+ . name ( "bat" )
761
+ . version ( "0.2.0" )
762
+ . create ( )
763
+ . unwrap ( ) ;
764
+ let web = env. frontend ( ) ;
765
+ assert_redirect ( "/bat//" , "/bat/0.2.0/bat/" , web) ?;
766
+ Ok ( ( ) )
767
+ } )
768
+ }
769
+
743
770
#[ test]
744
771
fn binary_docs_redirect_to_crate ( ) {
745
772
wrapper ( |env| {
0 commit comments