mirror of
https://github.com/agersant/polaris
synced 2025-03-02 06:17:10 +00:00
Fixed a bug where names with square brackets tripped routing
This commit is contained in:
parent
5d0ead96e4
commit
84507e4d86
4 changed files with 50 additions and 29 deletions
|
@ -430,7 +430,7 @@ fn browse(request: &mut Request, db: &DB) -> IronResult<Response> {
|
|||
Err(e) => return Err(IronError::new(e, status::BadRequest)),
|
||||
Ok(p) => p,
|
||||
};
|
||||
let browse_result = index::browse(db, &path)?;
|
||||
let browse_result = index::browse(db, path)?;
|
||||
|
||||
let result_json = serde_json::to_string(&browse_result);
|
||||
let result_json = match result_json {
|
||||
|
@ -504,7 +504,7 @@ fn serve(request: &mut Request, db: &DB) -> IronResult<Response> {
|
|||
};
|
||||
|
||||
let vfs = db.get_vfs()?;
|
||||
let real_path = vfs.virtual_to_real(&virtual_path);
|
||||
let real_path = vfs.virtual_to_real(virtual_path);
|
||||
let real_path = match real_path {
|
||||
Err(e) => return Err(IronError::new(e, status::NotFound)),
|
||||
Ok(p) => p,
|
||||
|
|
10
src/index.rs
10
src/index.rs
|
@ -537,15 +537,16 @@ fn virtualize_directory(vfs: &VFS, mut directory: Directory) -> Option<Directory
|
|||
Some(directory)
|
||||
}
|
||||
|
||||
pub fn browse<T>(db: &T, virtual_path: &Path) -> Result<Vec<CollectionFile>, errors::Error>
|
||||
pub fn browse<T, P>(db: &T, virtual_path: P) -> Result<Vec<CollectionFile>, errors::Error>
|
||||
where
|
||||
T: ConnectionSource + VFSSource,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let mut output = Vec::new();
|
||||
let vfs = db.get_vfs()?;
|
||||
let connection = db.get_connection();
|
||||
|
||||
if virtual_path.components().count() == 0 {
|
||||
if virtual_path.as_ref().components().count() == 0 {
|
||||
// Browse top-level
|
||||
let real_directories: Vec<Directory> = directories::table
|
||||
.filter(directories::parent.is_null())
|
||||
|
@ -581,15 +582,16 @@ where
|
|||
Ok(output)
|
||||
}
|
||||
|
||||
pub fn flatten<T>(db: &T, virtual_path: &Path) -> Result<Vec<Song>, errors::Error>
|
||||
pub fn flatten<T, P>(db: &T, virtual_path: P) -> Result<Vec<Song>, errors::Error>
|
||||
where
|
||||
T: ConnectionSource + VFSSource,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
use self::songs::dsl::*;
|
||||
let vfs = db.get_vfs()?;
|
||||
let connection = db.get_connection();
|
||||
|
||||
let real_songs: Vec<Song> = if virtual_path.parent() != None {
|
||||
let real_songs: Vec<Song> = if virtual_path.as_ref().parent() != None {
|
||||
let real_path = vfs.virtual_to_real(virtual_path)?;
|
||||
let like_path = real_path.as_path().to_string_lossy().into_owned() + "%";
|
||||
songs
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rocket::http::{Cookie, Cookies, Status};
|
||||
use rocket::request::{self, FromRequest, Request};
|
||||
use rocket::http::{Cookie, Cookies, RawStr, Status};
|
||||
use rocket::request::{self, FromParam, FromRequest, Request};
|
||||
use rocket::{Outcome, State};
|
||||
use rocket_contrib::json::Json;
|
||||
use std::fs::File;
|
||||
|
@ -21,8 +21,6 @@ const CURRENT_MAJOR_VERSION: i32 = 2;
|
|||
const CURRENT_MINOR_VERSION: i32 = 2;
|
||||
const SESSION_FIELD_USERNAME: &str = "username";
|
||||
|
||||
// TODO every path.. argument breaks when the path contains square brackets. Needs URLencoding back!!
|
||||
|
||||
pub fn get_routes() -> Vec<rocket::Route> {
|
||||
routes![
|
||||
version,
|
||||
|
@ -85,6 +83,27 @@ impl<'a, 'r> FromRequest<'a, 'r> for AdminRights {
|
|||
}
|
||||
}
|
||||
|
||||
struct VFSPathBuf {
|
||||
path_buf: PathBuf,
|
||||
}
|
||||
|
||||
impl<'r> FromParam<'r> for VFSPathBuf {
|
||||
type Error = &'r RawStr;
|
||||
|
||||
fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
|
||||
let decoded_path = param.percent_decode_lossy();
|
||||
Ok(VFSPathBuf{
|
||||
path_buf: PathBuf::from(decoded_path.into_owned())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VFSPathBuf> for PathBuf {
|
||||
fn from(vfs_path_buf: VFSPathBuf) -> Self {
|
||||
vfs_path_buf.path_buf.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Version {
|
||||
major: i32,
|
||||
|
@ -172,65 +191,65 @@ fn browse_root(
|
|||
db: State<DB>,
|
||||
_auth: Auth,
|
||||
) -> Result<Json<Vec<index::CollectionFile>>, errors::Error> {
|
||||
let result = index::browse::<DB>(&db, &PathBuf::new())?;
|
||||
let result = index::browse(db.deref(), &PathBuf::new())?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/browse/<path..>")]
|
||||
#[get("/browse/<path>")]
|
||||
fn browse(
|
||||
db: State<DB>,
|
||||
_auth: Auth,
|
||||
path: PathBuf,
|
||||
path: VFSPathBuf,
|
||||
) -> Result<Json<Vec<index::CollectionFile>>, errors::Error> {
|
||||
let result = index::browse::<DB>(&db, &path)?;
|
||||
let result = index::browse(db.deref(), &path.into() as &PathBuf)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/flatten")]
|
||||
fn flatten_root(db: State<DB>, _auth: Auth) -> Result<Json<Vec<index::Song>>, errors::Error> {
|
||||
let result = index::flatten::<DB>(&db, &PathBuf::new())?;
|
||||
let result = index::flatten(db.deref(), &PathBuf::new())?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/flatten/<path..>")]
|
||||
#[get("/flatten/<path>")]
|
||||
fn flatten(
|
||||
db: State<DB>,
|
||||
_auth: Auth,
|
||||
path: PathBuf,
|
||||
path: VFSPathBuf,
|
||||
) -> Result<Json<Vec<index::Song>>, errors::Error> {
|
||||
let result = index::flatten::<DB>(&db, &path)?;
|
||||
let result = index::flatten(db.deref(), &path.into() as &PathBuf)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/random")]
|
||||
fn random(db: State<DB>, _auth: Auth) -> Result<Json<Vec<index::Directory>>, errors::Error> {
|
||||
let result = index::get_random_albums::<DB>(&db, 20)?;
|
||||
let result = index::get_random_albums(db.deref(), 20)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/recent")]
|
||||
fn recent(db: State<DB>, _auth: Auth) -> Result<Json<Vec<index::Directory>>, errors::Error> {
|
||||
let result = index::get_recent_albums::<DB>(&db, 20)?;
|
||||
let result = index::get_recent_albums(db.deref(), 20)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/search")]
|
||||
fn search_root(db: State<DB>, _auth: Auth) -> Result<Json<Vec<index::CollectionFile>>, errors::Error> {
|
||||
let result = index::search::<DB>(&db, "")?;
|
||||
let result = index::search(db.deref(), "")?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/search/<query>")]
|
||||
fn search(db: State<DB>, _auth: Auth, query: String) -> Result<Json<Vec<index::CollectionFile>>, errors::Error> {
|
||||
let result = index::search::<DB>(&db, &query)?;
|
||||
let result = index::search(db.deref(), &query)?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[get("/serve/<path..>")]
|
||||
fn serve(db: State<DB>, _auth: Auth, path: PathBuf) -> Result<serve::RangeResponder<File>, errors::Error> {
|
||||
#[get("/serve/<path>")]
|
||||
fn serve(db: State<DB>, _auth: Auth, path: VFSPathBuf) -> Result<serve::RangeResponder<File>, errors::Error> {
|
||||
let db: &DB = db.deref();
|
||||
let vfs = db.get_vfs()?;
|
||||
let real_path = vfs.virtual_to_real(&path)?;
|
||||
let real_path = vfs.virtual_to_real(&path.into() as &PathBuf)?;
|
||||
|
||||
let serve_path = if utils::is_image(&real_path) {
|
||||
thumbnails::get_thumbnail(&real_path, 400)?
|
||||
|
|
|
@ -51,9 +51,9 @@ impl VFS {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn real_to_virtual(&self, real_path: &Path) -> Result<PathBuf> {
|
||||
pub fn real_to_virtual<P: AsRef<Path>>(&self, real_path: P) -> Result<PathBuf> {
|
||||
for (name, target) in &self.mount_points {
|
||||
if let Ok(p) = real_path.strip_prefix(target) {
|
||||
if let Ok(p) = real_path.as_ref().strip_prefix(target) {
|
||||
let mount_path = Path::new(&name);
|
||||
return if p.components().count() == 0 {
|
||||
Ok(mount_path.to_path_buf())
|
||||
|
@ -65,10 +65,10 @@ impl VFS {
|
|||
bail!("Real path has no match in VFS")
|
||||
}
|
||||
|
||||
pub fn virtual_to_real(&self, virtual_path: &Path) -> Result<PathBuf> {
|
||||
pub fn virtual_to_real<P: AsRef<Path>>(&self, virtual_path: P) -> Result<PathBuf> {
|
||||
for (name, target) in &self.mount_points {
|
||||
let mount_path = Path::new(&name);
|
||||
if let Ok(p) = virtual_path.strip_prefix(mount_path) {
|
||||
if let Ok(p) = virtual_path.as_ref().strip_prefix(mount_path) {
|
||||
return if p.components().count() == 0 {
|
||||
Ok(target.clone())
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue