=htp #21029 Move redirect to RequestContext. (#21071)

This commit is contained in:
Łukasz Dubiel 2016-08-02 11:30:32 +02:00 committed by Konrad Malawski
parent 5dc0db2112
commit 8e71346295
5 changed files with 41 additions and 15 deletions

View file

@ -15,7 +15,7 @@ Description
Completes the request with a redirection response to a given targer URI and of a given redirection type (status code). Completes the request with a redirection response to a given targer URI and of a given redirection type (status code).
``redirect`` is a convenience helper for completing the request with a redirection response. ``redirect`` is a convenience helper for completing the request with a redirection response.
It is equivalent to this snippet relying on the ``complete`` directive: It is equivalent to this snippet relying on the ``complete`` method on ``RequestContext`` (a directive is also available):
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala .. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala
:snippet: red-impl :snippet: red-impl

View file

@ -7,21 +7,29 @@ package akka.http.javadsl.server
import akka.http.javadsl.marshalling.Marshaller import akka.http.javadsl.marshalling.Marshaller
import akka.http.javadsl.model.HttpRequest import akka.http.javadsl.model.HttpRequest
import akka.http.scaladsl.util.FastFuture._ import akka.http.scaladsl.util.FastFuture._
import scala.concurrent.ExecutionContextExecutor import scala.concurrent.ExecutionContextExecutor
import akka.stream.Materializer import akka.stream.Materializer
import akka.event.LoggingAdapter import akka.event.LoggingAdapter
import akka.http.javadsl.settings.RoutingSettings import akka.http.javadsl.settings.RoutingSettings
import akka.http.javadsl.settings.ParserSettings import akka.http.javadsl.settings.ParserSettings
import akka.http.javadsl.model.HttpResponse import akka.http.javadsl.model.HttpResponse
import akka.http.javadsl.model.StatusCode
import akka.http.javadsl.model.Uri
import akka.http.javadsl.model.headers.Location
import java.util.concurrent.CompletionStage import java.util.concurrent.CompletionStage
import java.util.function.{ Function JFunction } import java.util.function.{ Function JFunction }
import akka.http.scaladsl import akka.http.scaladsl
import akka.http.impl.util.JavaMapping.Implicits._ import akka.http.impl.util.JavaMapping.Implicits._
import akka.http.scaladsl.marshalling.ToResponseMarshallable import akka.http.scaladsl.marshalling.ToResponseMarshallable
import scala.compat.java8.FutureConverters._ import scala.compat.java8.FutureConverters._
import scala.annotation.varargs import scala.annotation.varargs
import akka.http.scaladsl.model.Uri.Path import akka.http.scaladsl.model.Uri.Path
import akka.http.scaladsl.marshalling.PredefinedToResponseMarshallers
class RequestContext private (val delegate: scaladsl.server.RequestContext) { class RequestContext private (val delegate: scaladsl.server.RequestContext) {
import RequestContext._ import RequestContext._
import RoutingJavaMapping._ import RoutingJavaMapping._
@ -45,10 +53,19 @@ class RequestContext private (val delegate: scaladsl.server.RequestContext) {
.fast.map(r r: RouteResult)(akka.dispatch.ExecutionContexts.sameThreadExecutionContext).toJava .fast.map(r r: RouteResult)(akka.dispatch.ExecutionContexts.sameThreadExecutionContext).toJava
} }
def completeWith(response: HttpResponse): CompletionStage[RouteResult] = {
delegate.complete(response.asScala)
.fast.map(r r: RouteResult)(akka.dispatch.ExecutionContexts.sameThreadExecutionContext).toJava
}
@varargs def reject(rejections: Rejection*): CompletionStage[RouteResult] = { @varargs def reject(rejections: Rejection*): CompletionStage[RouteResult] = {
val scalaRejections = rejections.map(_.asScala) val scalaRejections = rejections.map(_.asScala)
delegate.reject(scalaRejections: _*) delegate.reject(scalaRejections: _*)
.fast.map(r r.asJava: RouteResult)(akka.dispatch.ExecutionContexts.sameThreadExecutionContext).toJava .fast.map(r r: RouteResult)(akka.dispatch.ExecutionContexts.sameThreadExecutionContext).toJava
}
def redirect(uri: Uri, redirectionType: StatusCode): CompletionStage[RouteResult] = {
completeWith(HttpResponse.create().withStatus(redirectionType).addHeader(Location.create(uri)))
} }
def fail(error: Throwable): CompletionStage[RouteResult] = def fail(error: Throwable): CompletionStage[RouteResult] =

View file

@ -8,7 +8,9 @@ import scala.concurrent.{ Future, ExecutionContextExecutor }
import akka.stream.Materializer import akka.stream.Materializer
import akka.event.LoggingAdapter import akka.event.LoggingAdapter
import akka.http.scaladsl.marshalling.ToResponseMarshallable import akka.http.scaladsl.marshalling.ToResponseMarshallable
import akka.http.scaladsl.model._ import akka.http.scaladsl.model._
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.settings.{ RoutingSettings, ParserSettings } import akka.http.scaladsl.settings.{ RoutingSettings, ParserSettings }
/** /**
@ -67,6 +69,12 @@ trait RequestContext {
*/ */
def reject(rejections: Rejection*): Future[RouteResult] def reject(rejections: Rejection*): Future[RouteResult]
/**
* Completes the request with redirection response of the given type to the given URI.
*
*/
def redirect(uri: Uri, redirectionType: Redirection): Future[RouteResult]
/** /**
* Bubbles the given error up the response chain where it is dealt with by the closest `handleExceptions` * Bubbles the given error up the response chain where it is dealt with by the closest `handleExceptions`
* directive and its `ExceptionHandler`, unless the error is a `RejectionError`. In this case the * directive and its `ExceptionHandler`, unless the error is a `RejectionError`. In this case the

View file

@ -10,6 +10,7 @@ import akka.event.LoggingAdapter
import akka.http.scaladsl.settings.{ ParserSettings, RoutingSettings } import akka.http.scaladsl.settings.{ ParserSettings, RoutingSettings }
import akka.http.scaladsl.marshalling.{ Marshal, ToResponseMarshallable } import akka.http.scaladsl.marshalling.{ Marshal, ToResponseMarshallable }
import akka.http.scaladsl.model._ import akka.http.scaladsl.model._
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.util.FastFuture import akka.http.scaladsl.util.FastFuture
import akka.http.scaladsl.util.FastFuture._ import akka.http.scaladsl.util.FastFuture._
@ -47,6 +48,18 @@ private[http] class RequestContextImpl(
override def reject(rejections: Rejection*): Future[RouteResult] = override def reject(rejections: Rejection*): Future[RouteResult] =
FastFuture.successful(RouteResult.Rejected(rejections.toList)) FastFuture.successful(RouteResult.Rejected(rejections.toList))
override def redirect(uri: Uri, redirectionType: Redirection): Future[RouteResult] = {
//# red-impl
complete(HttpResponse(
status = redirectionType,
headers = headers.Location(uri) :: Nil,
entity = redirectionType.htmlTemplate match {
case "" HttpEntity.Empty
case template HttpEntity(ContentTypes.`text/html(UTF-8)`, template format uri)
}))
//#
}
override def fail(error: Throwable): Future[RouteResult] = override def fail(error: Throwable): Future[RouteResult] =
FastFuture.failed(error) FastFuture.failed(error)

View file

@ -36,19 +36,7 @@ trait RouteDirectives {
* @group route * @group route
*/ */
def redirect(uri: Uri, redirectionType: Redirection): StandardRoute = def redirect(uri: Uri, redirectionType: Redirection): StandardRoute =
StandardRoute { StandardRoute(_.redirect(uri, redirectionType))
_. //# red-impl
complete {
HttpResponse(
status = redirectionType,
headers = headers.Location(uri) :: Nil,
entity = redirectionType.htmlTemplate match {
case "" HttpEntity.Empty
case template HttpEntity(ContentTypes.`text/html(UTF-8)`, template format uri)
})
}
//#
}
/** /**
* Completes the request using the given arguments. * Completes the request using the given arguments.