未经过滤的URL解码

时间:2013-08-06 14:42:18

标签: 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()
}

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

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

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

  • 我忘记了一些微不足道的事情并且自欺欺人。
  • 未经过滤,有一套工具可以自动处理麻烦。
  • 如果以上都不是,这种行为是否有特殊原因,或者我应该提交错误报告?

作为旁注,unfiltered标记不存在,我没有足够的声誉来创建它,这就是我默认为scala的原因。

1 个答案:

答案 0 :(得分: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")
  }
}

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

case reg @ Path(Seg(Decode.utf8(test) :: Nil)) =>
  println(test)
  ResponseString(test)

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

case reg @ Path(Decode.utf8(Seg(test :: Nil))) =>
  println(test)
  ResponseString(test)

值得庆幸的是,该框架非常灵活,可以像这样扩展,所以你当然可以选择。