Skip to content
Browse files

Run not found handler for not found status codes without a body

  • Loading branch information...
1 parent e05a209 commit 694498b04a00d808b69d8def5e4ef5cdaf99067a @casualjim casualjim committed Dec 22, 2012
View
12 core/src/main/scala/org/scalatra/ScalatraBase.scala
@@ -101,10 +101,11 @@ trait ScalatraSyntax extends CoreDsl with RequestResponseScope with Initializabl
val prehandleException = request.get("org.scalatra.PrehandleException")
if (prehandleException.isEmpty) {
runFilters(routes.beforeFilters)
- val actionResult = runRoutes(routes(request.requestMethod)).headOption orElse
- matchOtherMethods() getOrElse doNotFound()
+ val actionResult = runRoutes(routes(request.requestMethod)).headOption
// Give the status code handler a chance to override the actionResult
- result = handleStatusCode(status) getOrElse actionResult
+ result = handleStatusCode(status) getOrElse {
+ actionResult orElse matchOtherMethods() getOrElse doNotFound()
+ }
} else {
throw prehandleException.get.asInstanceOf[Exception]
}
@@ -286,6 +287,8 @@ trait ScalatraSyntax extends CoreDsl with RequestResponseScope with Initializabl
* response has been rendered.
*/
protected def renderPipeline: RenderPipeline = {
+ case 404 =>
+ doNotFound()
case status: Int =>
response.status = ResponseStatus(status)
case bytes: Array[Byte] =>
@@ -296,6 +299,7 @@ trait ScalatraSyntax extends CoreDsl with RequestResponseScope with Initializabl
using(new FileInputStream(file)) { in => zeroCopy(in, response.outputStream) }
case _: Unit | Unit =>
// If an action returns Unit, it assumes responsibility for the response
+ case ActionResult(ResponseStatus(404, _), _: Unit | Unit, _) => doNotFound()
case actionResult: ActionResult =>
response.status = actionResult.status
actionResult.headers.foreach { case(name, value) => response.addHeader(name, value) }
@@ -379,6 +383,8 @@ trait ScalatraSyntax extends CoreDsl with RequestResponseScope with Initializabl
protected def renderHaltException(e: HaltException) {
e match {
+ case HaltException(Some(404), _, _, _: Unit | Unit) | HaltException(_, _, _, ActionResult(ResponseStatus(404, _), _: Unit | Unit, _)) =>
+ doNotFound()
case HaltException(Some(status), Some(reason), _, _) =>
response.status = ResponseStatus(status, reason)
case HaltException(Some(status), None, _, _) =>
View
2 core/src/main/scala/org/scalatra/ScalatraFilter.scala
@@ -21,7 +21,7 @@ import javax.servlet._
*
* @see ScalatraServlet
*/
-@deprecated("This aproach uses thread locals which cause headaches in a multi-threading scenario, use org.scalatra.ScalatraApp instead.", "2.2")
+//@deprecated("This aproach uses thread locals which cause headaches in a multi-threading scenario, use org.scalatra.ScalatraApp instead.", "2.2")
trait ScalatraFilter extends Filter with ServletBase {
private[this] val _filterChain = new DynamicVariable[FilterChain](null)
protected def filterChain = _filterChain.value
View
2 core/src/main/scala/org/scalatra/ScalatraServlet.scala
@@ -47,7 +47,7 @@ object ScalatraServlet {
*
* @see ScalatraFilter
*/
-@deprecated("This aproach uses thread locals which cause headaches in a multi-threading scenario, use org.scalatra.ScalatraApp instead.", "2.2")
+//@deprecated("This aproach uses thread locals which cause headaches in a multi-threading scenario, use org.scalatra.ScalatraApp instead.", "2.2")
abstract class ScalatraServlet
extends HttpServlet
with ServletBase
View
4 core/src/test/scala/org/scalatra/HaltSpec.scala
@@ -28,7 +28,7 @@ class HaltTestServlet extends ScalatraServlet {
}
get("/status-and-body") {
- halt(403, <h1>Go away</h1>)
+ halt(404, <h1>Not Here</h1>)
"this content must not be returned"
}
@@ -74,7 +74,7 @@ class HaltSpec extends ScalatraSpec { def is =
"halt with a status and body should" ^
"behave like a common halt" ^ commonHalt("/status-and-body")^
"set the status" ! status("/status-and-body", 404)^
- "render the body" ! bodyEquals("/status-and-body", "<h1>Go away</h1>")^
+ "render the body" ! bodyEquals("/status-and-body", "<h1>Not Here</h1>")^
end^
"halt with all arguments should" ^
"behave like a common halt" ^ commonHalt("/all-args")^
View
4 core/src/test/scala/org/scalatra/ScalatraTest.scala
@@ -36,7 +36,7 @@ class ScalatraTestServlet extends ScalatraServlet {
}
get("/return-int") {
- 404
+ 403
}
get("/redirect") {
@@ -213,7 +213,7 @@ class ScalatraTest extends ScalatraFunSuite {
test("int return value sets status and no body") {
get("/return-int") {
- status should equal (404)
+ status should equal (403)
body should equal ("")
}
}
View
5 json/src/main/scala/org/scalatra/json/JValueResult.scala
@@ -15,7 +15,7 @@ trait JValueResult extends ScalatraSyntax { self: JsonSupport[_] =>
override protected def renderPipeline: RenderPipeline = renderToJson orElse super.renderPipeline
- private def renderToJson: RenderPipeline = {
+ private[this] def renderToJson: RenderPipeline = {
case a: JValue => super.renderPipeline(a)
case status: Int => super.renderPipeline(status)
case bytes: Array[Byte] => super.renderPipeline(bytes)
@@ -24,6 +24,8 @@ trait JValueResult extends ScalatraSyntax { self: JsonSupport[_] =>
case a: ActionResult => super.renderPipeline(a)
case _: Unit | Unit => super.renderPipeline(())
case s: String => super.renderPipeline(s)
+ case null if responseFormat == "json" || responseFormat == "xml" => JNull
+ case null => super.renderPipeline(null)
case x: scala.xml.Node if responseFormat == "xml"
contentType = formats("xml")
response.writer.write(scala.xml.Utility.trim(x).toString())
@@ -34,7 +36,6 @@ trait JValueResult extends ScalatraSyntax { self: JsonSupport[_] =>
response.writer.write(x.toString)
case p: Product if responseFormat == "json" || responseFormat == "xml" => Extraction.decompose(p)
case p: Traversable[_] if responseFormat == "json" || responseFormat == "xml" => Extraction.decompose(p)
- case a => super.renderPipeline(a)
}
}
View
2 notes/2.2.0.markdown
@@ -26,6 +26,8 @@
* ApiFormats now also has a reverse mapping for the txt extension
* Adds `GZipSupport`, contributed by @Marza
* Folds `TypedParamSupport` into core making the `params.getAs[Int]` methods available everywhere
+* When an action returns `halt(404)`, `halt(NotFound())`, `404` or `NotFound()` then the not found handler is run
+ If this has a body then the not found handler is skipped
### lift-json
* removed for json4s support

0 comments on commit 694498b

Please sign in to comment.
Something went wrong with that request. Please try again.