Skip to content

Commit

Permalink
Merge branch 'old-version-fixes' of github.com:jdegoes/blueeyes into …
Browse files Browse the repository at this point in the history
…old-version-fixes
  • Loading branch information
Jeff Simpson committed Nov 15, 2010
2 parents 61ee940 + 7ce3ae2 commit 09387f3
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
30 changes: 15 additions & 15 deletions src/main/scala/blueeyes/core/service/NettyRequestHandler.scala
Expand Up @@ -3,11 +3,11 @@ package blueeyes.core.service
import scala.collection.JavaConversions._
import org.jboss.netty.handler.codec.http.HttpHeaders.Names
import org.jboss.netty.handler.codec.http.HttpHeaders._
import blueeyes.util.FutureImplicits
import blueeyes.util.FutureImplicits._
import Converters._
import org.jboss.netty.handler.codec.http.{CookieEncoder, CookieDecoder, HttpRequest => NettyHttpRequest, HttpResponse => NettyHttpResponse, DefaultHttpResponse, HttpVersion => NettyHttpVersion}

import blueeyes.core.http.{HttpMethod, HttpStatusCodes, HttpRequest, HttpResponse, HttpStatus}
import blueeyes.core.http.{HttpMethod, HttpStatusCodes, HttpRequest, HttpResponse, HttpStatus, HttpException}
import org.jboss.netty.handler.codec.http._
import blueeyes.util.Future
import net.lag.logging.Logger
Expand Down Expand Up @@ -60,26 +60,26 @@ class RequestBuilder[S](event: MessageEvent, hierarchy: RestHierarchy[S]) extend
def isDefinedAt(uriAndMethod: (String, HttpMethod)) = findPattern(uriAndMethod._1, uriAndMethod._2).map(v => true).getOrElse(false)
def apply(uriAndMethod: (String, HttpMethod)) = createResponse(uriAndMethod._1, event, findPattern(uriAndMethod._1, uriAndMethod._2).get)

private def createResponse[T, S](requestUri: String, event: MessageEvent, handler: (RestPathPattern, HttpMethod, HttpRequest[T] => Future[HttpResponse[T]], HttpDataTranscoder[T, S])) = {
try {
private def createResponse[T, S](requestUri: String, event: MessageEvent, handler: (RestPathPattern, HttpMethod, HttpRequest[T] => Future[HttpResponse[T]], HttpDataTranscoder[T, S])): Future[NettyHttpResponse] = {
val transcoder: HttpDataTranscoder[T, S] = handler._4

try{
val request = event.getMessage().asInstanceOf[NettyHttpRequest]
val parameters = handler._1(requestUri)

handler._3(fromNettyRequest(request, parameters, event.getRemoteAddress, handler._4)).map(response => {
try {
toNettyResponse(response, handler._4)
}
catch {
case e: Throwable => log.error(e, "Error while NettyResponse creation. Request:" + event); errorResponse(e.getMessage);
}
handler._3(fromNettyRequest(request, parameters, event.getRemoteAddress, transcoder)).map(response => {
try {toNettyResponse(response, transcoder)} catch {case e: Throwable => handle(e, transcoder)}
})
}
catch {
case e: Throwable => log.error(e, "Error while request handling. Request:" + event); new Future[NettyHttpResponse]().deliver(errorResponse(e.getMessage));
}
catch{case e: Throwable => handle(e, transcoder)}
}

private def handle[T, S](th: Throwable, transcoder: HttpDataTranscoder[T, S]): NettyHttpResponse = th match{
case e: HttpException => toNettyResponse(HttpResponse(HttpStatus(e.failure, e.reason)), transcoder)
case _ => log.error(th, "Error while request handling. Request:" + event); toNettyResponse(errorResponse(th.getMessage), transcoder);
}

private def errorResponse(reason: String): NettyHttpResponse = new DefaultHttpResponse(NettyHttpVersion.HTTP_1_1, toNettyStatus(HttpStatus(HttpStatusCodes.InternalServerError, reason.replace("\n", ""))))
private def errorResponse[T](reason: String) = HttpResponse[T](HttpStatus(HttpStatusCodes.InternalServerError, reason.replace("\n", "")))

private def findPattern(uri: String, method: HttpMethod) = hierarchy.hierarchy.find(handler => handler._1.isDefinedAt(uri) && method == handler._2)
}
50 changes: 42 additions & 8 deletions src/test/scala/blueeyes/core/service/HttpServerNettySpec.scala
Expand Up @@ -4,10 +4,11 @@ import java.net.URI
import com.ning.http.client._
import org.specs.Specification
import blueeyes.core.service.RestPathPatternImplicits._
import blueeyes.util.{Future}
import blueeyes.util.Future
import blueeyes.util.Future._
import blueeyes.core.data.{TextToTextBijection}
import blueeyes.core.http.MimeTypes._
import blueeyes.core.http.{HttpMethod, HttpVersion, HttpMethods, HttpVersions, HttpRequest, HttpResponse, HttpStatusCode, HttpStatus, HttpStatusCodes, MimeType}
import blueeyes.core.http._

class HttpServerNettySpec extends Specification{
@volatile
Expand Down Expand Up @@ -53,6 +54,21 @@ class HttpServerNettySpec extends Specification{
response.getResponseBody mustEqual (Context.context)
}

"return Internall error when handling request crushes" in{
val client = new AsyncHttpClient()
val future = client.prepareGet("http://localhost:%d/error".format(port)).execute();

val response = future.get
response.getStatusCode mustEqual (HttpStatusCodes.InternalServerError.value)
}
"return Http error when handling request throws HttpException" in{
val client = new AsyncHttpClient()
val future = client.prepareGet("http://localhost:%d/http/error".format(port)).execute();

val response = future.get
response.getStatusCode mustEqual (HttpStatusCodes.BadRequest.value)
}

"return not found error by wrong URI" in{
val client = new AsyncHttpClient()
val future = client.prepareGet("http://localhost:%d/foo/foo/adCode.html".format(port)).execute();
Expand All @@ -69,17 +85,35 @@ class HttpServerNettySpec extends Specification{

class TestService extends RestHierarchyBuilder[String] with HttpService[String]{
private implicit val transcoder = new HttpStringDataTranscoder(TextToTextBijection, text / html)
path("/bar/'adId/adCode.html"){get(new Handler())}
path("/foo"){get(new Handler())}
path("/bar/'adId/adCode.html"){
get{request: HttpRequest[String] =>
future(HttpResponse[String](HttpStatus(HttpStatusCodes.OK), Map("Content-Type" -> "text/html"), Some(Context.context), HttpVersions.`HTTP/1.1`))
}
}
path("/foo"){
get{request: HttpRequest[String] =>
future(HttpResponse[String](HttpStatus(HttpStatusCodes.OK), Map("Content-Type" -> "text/html"), Some(Context.context), HttpVersions.`HTTP/1.1`))
}
}
path("/error") {
get { request: HttpRequest[String] =>
throw new RuntimeException("Unexecpcted Error.")
}
}
path("/http/error") {
get { request: HttpRequest[String] =>
throw HttpException(HttpStatusCodes.BadRequest)
}
}

private def future(response: HttpResponse[String]) = {
new Future().deliver(response)
}

def version = 1

def name = "test-service"
}
class Handler extends Function1[HttpRequest[String], Future[HttpResponse[String]]]{
def apply(request: HttpRequest[String]) = new Future[HttpResponse[String]]().deliver(HttpResponse[String](HttpStatus(HttpStatusCodes.OK), Map("Content-Type" -> "text/html"), Some(Context.context), HttpVersions.`HTTP/1.1`))
}

object Context{
val context = """<html>
<head>
Expand Down

0 comments on commit 09387f3

Please sign in to comment.