Redirect after-pagination queries to the corresponding before-queries
This normalizes the URLs, avoiding duplicate URLs for a sublist
This commit is contained in:
parent
7a63fdca0e
commit
b3ffcb916b
4 changed files with 58 additions and 7 deletions
|
@ -11,16 +11,19 @@ use state::State;
|
|||
use web::{Resource, ResponseFuture};
|
||||
|
||||
use super::pagination::Pagination;
|
||||
use super::TemporaryRedirectResource;
|
||||
|
||||
const PAGE_SIZE: i32 = 30;
|
||||
|
||||
type BoxResource = Box<Resource + Sync + Send>;
|
||||
|
||||
pub struct ChangesResource {
|
||||
state: State,
|
||||
before: Option<i32>,
|
||||
}
|
||||
|
||||
impl ChangesResource {
|
||||
pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=ChangesResource, Error=::web::Error>> {
|
||||
pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=BoxResource, Error=::web::Error>> {
|
||||
match pagination {
|
||||
Pagination::After(x) => Box::new(
|
||||
state.query_article_revision_stubs(move |query| {
|
||||
|
@ -38,14 +41,14 @@ impl ChangesResource {
|
|||
None
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
state,
|
||||
before: extra_element.map(|x| x.sequence_number),
|
||||
Ok(match extra_element {
|
||||
Some(x) => Box::new(TemporaryRedirectResource::new(format!("?before={}", x.sequence_number))) as BoxResource,
|
||||
None => Box::new(TemporaryRedirectResource::new(format!("_changes"))) as BoxResource,
|
||||
})
|
||||
})
|
||||
),
|
||||
Pagination::Before(x) => Box::new(finished(Self { state, before: Some(x) })),
|
||||
Pagination::None => Box::new(finished(Self { state, before: None })),
|
||||
Pagination::Before(x) => Box::new(finished(Box::new(Self { state, before: Some(x) }) as BoxResource)),
|
||||
Pagination::None => Box::new(finished(Box::new(Self { state, before: None }) as BoxResource)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ mod article_resource;
|
|||
mod changes_resource;
|
||||
mod new_article_resource;
|
||||
mod sitemap_resource;
|
||||
mod temporary_redirect_resource;
|
||||
|
||||
pub use self::article_redirect_resource::ArticleRedirectResource;
|
||||
pub use self::article_resource::ArticleResource;
|
||||
pub use self::changes_resource::ChangesResource;
|
||||
pub use self::new_article_resource::NewArticleResource;
|
||||
pub use self::sitemap_resource::SitemapResource;
|
||||
pub use self::temporary_redirect_resource::TemporaryRedirectResource;
|
||||
|
|
46
src/resources/temporary_redirect_resource.rs
Normal file
46
src/resources/temporary_redirect_resource.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use futures::{self, Future};
|
||||
use hyper;
|
||||
use hyper::header::Location;
|
||||
use hyper::server::*;
|
||||
|
||||
use web::{Resource, ResponseFuture};
|
||||
|
||||
pub struct TemporaryRedirectResource {
|
||||
location: String,
|
||||
}
|
||||
|
||||
impl TemporaryRedirectResource {
|
||||
pub fn new(location: String) -> Self {
|
||||
Self { location }
|
||||
}
|
||||
}
|
||||
|
||||
impl Resource for TemporaryRedirectResource {
|
||||
fn allow(&self) -> Vec<hyper::Method> {
|
||||
use hyper::Method::*;
|
||||
vec![Options, Head, Get, Put, Post]
|
||||
}
|
||||
|
||||
fn head(&self) -> ResponseFuture {
|
||||
Box::new(futures::finished(Response::new()
|
||||
.with_status(hyper::StatusCode::TemporaryRedirect)
|
||||
.with_header(Location::new(self.location.clone()))
|
||||
))
|
||||
}
|
||||
|
||||
fn get(self: Box<Self>) -> ResponseFuture {
|
||||
Box::new(self.head()
|
||||
.and_then(move |head| {
|
||||
Ok(head
|
||||
.with_body(format!("Moved to {}", self.location)))
|
||||
}))
|
||||
}
|
||||
|
||||
fn put(self: Box<Self>, _body: hyper::Body, _identity: Option<String>) -> ResponseFuture {
|
||||
Box::new(self.head()
|
||||
.and_then(move |head| {
|
||||
Ok(head
|
||||
.with_body(format!("Moved to {}", self.location)))
|
||||
}))
|
||||
}
|
||||
}
|
|
@ -87,7 +87,7 @@ impl WikiLookup {
|
|||
Box::new(
|
||||
done(pagination::from_str(query.unwrap_or("")).map_err(Into::into))
|
||||
.and_then(move |pagination| ChangesResource::new(state, pagination))
|
||||
.and_then(|changes_resource| Ok(Some(Box::new(changes_resource) as BoxResource)))
|
||||
.and_then(|resource| Ok(Some(resource)))
|
||||
)
|
||||
},
|
||||
("_new", None) =>
|
||||
|
|
Loading…
Reference in a new issue