未经过滤的URL解码

Nic*_*udo 2 scala unfiltered

我正在使用Unfiltered 0.6.8(使用Jetty连接器)并遇到了一个奇怪的行为:路径段不是URL解码的.

以下代码是我的最小测试用例:

import unfiltered.request._
import unfiltered.response._

object Test extends App with unfiltered.filter.Plan {
  def intent = {

    case reg @ Path(Seg(test :: Nil)) =>
      println(test)
      ResponseString(test)
  }

  unfiltered.jetty.Http.local(8080).filter(Test).run()
}
Run Code Online (Sandbox Code Playgroud)

查询http://localhost:8080/some_string产生预期结果:some_string,在客户端和服务器端.

另一方面,客户端和服务器上的http://localhost:8080/some%20string产量some%20string,而不是some string我期待的.

解决这个问题很简单(java.net.URLDecoder#decode(String, String)),但我想知道是否:

  • 我忘记了一些微不足道的事情并且自欺欺人.
  • 未经过滤的有一套工具可以自动处理麻烦.
  • 如果上述情况都不存在,是否存在此行为的特定原因,还是应该提交错误报告?

作为旁注,unfiltered标签不存在,我没有足够的声誉来创建它,这就是我违约的原因scala.

cmb*_*ter 7

奇怪,我也看到了这种行为.在Seg分割路径段之前,对象中没有任何东西可以进行任何类型的URL解码,我也没有在框架中看到任何其他内容.我遇到了一篇文章,详细介绍了使用自定义提取器的解决方案,如下所示:

object Decode {
  import java.net.URLDecoder
  import java.nio.charset.Charset

  trait Extract {
    def charset: Charset
    def unapply(raw: String) = 
      Try(URLDecoder.decode(raw, charset.name())).toOption
  }

  object utf8 extends Extract {
    val charset = Charset.forName("utf8")
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

case reg @ Path(Seg(Decode.utf8(test) :: Nil)) =>
  println(test)
  ResponseString(test)
Run Code Online (Sandbox Code Playgroud)

或者像这样,如果你想要整个路径解码:

case reg @ Path(Decode.utf8(Seg(test :: Nil))) =>
  println(test)
  ResponseString(test)
Run Code Online (Sandbox Code Playgroud)

值得庆幸的是,该框架是灵活的,并且可以像这样扩展,因此您当然可以选择.