This commit is contained in:
parent
b983f19c1f
commit
0e11ec2057
28 changed files with 674 additions and 120 deletions
|
|
@ -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);
|
||||||
|
//#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
92
akka-docs/rst/java/http/server-side-https-support.rst
Normal file
92
akka-docs/rst/java/http/server-side-https-support.rst
Normal 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
|
||||||
|
|
@ -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)
|
||||||
|
//#
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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:
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 we’d 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 we’d 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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
||||||
101
akka-docs/rst/scala/http/server-side-https-support.rst
Normal file
101
akka-docs/rst/scala/http/server-side-https-support.rst
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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._
|
||||||
|
|
|
||||||
|
|
@ -4,94 +4,157 @@
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
public class SimpleServerApp extends HttpApp {
|
public class SimpleServerApp extends HttpApp {
|
||||||
static Parameter<Integer> x = Parameters.intValue("x");
|
static Parameter<Integer> x = Parameters.intValue("x");
|
||||||
static Parameter<Integer> y = Parameters.intValue("y");
|
static Parameter<Integer> y = Parameters.intValue("y");
|
||||||
|
|
||||||
static PathMatcher<Integer> xSegment = PathMatchers.intValue();
|
static PathMatcher<Integer> xSegment = PathMatchers.intValue();
|
||||||
static PathMatcher<Integer> ySegment = PathMatchers.intValue();
|
static PathMatcher<Integer> ySegment = PathMatchers.intValue();
|
||||||
|
|
||||||
static RequestVal<String> bodyAsName = RequestVals.entityAs(Unmarshallers.String());
|
static RequestVal<String> bodyAsName = RequestVals.entityAs(Unmarshallers.String());
|
||||||
|
|
||||||
public static RouteResult multiply(RequestContext ctx, int x, int y) {
|
public static RouteResult multiply(RequestContext ctx, int x, int y) {
|
||||||
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) {
|
|
||||||
return CompletableFuture.supplyAsync(() -> multiply(ctx, x, y), ctx.executionContext());
|
public static CompletionStage<RouteResult> multiplyAsync(final RequestContext ctx, final int x, final int y) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> multiply(ctx, x, y), ctx.executionContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Route createRoute() {
|
||||||
|
Handler addHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public RouteResult apply(RequestContext ctx) {
|
||||||
|
int xVal = x.get(ctx);
|
||||||
|
int yVal = y.get(ctx);
|
||||||
|
int result = xVal + yVal;
|
||||||
|
return ctx.complete(String.format("%d + %d = %d", xVal, yVal, result));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Handler2<Integer, Integer> subtractHandler = new Handler2<Integer, Integer>() {
|
||||||
|
public RouteResult apply(RequestContext ctx, Integer xVal, Integer yVal) {
|
||||||
|
int result = xVal - yVal;
|
||||||
|
return ctx.complete(String.format("%d - %d = %d", xVal, yVal, result));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Handler1<String> helloPostHandler =
|
||||||
|
new Handler1<String>() {
|
||||||
|
@Override
|
||||||
|
public RouteResult apply(RequestContext ctx, String s) {
|
||||||
|
return ctx.complete("Hello " + s + "!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return
|
||||||
|
route(
|
||||||
|
// matches the empty path
|
||||||
|
pathSingleSlash().route(
|
||||||
|
getFromResource("web/calculator.html")
|
||||||
|
),
|
||||||
|
// matches paths like this: /add?x=42&y=23
|
||||||
|
path("add").route(
|
||||||
|
handleWith(addHandler, x, y)
|
||||||
|
),
|
||||||
|
path("subtract").route(
|
||||||
|
handleWith2(x, y, subtractHandler)
|
||||||
|
),
|
||||||
|
// matches paths like this: /multiply/{x}/{y}
|
||||||
|
path("multiply", xSegment, ySegment).route(
|
||||||
|
// bind handler by reflection
|
||||||
|
handleReflectively(SimpleServerApp.class, "multiply", xSegment, ySegment)
|
||||||
|
),
|
||||||
|
path("multiplyAsync", xSegment, ySegment).route(
|
||||||
|
// bind async handler by reflection
|
||||||
|
handleReflectively(SimpleServerApp.class, "multiplyAsync", xSegment, ySegment)
|
||||||
|
),
|
||||||
|
post(
|
||||||
|
path("hello").route(
|
||||||
|
handleWith1(bodyAsName, helloPostHandler)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ** STARTING THE SERVER ** //
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
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);
|
||||||
|
|
||||||
|
System.out.println("Type RETURN to exit");
|
||||||
|
System.in.read();
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public Route createRoute() {
|
//#
|
||||||
Handler addHandler = new Handler() {
|
|
||||||
@Override
|
|
||||||
public RouteResult apply(RequestContext ctx) {
|
|
||||||
int xVal = x.get(ctx);
|
|
||||||
int yVal = y.get(ctx);
|
|
||||||
int result = xVal + yVal;
|
|
||||||
return ctx.complete(String.format("%d + %d = %d", xVal, yVal, result));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handler2<Integer, Integer> subtractHandler = new Handler2<Integer, Integer>() {
|
|
||||||
public RouteResult apply(RequestContext ctx, Integer xVal, Integer yVal) {
|
|
||||||
int result = xVal - yVal;
|
|
||||||
return ctx.complete(String.format("%d - %d = %d", xVal, yVal, result));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handler1<String> helloPostHandler =
|
|
||||||
new Handler1<String>() {
|
|
||||||
@Override
|
|
||||||
public RouteResult apply(RequestContext ctx, String s) {
|
|
||||||
return ctx.complete("Hello " + s + "!");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return
|
|
||||||
route(
|
|
||||||
// matches the empty path
|
|
||||||
pathSingleSlash().route(
|
|
||||||
getFromResource("web/calculator.html")
|
|
||||||
),
|
|
||||||
// matches paths like this: /add?x=42&y=23
|
|
||||||
path("add").route(
|
|
||||||
handleWith(addHandler, x, y)
|
|
||||||
),
|
|
||||||
path("subtract").route(
|
|
||||||
handleWith2(x, y, subtractHandler)
|
|
||||||
),
|
|
||||||
// matches paths like this: /multiply/{x}/{y}
|
|
||||||
path("multiply", xSegment, ySegment).route(
|
|
||||||
// bind handler by reflection
|
|
||||||
handleReflectively(SimpleServerApp.class, "multiply", xSegment, ySegment)
|
|
||||||
),
|
|
||||||
path("multiplyAsync", xSegment, ySegment).route(
|
|
||||||
// bind async handler by reflection
|
|
||||||
handleReflectively(SimpleServerApp.class, "multiplyAsync", xSegment, ySegment)
|
|
||||||
),
|
|
||||||
post(
|
|
||||||
path("hello").route(
|
|
||||||
handleWith1(bodyAsName, helloPostHandler)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
ActorSystem system = ActorSystem.create();
|
|
||||||
new SimpleServerApp().bindRoute("localhost", 8080, system);
|
|
||||||
System.out.println("Type RETURN to exit");
|
|
||||||
System.in.read();
|
|
||||||
system.terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
||||||
|
```
|
||||||
|
|
@ -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-----
|
||||||
|
|
@ -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-----
|
||||||
|
|
@ -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-----
|
||||||
|
|
@ -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-----
|
||||||
|
|
@ -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-----
|
||||||
BIN
akka-http-tests/src/main/resources/httpsDemoKeys/keys/server.p12
Normal file
BIN
akka-http-tests/src/main/resources/httpsDemoKeys/keys/server.p12
Normal file
Binary file not shown.
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue