From 8e71346295e1a239db1d0c74be541004203d66b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Dubiel?= Date: Tue, 2 Aug 2016 11:30:32 +0200 Subject: [PATCH] =htp #21029 Move redirect to RequestContext. (#21071) --- .../directives/route-directives/redirect.rst | 2 +- .../http/javadsl/server/RequestContext.scala | 19 ++++++++++++++++++- .../http/scaladsl/server/RequestContext.scala | 8 ++++++++ .../scaladsl/server/RequestContextImpl.scala | 13 +++++++++++++ .../server/directives/RouteDirectives.scala | 14 +------------- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/akka-docs/rst/scala/http/routing-dsl/directives/route-directives/redirect.rst b/akka-docs/rst/scala/http/routing-dsl/directives/route-directives/redirect.rst index af9364b118..48fc04ba7b 100644 --- a/akka-docs/rst/scala/http/routing-dsl/directives/route-directives/redirect.rst +++ b/akka-docs/rst/scala/http/routing-dsl/directives/route-directives/redirect.rst @@ -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). ``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 :snippet: red-impl diff --git a/akka-http/src/main/scala/akka/http/javadsl/server/RequestContext.scala b/akka-http/src/main/scala/akka/http/javadsl/server/RequestContext.scala index 1dc9408c7d..9484b922e4 100644 --- a/akka-http/src/main/scala/akka/http/javadsl/server/RequestContext.scala +++ b/akka-http/src/main/scala/akka/http/javadsl/server/RequestContext.scala @@ -7,21 +7,29 @@ package akka.http.javadsl.server import akka.http.javadsl.marshalling.Marshaller import akka.http.javadsl.model.HttpRequest import akka.http.scaladsl.util.FastFuture._ + import scala.concurrent.ExecutionContextExecutor import akka.stream.Materializer import akka.event.LoggingAdapter import akka.http.javadsl.settings.RoutingSettings import akka.http.javadsl.settings.ParserSettings 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.function.{ Function ⇒ JFunction } + import akka.http.scaladsl import akka.http.impl.util.JavaMapping.Implicits._ import akka.http.scaladsl.marshalling.ToResponseMarshallable + import scala.compat.java8.FutureConverters._ import scala.annotation.varargs import akka.http.scaladsl.model.Uri.Path +import akka.http.scaladsl.marshalling.PredefinedToResponseMarshallers + class RequestContext private (val delegate: scaladsl.server.RequestContext) { import RequestContext._ import RoutingJavaMapping._ @@ -45,10 +53,19 @@ class RequestContext private (val delegate: scaladsl.server.RequestContext) { .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] = { val scalaRejections = rejections.map(_.asScala) 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] = diff --git a/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContext.scala b/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContext.scala index 37e3855cbf..587175c5c3 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContext.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContext.scala @@ -8,7 +8,9 @@ import scala.concurrent.{ Future, ExecutionContextExecutor } import akka.stream.Materializer import akka.event.LoggingAdapter import akka.http.scaladsl.marshalling.ToResponseMarshallable + import akka.http.scaladsl.model._ +import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.settings.{ RoutingSettings, ParserSettings } /** @@ -67,6 +69,12 @@ trait RequestContext { */ 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` * directive and its `ExceptionHandler`, unless the error is a `RejectionError`. In this case the diff --git a/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContextImpl.scala b/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContextImpl.scala index c1c008647f..2c31625dbf 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContextImpl.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/server/RequestContextImpl.scala @@ -10,6 +10,7 @@ import akka.event.LoggingAdapter import akka.http.scaladsl.settings.{ ParserSettings, RoutingSettings } import akka.http.scaladsl.marshalling.{ Marshal, ToResponseMarshallable } import akka.http.scaladsl.model._ +import akka.http.scaladsl.model.StatusCodes._ 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] = 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] = FastFuture.failed(error) diff --git a/akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala b/akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala index c1c7cf612e..4a6e2e0f7f 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/server/directives/RouteDirectives.scala @@ -36,19 +36,7 @@ trait RouteDirectives { * @group route */ def redirect(uri: Uri, redirectionType: Redirection): StandardRoute = - StandardRoute { - _. //# 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) - }) - } - //# - } + StandardRoute(_.redirect(uri, redirectionType)) /** * Completes the request using the given arguments.