!htc #20371 allows for simple HTTPS usage from Java, fixes typo in APIs (#20373)

This commit is contained in:
Konrad Malawski 2016-04-25 12:01:03 +02:00
parent b983f19c1f
commit 0e11ec2057
28 changed files with 674 additions and 120 deletions

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
*/
package docs.http.javadsl.server;
import akka.actor.ActorSystem;
import com.typesafe.sslconfig.akka.AkkaSSLConfig;
import org.junit.Test;
import org.scalatest.junit.JUnitSuite;
/* COMPILE ONLY TEST */
public class HttpsServerExampleTest extends JUnitSuite {
@Test
public void compileOnlySpec() throws Exception {
// just making sure for it to be really compiled / run even if empty
}
void sslConfigGet() {
//#akka-ssl-config
final ActorSystem system = ActorSystem.create();
final AkkaSSLConfig sslConfig = AkkaSSLConfig.get(system);
//#
}
}

View file

@ -125,7 +125,7 @@ Disabling TLS security features, at your own risk
The following shows an example of disabling SNI for a given connection: The following shows an example of disabling SNI for a given connection:
.. includecode:: ../../code/docs/http/scaladsl/HttpsExamplesSpec.scala .. includecode:: ../../code/docs/http/javadsl/HttpsExamplesDocTest.java
:include: disable-sni-connection :include: disable-sni-connection
The ``badSslConfig`` is a copy of the default ``AkkaSSLConfig`` with with the slightly changed configuration to disable SNI. The ``badSslConfig`` is a copy of the default ``AkkaSSLConfig`` with with the slightly changed configuration to disable SNI.

View file

@ -26,5 +26,5 @@ Akka HTTP will happily handle many thousand concurrent connections to a single o
connection-level connection-level
host-level host-level
request-level request-level
https-support client-https-support
websocket-support websocket-support

View file

@ -36,6 +36,7 @@ akka-http-jackson
server-side/websocket-support server-side/websocket-support
routing-dsl/index routing-dsl/index
client-side/index client-side/index
server-side-https-support
configuration configuration
.. _jackson: https://github.com/FasterXML/jackson .. _jackson: https://github.com/FasterXML/jackson

View file

@ -0,0 +1,92 @@
.. _serverSideHTTPS-java:
Server-Side HTTPS Support
=========================
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/javadsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.javadsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
.. _akka.http.javadsl.Http: https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/javadsl/Http.scala
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
In order to use SSL-Config in Akka so it logs to the right ActorSystem-wise logger etc., the
``AkkaSSLConfig`` extension is provided. Obtaining it is as simple as:
.. includecode2:: ../code/docs/http/javadsl/server/HttpsServerExampleTest.java
:snippet: akka-ssl-config
While typical usage, for example for configuring http client settings would be applied globally by configuring
ssl-config in ``application.conf``, it's possible to obtain the extension and ``copy`` it while modifying any
configuration that you might need to change and then use that specific ``AkkaSSLConfig`` instance while establishing
connections be it client or server-side.
Obtaining SSL/TLS Certificates
------------------------------
In order to run an HTTPS server a certificate has to be provided, which usually is either obtained from a signing
authority or created by yourself for local or staging environment purposes.
Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat
configuration). If you want to generate your own certificates, the official Oracle documentation on how to generate
keystores using the JDK keytool utility can be found `here <https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html>`_.
SSL-Config provides a more targeted guide on generating certificates, so we recommend you start with the guide
titled `Generating X.509 Certificates <http://typesafehub.github.io/ssl-config/CertificateGeneration.html>`_.
Using HTTPS
-----------
Once you have obtained the server certificate, using it is as simple as preparing an ``HttpsConnectionContext``
and either setting it as the default one to be used by all servers started by the given ``Http`` extension
or passing it in explicitly when binding the server.
The below example shows how setting up HTTPS works when using the ``akka.http.javadsl.server.HttpApp`` convenience class:
.. includecode2:: ../../../../akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java
:snippet: https-http-app
Further reading
---------------
The topic of properly configuring HTTPS for your web server is an always changing one,
thus we recommend staying up to date with various security breach news and of course
keep your JVM at the latest version possible, as the default settings are often updated by
Oracle in reaction to various security updates and known issues.
We also recommend having a look at the `Play documentation about securing your app`_,
as well as the techniques described in the Play documentation about setting up a `reverse proxy to terminate TLS in
front of your application`_ instead of terminating TLS inside the JVM, and therefore Akka HTTP, itself.
Other excellent articles on the subject:
- `Oracle Java SE 8: Creating a Keystore using JSSE <https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore>`_
- `Java PKI Programmer's Guide <https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html>`_
- `Fixing X.509 Certificates <https://tersesystems.com/2014/03/20/fixing-x509-certificates/>`_
.. _Play documentation about securing your app: https://www.playframework.com/documentation/2.5.x/ConfiguringHttps#ssl-certificates
.. _reverse proxy to terminate TLS in front of your application: https://www.playframework.com/documentation/2.5.x/HTTPServer

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
*/
package docs.http.scaladsl.server
//#imports
import java.io.InputStream
import java.security.{ SecureRandom, KeyStore }
import javax.net.ssl.{ SSLContext, TrustManagerFactory, KeyManagerFactory }
import akka.actor.ActorSystem
import akka.http.scaladsl.server.{ RouteResult, Route, Directives }
import akka.http.scaladsl.{ ConnectionContext, HttpsConnectionContext, Http }
import akka.stream.ActorMaterializer
import com.typesafe.sslconfig.akka.AkkaSSLConfig
//#
import docs.CompileOnlySpec
import org.scalatest.{ Matchers, WordSpec }
abstract class HttpsServerExampleSpec extends WordSpec with Matchers
with Directives with CompileOnlySpec {
class HowToObtainSSLConfig {
//#akka-ssl-config
implicit val system = ActorSystem()
val sslConfig = AkkaSSLConfig()
//#
}
"low level api" in compileOnlySpec {
//#low-level-default
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
implicit val dispatcher = system.dispatcher
// Manual HTTPS configuration
val password: Array[Char] = ??? // do not store passwords in code, read them from somewhere safe!
val ks: KeyStore = KeyStore.getInstance("PKCS12")
val keystore: InputStream = getClass.getClassLoader.getResourceAsStream("server.p12")
require(keystore != null, "Keystore required!")
ks.load(keystore, password)
val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(ks, password)
val tmf: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
tmf.init(ks)
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(keyManagerFactory.getKeyManagers, tmf.getTrustManagers, SecureRandom.getInstanceStrong)
val https: HttpsConnectionContext = ConnectionContext.https(sslContext)
// sets default context to HTTPS all Http() bound servers for this ActorSystem will use HTTPS from now on
Http().setDefaultServerHttpContext(https)
//#
//#bind-low-level-context
Http().bind("127.0.0.1", connectionContext = https)
// or using the high level routing DSL:
val routes: Route = get { complete("Hello world!") }
Http().bindAndHandle(routes, "127.0.0.1", 8080, connectionContext = https)
//#
}
}

View file

@ -3,7 +3,7 @@
Client-Side HTTPS Support Client-Side HTTPS Support
========================= =========================
Akka HTTP supports TLS encryption on the client-side as well as on the :ref:`server-side <serverSideHTTPS>`. Akka HTTP supports TLS encryption on the client-side as well as on the :ref:`server-side <serverSideHTTPS-scala>`.
.. warning: .. warning:

View file

@ -27,5 +27,5 @@ Akka HTTP will happily handle many thousand concurrent connections to a single o
connection-level connection-level
host-level host-level
request-level request-level
https-support client-https-support
websocket-support websocket-support

View file

@ -12,4 +12,5 @@ Akka HTTP
low-level-server-side-api low-level-server-side-api
routing-dsl/index routing-dsl/index
client-side/index client-side/index
server-side-https-support
migration-from-spray migration-from-spray

View file

@ -11,7 +11,8 @@ This means that, if you have trouble achieving something using a high-level API,
it done with a low-level API, which offers more flexibility but might require you to write more application code. it done with a low-level API, which offers more flexibility but might require you to write more application code.
Philosophy Philosophy
--------------- ----------
Akka HTTP has been driven with a clear focus on providing tools for building integration layers rather than application cores. As such it regards itself as a suite of libraries rather than a framework. Akka HTTP has been driven with a clear focus on providing tools for building integration layers rather than application cores. As such it regards itself as a suite of libraries rather than a framework.
A framework, as wed like to think of the term, gives you a “frame”, in which you build your application. It comes with a lot of decisions already pre-made and provides a foundation including support structures that lets you get started and deliver results quickly. In a way a framework is like a skeleton onto which you put the “flesh” of your application in order to have it come alive. As such frameworks work best if you choose them before you start application development and try to stick to the frameworks “way of doing things” as you go along. A framework, as wed like to think of the term, gives you a “frame”, in which you build your application. It comes with a lot of decisions already pre-made and provides a foundation including support structures that lets you get started and deliver results quickly. In a way a framework is like a skeleton onto which you put the “flesh” of your application in order to have it come alive. As such frameworks work best if you choose them before you start application development and try to stick to the frameworks “way of doing things” as you go along.

View file

@ -136,39 +136,10 @@ Connection will also be closed if request entity has been cancelled (e.g. by att
or consumed only partially (e.g. by using ``take`` combinator). In order to prevent this behaviour entity should be or consumed only partially (e.g. by using ``take`` combinator). In order to prevent this behaviour entity should be
explicitly drained by attaching it to ``Sink.ignore``. explicitly drained by attaching it to ``Sink.ignore``.
Configuring Server-side HTTPS
-----------------------------
.. _serverSideHTTPS: For detailed documentation about configuring and using HTTPS on the server-side refer to :ref:`serverSideHTTPS-scala`.
Server-Side HTTPS Support
-------------------------
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.scaladsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
.. _http-server-layer-scala: .. _http-server-layer-scala:
@ -277,3 +248,4 @@ anyway, which is a reasonable default for such problems.
In order to learn more about handling exceptions in the actual routing layer, which is where your application code In order to learn more about handling exceptions in the actual routing layer, which is where your application code
comes into the picture, refer to :ref:`exception-handling-scala` which focuses explicitly on explaining how exceptions comes into the picture, refer to :ref:`exception-handling-scala` which focuses explicitly on explaining how exceptions
thrown in routes can be handled and transformed into :class:`HttpResponse` s with apropriate error codes and human-readable failure descriptions. thrown in routes can be handled and transformed into :class:`HttpResponse` s with apropriate error codes and human-readable failure descriptions.

View file

@ -97,3 +97,7 @@ and split each line before we send it to an actor for further processing:
.. includecode2:: ../../code/docs/http/scaladsl/server/FileUploadExamplesSpec.scala .. includecode2:: ../../code/docs/http/scaladsl/server/FileUploadExamplesSpec.scala
:snippet: stream-csv-upload :snippet: stream-csv-upload
Configuring Server-side HTTPS
-----------------------------
For detailed documentation about configuring and using HTTPS on the server-side refer to :ref:`serverSideHTTPS-scala`.

View file

@ -0,0 +1,101 @@
.. _serverSideHTTPS-scala:
Server-Side HTTPS Support
=========================
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.scaladsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
.. _akka.http.scaladsl.Http: https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
In order to use SSL-Config in Akka so it logs to the right ActorSystem-wise logger etc., the
``AkkaSSLConfig`` extension is provided. Obtaining it is as simple as:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: akka-ssl-config
While typical usage, for example for configuring http client settings would be applied globally by configuring
ssl-config in ``application.conf``, it's possible to obtain the extension and ``copy`` it while modifying any
configuration that you might need to change and then use that specific ``AkkaSSLConfig`` instance while establishing
connections be it client or server-side.
Obtaining SSL/TLS Certificates
------------------------------
In order to run an HTTPS server a certificate has to be provided, which usually is either obtained from a signing
authority or created by yourself for local or staging environment purposes.
Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat
configuration). If you want to generate your own certificates, the official Oracle documentation on how to generate
keystores using the JDK keytool utility can be found `here <https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html>`_.
SSL-Config provides a more targeted guide on generating certificates, so we recommend you start with the guide
titled `Generating X.509 Certificates <http://typesafehub.github.io/ssl-config/CertificateGeneration.html>`_.
Using HTTPS
-----------
Once you have obtained the server certificate, using it is as simple as preparing an ``HttpsConnectionContext``
and either setting it as the default one to be used by all servers started by the given ``Http`` extension
or passing it in explicitly when binding the server:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: imports
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: low-level-default
It is also possible to pass in the context to specific ``bind...`` (or client) calls, like displayed below:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: bind-low-level-context
Further reading
---------------
The topic of properly configuring HTTPS for your web server is an always changing one,
thus we recommend staying up to date with various security breach news and of course
keep your JVM at the latest version possible, as the default settings are often updated by
Oracle in reaction to various security updates and known issues.
We also recommend having a look at the `Play documentation about securing your app`_,
as well as the techniques described in the Play documentation about setting up a `reverse proxy to terminate TLS in
front of your application`_ instead of terminating TLS inside the JVM, and therefore Akka HTTP, itself.
Other excellent articles on the subject:
- `Oracle Java SE 8: Creating a Keystore using JSSE <https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore>`_
- `Java PKI Programmer's Guide <https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html>`_
- `Fixing X.509 Certificates <https://tersesystems.com/2014/03/20/fixing-x509-certificates/>`_
.. _Play documentation about securing your app: https://www.playframework.com/documentation/2.5.x/ConfiguringHttps#ssl-certificates
.. _reverse proxy to terminate TLS in front of your application: https://www.playframework.com/documentation/2.5.x/HTTPServer

View file

@ -18,8 +18,11 @@ object ConnectionContext {
scaladsl.ConnectionContext.https(sslContext) scaladsl.ConnectionContext.https(sslContext)
/** Used to serve HTTPS traffic. */ /** Used to serve HTTPS traffic. */
def https(sslContext: SSLContext, enabledCipherSuites: Optional[JCollection[String]], def https(sslContext: SSLContext,
enabledProtocols: Optional[JCollection[String]], clientAuth: Optional[TLSClientAuth], sslParameters: Optional[SSLParameters]) = enabledCipherSuites: Optional[JCollection[String]],
enabledProtocols: Optional[JCollection[String]],
clientAuth: Optional[TLSClientAuth],
sslParameters: Optional[SSLParameters]) =
scaladsl.ConnectionContext.https(sslContext, sslParameters = OptionConverters.toScala(sslParameters)) scaladsl.ConnectionContext.https(sslContext, sslParameters = OptionConverters.toScala(sslParameters))
//#https-context-creation //#https-context-creation

View file

@ -640,13 +640,19 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
def shutdownAllConnectionPools(): CompletionStage[Unit] = delegate.shutdownAllConnectionPools().toJava def shutdownAllConnectionPools(): CompletionStage[Unit] = delegate.shutdownAllConnectionPools().toJava
/** /**
* Gets the default * Gets the current default server-side [[ConnectionContext]] defaults to plain HTTP.
* * Can be modified using [[setDefaultServerHttpContext]], and will then apply for servers bound after that call has completed.
* @return
*/ */
def defaultServerHttpContext: ConnectionContext = def defaultServerHttpContext: ConnectionContext =
delegate.defaultServerHttpContext delegate.defaultServerHttpContext
/**
* Sets the default server-side [[ConnectionContext]].
* If it is an instance of [[HttpsConnectionContext]] then the server will be bound using HTTPS.
*/
def setDefaultServerHttpContext(context: ConnectionContext): Unit =
delegate.setDefaultServerHttpContext(context.asScala)
/** /**
* Gets the current default client-side [[ConnectionContext]]. * Gets the current default client-side [[ConnectionContext]].
*/ */
@ -656,7 +662,10 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
* Sets the default client-side [[ConnectionContext]]. * Sets the default client-side [[ConnectionContext]].
*/ */
def setDefaultClientHttpsContext(context: HttpsConnectionContext): Unit = def setDefaultClientHttpsContext(context: HttpsConnectionContext): Unit =
delegate.setDefaultClientHttpsContext(context.asInstanceOf[akka.http.scaladsl.HttpsConnectionContext]) delegate.setDefaultClientHttpsContext(context.asScala)
def createServerHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext =
delegate.createServerHttpsContext(sslConfig)
def createClientHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext = def createClientHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext =
delegate.createClientHttpsContext(sslConfig) delegate.createClientHttpsContext(sslConfig)

View file

@ -508,6 +508,7 @@ class HttpExt(private val config: Config)(implicit val system: ActorSystem) exte
/** /**
* Gets the current default server-side [[ConnectionContext]] defaults to plain HTTP. * Gets the current default server-side [[ConnectionContext]] defaults to plain HTTP.
* Can be modified using [[setDefaultServerHttpContext]], and will then apply for servers bound after that call has completed.
*/ */
def defaultServerHttpContext: ConnectionContext = def defaultServerHttpContext: ConnectionContext =
synchronized { synchronized {
@ -520,7 +521,7 @@ class HttpExt(private val config: Config)(implicit val system: ActorSystem) exte
* Sets the default server-side [[ConnectionContext]]. * Sets the default server-side [[ConnectionContext]].
* If it is an instance of [[HttpsConnectionContext]] then the server will be bound using HTTPS. * If it is an instance of [[HttpsConnectionContext]] then the server will be bound using HTTPS.
*/ */
def setDefaultClientHttpsContext(context: ConnectionContext): Unit = def setDefaultServerHttpContext(context: ConnectionContext): Unit =
synchronized { synchronized {
_defaultServerConnectionContext = context _defaultServerConnectionContext = context
} }
@ -764,6 +765,13 @@ trait DefaultSSLContextCreation {
def createDefaultClientHttpsContext(): HttpsConnectionContext = def createDefaultClientHttpsContext(): HttpsConnectionContext =
createClientHttpsContext(sslConfig) createClientHttpsContext(sslConfig)
// currently the same configuration as client by default, however we should tune this for server-side apropriately (!)
def createServerHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext = {
log.warning("Automatic server-side configuration is not supported yet, will attempt to use client-side settings. " +
"Instead it is recommended to construct the Servers HttpsConnectionContext manually (via SSLContext).")
createClientHttpsContext(sslConfig)
}
def createClientHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext = { def createClientHttpsContext(sslConfig: AkkaSSLConfig): HttpsConnectionContext = {
val config = sslConfig.config val config = sslConfig.config

View file

@ -4,6 +4,8 @@
package akka.http.scaladsl package akka.http.scaladsl
import javax.net.ssl.SSLContext
import akka.NotUsed import akka.NotUsed
import scala.concurrent.duration._ import scala.concurrent.duration._

View file

@ -4,15 +4,28 @@
package akka.http.javadsl.server.examples.simple; package akka.http.javadsl.server.examples.simple;
//#https-http-app
import akka.actor.ActorSystem; import akka.actor.ActorSystem;
import akka.http.javadsl.ConnectionContext;
import akka.http.javadsl.Http;
import akka.http.javadsl.HttpsConnectionContext;
import akka.http.javadsl.server.*; import akka.http.javadsl.server.*;
import akka.http.javadsl.server.values.Parameter; import akka.http.javadsl.server.values.Parameter;
import akka.http.javadsl.server.values.Parameters; import akka.http.javadsl.server.values.Parameters;
import akka.http.javadsl.server.values.PathMatcher; import akka.http.javadsl.server.values.PathMatcher;
import akka.http.javadsl.server.values.PathMatchers; import akka.http.javadsl.server.values.PathMatchers;
import com.typesafe.config.ConfigFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Callable; import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage; import java.util.concurrent.CompletionStage;
@ -29,6 +42,7 @@ public class SimpleServerApp extends HttpApp {
int result = x * y; int result = x * y;
return ctx.complete(String.format("%d * %d = %d", x, y, result)); return ctx.complete(String.format("%d * %d = %d", x, y, result));
} }
public static CompletionStage<RouteResult> multiplyAsync(final RequestContext ctx, final int x, final int y) { public static CompletionStage<RouteResult> multiplyAsync(final RequestContext ctx, final int x, final int y) {
return CompletableFuture.supplyAsync(() -> multiply(ctx, x, y), ctx.executionContext()); return CompletableFuture.supplyAsync(() -> multiply(ctx, x, y), ctx.executionContext());
} }
@ -87,11 +101,60 @@ public class SimpleServerApp extends HttpApp {
); );
} }
// ** STARTING THE SERVER ** //
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
ActorSystem system = ActorSystem.create(); final ActorSystem system = ActorSystem.create("SimpleServerApp");
final Http http = Http.get(system);
boolean useHttps = false; // pick value from anywhere
useHttps(system, http, useHttps);
new SimpleServerApp().bindRoute("localhost", 8080, system); new SimpleServerApp().bindRoute("localhost", 8080, system);
System.out.println("Type RETURN to exit"); System.out.println("Type RETURN to exit");
System.in.read(); System.in.read();
system.terminate(); system.terminate();
} }
// ** CONFIGURING ADDITIONAL SETTINGS ** //
public static void useHttps(ActorSystem system, Http http, boolean useHttps) {
if (useHttps) {
HttpsConnectionContext https = null;
try {
// initialise the keystore
// !!! never put passwords into code !!!
final char[] password = new char[]{'a', 'b', 'c', 'd', 'e', 'f'};
final KeyStore ks = KeyStore.getInstance("PKCS12");
final InputStream keystore = SimpleServerApp.class.getClassLoader().getResourceAsStream("httpsDemoKeys/keys/server.p12");
if (keystore == null) {
throw new RuntimeException("Keystore required!");
} }
ks.load(keystore, password);
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(ks, password);
final TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), SecureRandom.getInstanceStrong());
https = ConnectionContext.https(sslContext);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
system.log().error("Exception while configuring HTTPS.", e);
} catch (CertificateException | KeyStoreException | UnrecoverableKeyException | IOException e) {
system.log().error("Exception while ", e);
}
http.setDefaultServerHttpContext(https);
}
}
}
//#

View file

@ -0,0 +1,57 @@
Keys for running Tls tests using the `ExampleHttpContexts`
----------------------------------------------------------
Instructions adapted from
* http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/
* http://security.stackexchange.com/questions/9600/how-to-use-openssl-generated-keys-in-java
# Create a rootCA key:
```
openssl genrsa -out rootCA.key 2048
```
# Self-sign CA:
```
openssl req -x509 -new -nodes -key rootCA.key -days 3560 -out rootCA.crt
```
# Create server key:
```
openssl genrsa -out server.key 2048
```
# Create server CSR (you need to set the common name CN to "akka.example.org"):
```
openssl req -new -key server.key -out server.csr
```
# Create server certificate:
```
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 3560
```
# Create certificate chain:
```
cat server.crt rootCA.crt > chain.pem
```
# Convert certificate and key to pkcs12 (you need to provide a password manually, `ExampleHttpContexts`
# expects the password to be "abcdef"):
```
openssl pkcs12 -export -name servercrt -in chain.pem -inkey server.key -out server.p12
```
# For investigating remote certs use:
```
openssl s_client -showcerts -connect 54.173.126.144:443
```

View file

@ -0,0 +1,40 @@
-----BEGIN CERTIFICATE-----
MIIDITCCAgkCCQCo8H6OcPrArzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE1MDcyMzA5NTEyMloXDTI1MDQyMTA5NTEyMlowYDELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDEZMBcGA1UEAwwQYWtrYS5leGFtcGxlLm9yZzCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMy/wgrSYVhVtu9OGbo2rSKauiz
5V56X4uCqtCHF9UeHtnVtFLCBMa+pimOS+UyUAT4mbBsxW22BhoNUBZ15KPxltyD
yEsqNCKwWGxL3r8AXQtze2MEpTl22Lvp/iCTXO1vbML/+9r3uqUjw/AAP9HwF9Wd
j/yOrs6q8WE4sfc48iOj6N60/h2pRfn2WNJmo9W9FLC53NznixfsG5oN6Jmb9RM+
fMHYXLfL/Vt6NrgVX1uqHt9HvuoxfNKhhXE5VU8bNfFfzPYvIt4aZXGxO15vEqsq
OaZ7YJyKr1oFfJC8LmE5xPa3GHToCqmkdMXQK38mpslMQWlQLYnmkS5Qzv8CAwEA
ATANBgkqhkiG9w0BAQsFAAOCAQEAEPDd1gAF9q2LtoZqTdcwmeBjdbT7n0WDRSuI
BzQ/qKjvymwpFKQ0pZSPUyaw2qfRRiTQ/QTbqYep2mhvl5n+gW3ifTp83zgTGKH/
3sDlX0HPSCBYCDy2gP/AOIgV/57ADMpEkTlz8yyLMH+pLDAoNFIPwy7blAkq+ULQ
y6TfEBmZXoemSaIh5tRnexCD+pTvL4MRrGlBEoxdejDnIAt4n6BxmF0b4hKg8uta
UvivA85lBKzWUoR/Vam5/SC8jtcyLt9RThRcNSj6zP6s5d+o+8PLznrSEadAtfD9
0q+t4TYF81tClEEgGruVPNL4WIpDniOfw9AJgQNVJGfy5TKY1Q==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANYwx08wP3STMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNzIzMDk0ODI2WhcNMjUwNDIxMDk0ODI2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhbBXCrFaIl
Io0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNYA9ORWoGE
XhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIGasEzzigB
LX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j+STWlD9v
+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRea7CQXN7g
191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABo1AwTjAdBgNVHQ4EFgQU2THI/ilU
M0xds3vZlV4CvhAZ1d8wHwYDVR0jBBgwFoAU2THI/ilUM0xds3vZlV4CvhAZ1d8w
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAK9LO0HyIi0xbTISsc+A5
LQyZowgRAGqsNNmni7NKDXauPLZrCfDVhvo/FPP1XSFShXo7ARvro9lul4AJlkNN
VgX0gbWtkiAx0uLqlbMsC6imj2L9boRse7mzI/Ymem5SNTn9GUnlMiZ74rca9UT4
Dk9YytrT4FSpomiL6z8Xj604W3RuLSdEfpfcn3Jh2tFSZ9hyLwB7ATUTA/yuj1SU
G1gmoPMvlnPzNj2lIqyIdQxGdxt+L3mFO20CxBkeieWqQuNptpjwptliFjkZJJZP
wQlx9qLLvs/eFC2AUWj+hbsl37PuARR9hoeqbKRcUjwGtaXOqikrvX1qzPc2+ij9
/w==
-----END CERTIFICATE-----

View file

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANYwx08wP3STMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNzIzMDk0ODI2WhcNMjUwNDIxMDk0ODI2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhbBXCrFaIl
Io0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNYA9ORWoGE
XhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIGasEzzigB
LX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j+STWlD9v
+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRea7CQXN7g
191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABo1AwTjAdBgNVHQ4EFgQU2THI/ilU
M0xds3vZlV4CvhAZ1d8wHwYDVR0jBBgwFoAU2THI/ilUM0xds3vZlV4CvhAZ1d8w
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAK9LO0HyIi0xbTISsc+A5
LQyZowgRAGqsNNmni7NKDXauPLZrCfDVhvo/FPP1XSFShXo7ARvro9lul4AJlkNN
VgX0gbWtkiAx0uLqlbMsC6imj2L9boRse7mzI/Ymem5SNTn9GUnlMiZ74rca9UT4
Dk9YytrT4FSpomiL6z8Xj604W3RuLSdEfpfcn3Jh2tFSZ9hyLwB7ATUTA/yuj1SU
G1gmoPMvlnPzNj2lIqyIdQxGdxt+L3mFO20CxBkeieWqQuNptpjwptliFjkZJJZP
wQlx9qLLvs/eFC2AUWj+hbsl37PuARR9hoeqbKRcUjwGtaXOqikrvX1qzPc2+ij9
/w==
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhb
BXCrFaIlIo0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNY
A9ORWoGEXhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIG
asEzzigBLX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j
+STWlD9v+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRe
a7CQXN7g191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABAoIBAQCSXAEpLMNRmq33
mlMMqhF7VcPKyF5+Xl9Je/xgcjFWi0CLt5Ruyf/vJ3tVOwLSM3YxQHuN9cSQSXGX
P3rt0SpbWjJ+q/pwpvV7z/5uhUCWjS46m6GxfNsmC3GR8AJDo/F67fBQFTcYWlrn
TLrqxR4EUCgGoJWjPsZr3j6KHX5BYmzyTuJFBzxxipK42hnJQ7tMB8l6/5r4nRka
d6SGFpJDkyhO+Wl0sBXjxHu1E4g8asI061jEOhcROV1Dk4hp1CYhd8TBj//6FSBC
ttsIe2gxT0fk8bnNC78FuO0CUTCj4hFOWP7apr/NhLlxypu+4hj17NMhlptRvGxz
6pPlMVDJAoGBANPVTS5nkJpMyczA5vaHsyTF/nwunogwHVeVYsQQ3Bed28Ldp7gr
Dr4hgYFvGkEmlLvWOleHvGISuD3lHLd112LcPyLFMRrs8wX9vWTueZGYj5KDLS3C
i3GaYMqqYbuiFY1QYprF36zRQkLMKUiOomE2+baCasbhluAqqx32KEKvAoGBANKk
cG0X0svJ/TTQIE5nfDtKePDUA7wEPYGrQOO4vKKZUlytVhf+gEcYr575bPjkTl1h
5jrrhr4OWpFDmRyBpi7wB95Fe93Df+0o4KmiNtsioZsi/MA5Tga2rAZPBBuZ9+5l
alYl0fTo5PR3fOXJJoJ+w7+QI4N/9TGuBJoiEl6lAoGBAM8XapsBOIcApxB7TdCa
HXLH9eDlmqq9jxH+w022xdR4yU2acMtFnOYXz4oAWgRzeVihOOw1kN+4OVKZWBer
JuRJOZf+e+E84OFsjOnNkh/arBGqGFLyLGzlZdb79wv+i19ZxOxWojNLaKHxAjMi
7nBn1Hyux0CjbmK8lAl4iyeVAoGAT6r4BprTFFaiGN56yYykVPx2v4dAnlTwOmHe
GgLd/ZWFrB23CT4toDY6/iKST5Rx+ymy3SgFf06IfJaXi0uR4gDQyQV4sshlUvp5
9k6u9rSjcLyL4dwKoclnSL+L6zCRsC3VSR3myf1n0vp6V6J7mTF+sa4/cFXuE8sg
XHd0gS0CgYAXNDcF+zYoSmbfdG7uM7qOPQwNRbr0pHvAg0NmtM9JOj8gZPoaeAy3
3jEk9AMQrK0MNsRynAoMkhy+7WOU6TNLvyxXAKGZffOmABzSB9LEFgHkVPutl5/i
wL2pE1SoG2QwSqFYGv+rHgIpREJzDTNwbmSbl/Za50JrIZ3OFfTMDQ==
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDITCCAgkCCQCo8H6OcPrArzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE1MDcyMzA5NTEyMloXDTI1MDQyMTA5NTEyMlowYDELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDEZMBcGA1UEAwwQYWtrYS5leGFtcGxlLm9yZzCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMy/wgrSYVhVtu9OGbo2rSKauiz
5V56X4uCqtCHF9UeHtnVtFLCBMa+pimOS+UyUAT4mbBsxW22BhoNUBZ15KPxltyD
yEsqNCKwWGxL3r8AXQtze2MEpTl22Lvp/iCTXO1vbML/+9r3uqUjw/AAP9HwF9Wd
j/yOrs6q8WE4sfc48iOj6N60/h2pRfn2WNJmo9W9FLC53NznixfsG5oN6Jmb9RM+
fMHYXLfL/Vt6NrgVX1uqHt9HvuoxfNKhhXE5VU8bNfFfzPYvIt4aZXGxO15vEqsq
OaZ7YJyKr1oFfJC8LmE5xPa3GHToCqmkdMXQK38mpslMQWlQLYnmkS5Qzv8CAwEA
ATANBgkqhkiG9w0BAQsFAAOCAQEAEPDd1gAF9q2LtoZqTdcwmeBjdbT7n0WDRSuI
BzQ/qKjvymwpFKQ0pZSPUyaw2qfRRiTQ/QTbqYep2mhvl5n+gW3ifTp83zgTGKH/
3sDlX0HPSCBYCDy2gP/AOIgV/57ADMpEkTlz8yyLMH+pLDAoNFIPwy7blAkq+ULQ
y6TfEBmZXoemSaIh5tRnexCD+pTvL4MRrGlBEoxdejDnIAt4n6BxmF0b4hKg8uta
UvivA85lBKzWUoR/Vam5/SC8jtcyLt9RThRcNSj6zP6s5d+o+8PLznrSEadAtfD9
0q+t4TYF81tClEEgGruVPNL4WIpDniOfw9AJgQNVJGfy5TKY1Q==
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA0zL/CCtJhWFW2704ZujatIpq6LPlXnpfi4Kq0IcX1R4e2dW0
UsIExr6mKY5L5TJQBPiZsGzFbbYGGg1QFnXko/GW3IPISyo0IrBYbEvevwBdC3N7
YwSlOXbYu+n+IJNc7W9swv/72ve6pSPD8AA/0fAX1Z2P/I6uzqrxYTix9zjyI6Po
3rT+HalF+fZY0maj1b0UsLnc3OeLF+wbmg3omZv1Ez58wdhct8v9W3o2uBVfW6oe
30e+6jF80qGFcTlVTxs18V/M9i8i3hplcbE7Xm8Sqyo5pntgnIqvWgV8kLwuYTnE
9rcYdOgKqaR0xdArfyamyUxBaVAtieaRLlDO/wIDAQABAoIBADfqTXkVNM7aWYut
yiv8xEJ+TxWy4ywjS/58psq0qYukANj9alNqyKbxvL5NzSwuKN9YDiCWe6KzSWRG
WAjKR7Fb+ewB+9pinxD8DT0GzT9WUkwA1A8AINpY68K8jaqEOVsnX+00prJvWfv0
vyBggIUNgtHseD2ObRuMSIHL59oivxoBKmeRqFl26PCq+m6Dp1SsMwL8NE02rfUu
uVW0zSz0/A5ZK90l8St3N78Puw/qicvfrI4PrGi4kLKW9UKJKP5FzfPF7Kf9itVA
1VB3gd8Gs98vRnzHwZlwgjyAQkePzS/iEQid9uRA/Xys5ozcT1arYM00t3I7ZEUg
GJTKHBECgYEA+K/M6smzPrTAi0BEuI1NCb3zfxkjbBhC0cco9U4VIuhYVU+7Ukre
zi5yI+BQR8MPbftSeeosXV6eQaq04pKCrHWF+ql+3Io9Hojghd/EnNCOtGxjTGmI
Px8G7byeIr4+QyP+JSEdsVBfIEEQ9BJ8Up84RibsMfWcKe6ntzAMEmkCgYEA2Wj6
DqPisPp4WwGi8bSvSRZsF3h3xu0saml+ug28j+b3kOa99Uz49kCi99sacJArYOWv
Dn+DPl2K2/lwYO0bfyXwWaLp8pd/MAmwhKZ2+qvoUnkZJFRU3yrUoPp7CURZSbcG
aD7IKotFH7wutqj8pZ50y8VGqKVACenhRSAH2ScCgYAuX7IJslUfg1tIXFK0S30r
LOXENK7bUGbdcZMcs1PTr5oRRo362YVU02prcD/oMeKlsrD9lQJy4tsGCcwzV/jQ
KhYy2PqUK58cG5AqxsCGMYn68R9PN3q1spZ7LKocdndr08FnsRY1Y3Rpslhz+yJ9
0b0Pr+BprJBTbXKPAYGuyQKBgAJFu59djSgGZi2lVburBM4Bwv13z+CvZ/Bwy9dL
/3WNl3bXQpMGy+9e+5UVoDAfAaUQoYTIRmnndmUYNVl+APSSQ/Hb5xAXD0hEQakR
SFsUYuhBxcaAbyap/vDzzUdqhHhlxlZemZ8AN6e+Qsq793APuO7MUBHBMGsqG6Wq
UQqvAoGAINEINXhFXp2qVRDBUY57rRtpjQHajeNTMChgWTg30owfVNBY4evjRj8f
9XDuUkTumYcDcnOKmX3L6n9rg4noHlfNvxmn9pmG9vP0mG0MEOOxSxXFHVIuBw10
wdTb0WE/i3FhyufdaRHLGhPAMQjaCeFSV3sMxMHuNePvCxnKD3E=
-----END RSA PRIVATE KEY-----

View file

@ -12,6 +12,7 @@ import akka.http.javadsl.testkit.JUnitRouteTest;
import akka.http.scaladsl.settings.ConnectionPoolSettings; import akka.http.scaladsl.settings.ConnectionPoolSettings;
import akka.japi.Function; import akka.japi.Function;
import akka.stream.javadsl.Flow; import akka.stream.javadsl.Flow;
import org.junit.Test;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -23,6 +24,9 @@ import java.util.concurrent.CompletionStage;
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public class HttpAPIsTest extends JUnitRouteTest { public class HttpAPIsTest extends JUnitRouteTest {
@Test
public void compileOnlyTest() {}
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void compileOnly() throws Exception { public void compileOnly() throws Exception {
final Http http = Http.get(system()); final Http http = Http.get(system());

View file

@ -1276,8 +1276,7 @@ private[stream] final class RecoverWith[T, M](maximumRetries: Int, pf: PartialFu
if ((maximumRetries == RecoverWith.InfiniteRetries || attempt < maximumRetries) && pf.isDefinedAt(ex)) { if ((maximumRetries == RecoverWith.InfiniteRetries || attempt < maximumRetries) && pf.isDefinedAt(ex)) {
switchTo(pf(ex)) switchTo(pf(ex))
attempt += 1 attempt += 1
} } else
else
failStage(ex) failStage(ex)
def switchTo(source: Graph[SourceShape[T], M]): Unit = { def switchTo(source: Graph[SourceShape[T], M]): Unit = {

View file

@ -744,6 +744,10 @@ object MiMa extends AutoPlugin {
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.scaladsl.FlowOps.recoverWithRetries") ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.scaladsl.FlowOps.recoverWithRetries")
), ),
"2.4.4" -> Seq( "2.4.4" -> Seq(
// #20371, missing method and typo in another one making it impossible to use HTTPs via setting default HttpsConnectionContext
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.http.scaladsl.HttpExt.setDefaultClientHttpsContext"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.DefaultSSLContextCreation.createServerHttpsContext"),
// #20342 HttpEntity scaladsl overrides // #20342 HttpEntity scaladsl overrides
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withoutSizeLimit"), ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withoutSizeLimit"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withSizeLimit"), ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withSizeLimit"),