in http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/Uri.scala [890:917]
private[http] def collapseDotSegments(path: Path): Path = {
import Path._
@tailrec def hasDotOrDotDotSegment(p: Path): Boolean = p match {
case Path.Empty => false
case Path.Segment(".", _) | Path.Segment("..", _) => true
case _ => hasDotOrDotDotSegment(p.tail)
}
// http://tools.ietf.org/html/rfc3986#section-5.2.4
@tailrec def process(input: Path, output: Path = Path.Empty): Path = {
input match {
case Path.Empty => output.reverse
case Segment("." | "..", Slash(tail)) => process(tail, output)
case Slash(Segment(".", tail)) => process(if (tail.isEmpty) Path./ else tail, output)
case Slash(Segment("..", tail)) => process(
input = if (tail.isEmpty) Path./ else tail,
output =
if (output.startsWithSegment)
if (output.tail.startsWithSlash) output.tail.tail else tail
else output)
case Segment("." | "..", tail) => process(tail, output)
case Slash(tail) => process(tail, Slash(output))
case Segment(string, tail) => process(tail, string :: output)
}
}
if (hasDotOrDotDotSegment(path))
if (path.startsWithSlash) process(path) else process(Slash(path)).tail
else path
}