mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-04 10:29:34 +00:00
parent
e9cb3d2b42
commit
2c9e012c96
@ -50,7 +50,7 @@ object Contact {
|
||||
p match {
|
||||
case LenientUri.RootPath => false
|
||||
case LenientUri.EmptyPath => false
|
||||
case LenientUri.NonEmptyPath(segs) =>
|
||||
case LenientUri.NonEmptyPath(segs, _) =>
|
||||
Ident.fromString(segs.last).isRight &&
|
||||
segs.init.takeRight(3) == List("open", "upload", "item")
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ object LenientUri {
|
||||
val isRoot = true
|
||||
val isEmpty = false
|
||||
def /(seg: String): Path =
|
||||
NonEmptyPath(NonEmptyList.of(seg))
|
||||
NonEmptyPath(NonEmptyList.of(seg), false)
|
||||
def asString = "/"
|
||||
}
|
||||
case object EmptyPath extends Path {
|
||||
@ -129,20 +129,22 @@ object LenientUri {
|
||||
val isRoot = false
|
||||
val isEmpty = true
|
||||
def /(seg: String): Path =
|
||||
NonEmptyPath(NonEmptyList.of(seg))
|
||||
NonEmptyPath(NonEmptyList.of(seg), false)
|
||||
def asString = ""
|
||||
}
|
||||
case class NonEmptyPath(segs: NonEmptyList[String]) extends Path {
|
||||
case class NonEmptyPath(segs: NonEmptyList[String], trailingSlash: Boolean)
|
||||
extends Path {
|
||||
def segments = segs.toList
|
||||
val isEmpty = false
|
||||
val isRoot = false
|
||||
private val slashSuffix = if (trailingSlash) "/" else ""
|
||||
def /(seg: String): Path =
|
||||
copy(segs = segs.append(seg))
|
||||
def asString =
|
||||
segs.head match {
|
||||
case "." => segments.map(percentEncode).mkString("/")
|
||||
case ".." => segments.map(percentEncode).mkString("/")
|
||||
case _ => "/" + segments.map(percentEncode).mkString("/")
|
||||
case "." => segments.map(percentEncode).mkString("/") + slashSuffix
|
||||
case ".." => segments.map(percentEncode).mkString("/") + slashSuffix
|
||||
case _ => "/" + segments.map(percentEncode).mkString("/") + slashSuffix
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,14 +159,14 @@ object LenientUri {
|
||||
str.trim match {
|
||||
case "/" => Right(RootPath)
|
||||
case "" => Right(EmptyPath)
|
||||
case _ =>
|
||||
case uriStr =>
|
||||
Either.fromOption(
|
||||
stripLeading(str, '/')
|
||||
stripLeading(uriStr, '/')
|
||||
.split('/')
|
||||
.toList
|
||||
.traverse(percentDecode)
|
||||
.flatMap(NonEmptyList.fromList)
|
||||
.map(NonEmptyPath.apply),
|
||||
.map(NonEmptyPath(_, uriStr.endsWith("/"))),
|
||||
s"Invalid path: $str"
|
||||
)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ object UrlMatcher {
|
||||
// strip path to only match prefixes
|
||||
val mPath: LenientUri.Path =
|
||||
NonEmptyList.fromList(url.path.segments.take(pathSegmentCount)) match {
|
||||
case Some(nel) => LenientUri.NonEmptyPath(nel)
|
||||
case Some(nel) => LenientUri.NonEmptyPath(nel, false)
|
||||
case None => LenientUri.RootPath
|
||||
}
|
||||
|
||||
|
@ -29,4 +29,11 @@ class LenientUriTest extends FunSuite {
|
||||
)
|
||||
assertEquals(LenientUri.percentDecode("a%25b%5Cc%7Cd%23e"), "a%b\\c|d#e".some)
|
||||
}
|
||||
|
||||
test("parse with trailing slash") {
|
||||
assertEquals(LenientUri.unsafe("http://a.com/").asString, "http://a.com/")
|
||||
assertEquals(LenientUri.unsafe("http://a.com").asString, "http://a.com")
|
||||
assertEquals(LenientUri.unsafe("http://a.com/path").asString, "http://a.com/path")
|
||||
assertEquals(LenientUri.unsafe("http://a.com/path/").asString, "http://a.com/path/")
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ object FileUrlReader {
|
||||
scheme = Nel.of(scheme),
|
||||
authority = Some(""),
|
||||
path = LenientUri.NonEmptyPath(
|
||||
Nel.of(key.collective.id, key.category.id.id, key.id.id)
|
||||
Nel.of(key.collective.id, key.category.id.id, key.id.id),
|
||||
false
|
||||
),
|
||||
query = None,
|
||||
fragment = None
|
||||
|
Loading…
x
Reference in New Issue
Block a user