=doc port over some http documentation from the scala side

This commit is contained in:
Johannes Rudolph 2015-07-10 19:13:56 +02:00
parent 16d4b4a331
commit 11d98a6593
18 changed files with 701 additions and 9 deletions

View file

@ -0,0 +1,96 @@
/*
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.http.javadsl;
import akka.actor.ActorSystem;
import akka.http.javadsl.Http;
import akka.http.javadsl.IncomingConnection;
import akka.http.javadsl.ServerBinding;
import akka.http.javadsl.model.*;
import akka.http.javadsl.model.ws.Websocket;
import akka.japi.function.Function;
import akka.japi.function.Procedure;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.javadsl.Flow;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
import org.junit.Test;
import scala.Function1;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.FiniteDuration;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;
public class HttpServerExampleSpec {
public void bindingExample() {
//#binding-example
ActorSystem system = ActorSystem.create();
Materializer materializer = ActorMaterializer.create(system);
Source<IncomingConnection, Future<ServerBinding>> serverSource =
Http.get(system).bind("localhost", 8080, materializer);
Future<ServerBinding> serverBindingFuture =
serverSource.to(Sink.foreach(
new Procedure<IncomingConnection>() {
@Override
public void apply(IncomingConnection connection) throws Exception {
System.out.println("Accepted new connection from " + connection.remoteAddress());
// ... and then actually handle the connection
}
})).run(materializer);
//#binding-example
}
public void fullServerExample() {
//#full-server-example
ActorSystem system = ActorSystem.create();
final Materializer materializer = ActorMaterializer.create(system);
Source<IncomingConnection, Future<ServerBinding>> serverSource =
Http.get(system).bind("localhost", 8080, materializer);
final Function<HttpRequest, HttpResponse> requestHandler =
new Function<HttpRequest, HttpResponse>() {
private final HttpResponse NOT_FOUND =
HttpResponse.create()
.withStatus(404)
.withEntity("Unknown resource!");
@Override
public HttpResponse apply(HttpRequest request) throws Exception {
if (request.method() == HttpMethods.GET) {
if (request.getUri().path().equals("/"))
return
HttpResponse.create()
.withEntity(MediaTypes.TEXT_HTML.toContentType(),
"<html><body>Hello world!</body></html>");
else if (request.getUri().path().equals("/ping"))
return HttpResponse.create().withEntity("PONG!");
else
return NOT_FOUND;
}
else return NOT_FOUND;
}
};
Future<ServerBinding> serverBindingFuture =
serverSource.to(Sink.foreach(
new Procedure<IncomingConnection>() {
@Override
public void apply(IncomingConnection connection) throws Exception {
System.out.println("Accepted new connection from " + connection.remoteAddress());
connection.handleWithSyncHandler(requestHandler, materializer);
// this is equivalent to
//connection.handleWith(Flow.of(HttpRequest.class).map(requestHandler), materializer);
}
})).run(materializer);
//#full-server-example
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.http.javadsl;
import akka.japi.Option;
import akka.util.ByteString;
import org.junit.Test;
//#import-model
import akka.http.javadsl.model.*;
import akka.http.javadsl.model.headers.*;
//#import-model
public class ModelSpec {
@Test
public void testConstructRequest() {
//#construct-request
// construct a simple GET request to `homeUri`
Uri homeUri = Uri.create("/home");
HttpRequest request1 = HttpRequest.create().withUri(homeUri);
// construct simple GET request to "/index" using helper methods
HttpRequest request2 = HttpRequest.GET("/index");
// construct simple POST request containing entity
ByteString data = ByteString.fromString("abc");
HttpRequest postRequest1 = HttpRequest.POST("/receive").withEntity(data);
// customize every detail of HTTP request
//import HttpProtocols._
//import MediaTypes._
Authorization authorization = Authorization.basic("user", "pass");
HttpRequest complexRequest =
HttpRequest.PUT("/user")
.withEntity(HttpEntities.create(MediaTypes.TEXT_PLAIN.toContentType(), "abc"))
.addHeader(authorization)
.withProtocol(HttpProtocols.HTTP_1_0);
//#construct-request
}
@Test
public void testConstructResponse() {
//#construct-response
// simple OK response without data created using the integer status code
HttpResponse ok = HttpResponse.create().withStatus(200);
// 404 response created using the named StatusCode constant
HttpResponse notFound = HttpResponse.create().withStatus(StatusCodes.NOT_FOUND);
// 404 response with a body explaining the error
HttpResponse notFoundCustom =
HttpResponse.create()
.withStatus(404)
.withEntity("Unfortunately, the resource couldn't be found.");
// A redirecting response containing an extra header
Location locationHeader = Location.create("http://example.com/other");
HttpResponse redirectResponse =
HttpResponse.create()
.withStatus(StatusCodes.FOUND)
.addHeader(locationHeader);
//#construct-response
}
@Test
public void testDealWithHeaders() {
//#headers
// create a ``Location`` header
Location locationHeader = Location.create("http://example.com/other");
// create an ``Authorization`` header with HTTP Basic authentication data
Authorization authorization = Authorization.basic("user", "pass");
//#headers
}
//#headers
// a method that extracts basic HTTP credentials from a request
private Option<BasicHttpCredentials> getCredentialsOfRequest(HttpRequest request) {
Option<Authorization> auth = request.getHeader(Authorization.class);
if (auth.isDefined() && auth.get().credentials() instanceof BasicHttpCredentials)
return Option.some((BasicHttpCredentials) auth.get().credentials());
else
return Option.none();
}
//#headers
}

View file

@ -0,0 +1,4 @@
.. _ConnectionLevelApi-java:
Connection-Level Client-Side API
================================

View file

@ -0,0 +1,4 @@
.. _HostLevelApi-java:
Host-Level Client-Side API
==========================

View file

@ -0,0 +1,4 @@
.. _clientSideHTTPS-java:
Client-Side HTTPS Support
=========================

View file

@ -0,0 +1,15 @@
.. _http-client-side-java:
Consuming HTTP-based Services (Client-Side)
===========================================
...
.. toctree::
:maxdepth: 2
connection-level
host-level
request-level
https-support
websocket-support

View file

@ -0,0 +1,6 @@
.. _RequestLevelApi-java:
Request-Level Client-Side API
=============================
...

View file

@ -0,0 +1,4 @@
Client-Side WebSocket Support
=============================
TODO

View file

@ -0,0 +1,28 @@
.. _akka-http-configuration-java:
Configuration
=============
Just like any other Akka module Akka HTTP is configured via `Typesafe Config`_.
Usually this means that you provide an ``application.conf`` which contains all the application-specific settings that
differ from the default ones provided by the reference configuration files from the individual Akka modules.
These are the relevant default configuration values for the Akka HTTP modules.
akka-http-core
~~~~~~~~~~~~~~
.. literalinclude:: ../../../../akka-http-core/src/main/resources/reference.conf
:language: none
akka-http
~~~~~~~~~
.. literalinclude:: ../../../../akka-http/src/main/resources/reference.conf
:language: none
The other Akka HTTP modules do not offer any configuration via `Typesafe Config`_.
.. _Typesafe Config: https://github.com/typesafehub/config

View file

@ -0,0 +1,233 @@
.. _http-model-java:
HTTP Model
==========
Akka HTTP model contains a deeply structured, fully immutable, case-class based model of all the major HTTP data
structures, like HTTP requests, responses and common headers.
It lives in the *akka-http-core* module and forms the basis for most of Akka HTTP's APIs.
Overview
--------
Since akka-http-core provides the central HTTP data structures you will find the following import in quite a
few places around the code base (and probably your own code as well):
.. includecode:: ../code/docs/http/javadsl/ModelSpec.java
:include: import-model
This brings all of the most relevant types in scope, mainly:
- ``HttpRequest`` and ``HttpResponse``, the central message model
- ``headers``, the package containing all the predefined HTTP header models and supporting types
- Supporting types like ``Uri``, ``HttpMethods``, ``MediaTypes``, ``StatusCodes``, etc.
A common pattern is that the model of a certain entity is represented by an immutable type (class or trait),
while the actual instances of the entity defined by the HTTP spec live in an accompanying object carrying the name of
the type plus a trailing plural 's'.
For example:
- Defined ``HttpMethod`` instances are defined as static fields of the ``HttpMethods`` class.
- Defined ``HttpCharset`` instances are defined as static fields of the ``HttpCharsets`` class.
- Defined ``HttpEncoding`` instances are defined as static fields of the ``HttpEncodings`` class.
- Defined ``HttpProtocol`` instances are defined as static fields of the ``HttpProtocols`` class.
- Defined ``MediaType`` instances are defined as static fields of the ``MediaTypes`` class.
- Defined ``StatusCode`` instances are defined as static fields of the ``StatusCodes`` class.
HttpRequest
-----------
``HttpRequest`` and ``HttpResponse`` are the basic immutable classes representing HTTP messages.
An ``HttpRequest`` consists of
- a method (GET, POST, etc.)
- a URI
- a seq of headers
- an entity (body data)
- a protocol
Here are some examples how to construct an ``HttpRequest``:
.. includecode:: ../code/docs/http/javadsl/ModelSpec.java
:include: construct-request
In its basic form ``HttpRequest.create`` creates an empty default GET request without headers which can then be
transformed using one of the ``withX`` methods, ``addHeader``, or ``addHeaders``. Each of those will create a
new immutable instance, so instances can be shared freely. There exist some overloads for ``HttpRequest.create`` that
simplify creating requests for common cases. Also, to aid readability, there are predefined alternatives for ``create``
named after HTTP methods to create a request with a given method and uri directly.
HttpResponse
------------
An ``HttpResponse`` consists of
- a status code
- a list of headers
- an entity (body data)
- a protocol
Here are some examples how to construct an ``HttpResponse``:
.. includecode:: ../code/docs/http/javadsl/ModelSpec.java
:include: construct-response
In addition to the simple ``HttpEntities.create`` methods which create an entity from a fixed ``String`` or ``ByteString``
as shown here the Akka HTTP model defines a number of subclasses of ``HttpEntity`` which allow body data to be specified as a
stream of bytes. All of these types can be created using the method on ``HttpEntites``.
.. _HttpEntity-java:
HttpEntity
----------
An ``HttpEntity`` carries the data bytes of a message together with its Content-Type and, if known, its Content-Length.
In Akka HTTP there are five different kinds of entities which model the various ways that message content can be
received or sent:
HttpEntityStrict
The simplest entity, which is used when all the entity are already available in memory.
It wraps a plain ``ByteString`` and represents a standard, unchunked entity with a known ``Content-Length``.
HttpEntityDefault
The general, unchunked HTTP/1.1 message entity.
It has a known length and presents its data as a ``Source[ByteString]`` which can be only materialized once.
It is an error if the provided source doesn't produce exactly as many bytes as specified.
The distinction of ``HttpEntityStrict`` and ``HttpEntityDefault`` is an API-only one. One the wire,
both kinds of entities look the same.
HttpEntityChunked
The model for HTTP/1.1 `chunked content`__ (i.e. sent with ``Transfer-Encoding: chunked``).
The content length is unknown and the individual chunks are presented as a ``Source[ChunkStreamPart]``.
A ``ChunkStreamPart`` is either a non-empty chunk or the empty last chunk containing optional trailer headers.
The stream consists of zero or more non-empty chunks parts and can be terminated by an optional last chunk.
HttpEntityCloseDelimited
An unchunked entity of unknown length that is implicitly delimited by closing the connection (``Connection: close``).
Content data is presented as a ``Source[ByteString]``.
Since the connection must be closed after sending an entity of this type it can only be used on the server-side for
sending a response.
Also, the main purpose of ``CloseDelimited`` entities is compatibility with HTTP/1.0 peers, which do not support
chunked transfer encoding. If you are building a new application and are not constrained by legacy requirements you
shouldn't rely on ``CloseDelimited`` entities, since implicit terminate-by-connection-close is not a robust way of
signaling response end, especially in the presence of proxies. Additionally this type of entity prevents connection
reuse which can seriously degrade performance. Use ``HttpEntityChunked`` instead!
HttpEntityIndefiniteLength
A streaming entity of unspecified length for use in a ``Multipart.BodyPart``.
__ http://tools.ietf.org/html/rfc7230#section-4.1
Entity types ``HttpEntityStrict``, ``HttpEntityDefault``, and ``HttpEntityChunked`` are a subtype of ``RequestEntity``
which allows to use them for requests and responses. In contrast, ``HttpEntityCloseDelimited`` can only be used for responses.
Streaming entity types (i.e. all but ``HttpEntityStrict``) cannot be shared or serialized. To create a strict, sharable copy of an
entity or message use ``HttpEntity.toStrict`` or ``HttpMessage.toStrict`` which returns a ``Future`` of the object with
the body data collected into a ``ByteString``.
The class ``HttpEntities`` contains static methods to create entities from common types easily.
You can use the ``isX` methods of ``HttpEntity`` to find out of which subclass an entity is if you want to provide
special handling for each of the subtypes. However, in many cases a recipient of an ``HttpEntity`` doesn't care about
of which subtype an entity is (and how data is transported exactly on the HTTP layer). Therefore, a general
``HttpEntity::getDataBytes: Source<ByteString, ?>`` is provided which allows access to the data of an entity regardless
of its concrete subtype.
.. note::
When to use which subtype?
- Use ``HttpEntityStrict`` if the amount of data is "small" and already available in memory (e.g. as a ``String`` or ``ByteString``)
- Use ``HttpEntityDefault`` if the data is generated by a streaming data source and the size of the data is known
- Use ``HttpEntityChunked`` for an entity of unknown length
- Use ``HttpEntityCloseDelimited`` for a response as a legacy alternative to ``HttpEntityChunked`` if the client
doesn't support chunked transfer encoding. Otherwise use ``HttpEntityChunked``!
- In a ``Multipart.Bodypart`` use ``HttpEntityIndefiniteLength`` for content of unknown length.
.. caution::
When you receive a non-strict message from a connection then additional data is only read from the network when you
request it by consuming the entity data stream. This means that, if you *don't* consume the entity stream then the
connection will effectively be stalled. In particular, no subsequent message (request or response) will be read from
the connection as the entity of the current message "blocks" the stream.
Therefore you must make sure that you always consume the entity data, even in the case that you are not actually
interested in it!
Header Model
------------
Akka HTTP contains a rich model of the most common HTTP headers. Parsing and rendering is done automatically so that
applications don't need to care for the actual syntax of headers. Headers not modelled explicitly are represented
as a ``RawHeader`` (which is essentially a String/String name/value pair).
See these examples of how to deal with headers:
.. includecode:: ../code/docs/http/javadsl/ModelSpec.java
:include: headers
HTTP Headers
------------
When the Akka HTTP server receives an HTTP request it tries to parse all its headers into their respective
model classes. Independently of whether this succeeds or not, the HTTP layer will
always pass on all received headers to the application. Unknown headers as well as ones with invalid syntax (according
to the header parser) will be made available as ``RawHeader`` instances. For the ones exhibiting parsing errors a
warning message is logged depending on the value of the ``illegal-header-warnings`` config setting.
Some headers have special status in HTTP and are therefore treated differently from "regular" headers:
Content-Type
The Content-Type of an HTTP message is modeled as the ``contentType`` field of the ``HttpEntity``.
The ``Content-Type`` header therefore doesn't appear in the ``headers`` sequence of a message.
Also, a ``Content-Type`` header instance that is explicitly added to the ``headers`` of a request or response will
not be rendered onto the wire and trigger a warning being logged instead!
Transfer-Encoding
Messages with ``Transfer-Encoding: chunked`` are represented as a ``HttpEntityChunked`` entity.
As such chunked messages that do not have another deeper nested transfer encoding will not have a ``Transfer-Encoding``
header in their ``headers`` list.
Similarly, a ``Transfer-Encoding`` header instance that is explicitly added to the ``headers`` of a request or
response will not be rendered onto the wire and trigger a warning being logged instead!
Content-Length
The content length of a message is modelled via its :ref:`HttpEntity-java`. As such no ``Content-Length`` header will ever
be part of a message's ``header`` sequence.
Similarly, a ``Content-Length`` header instance that is explicitly added to the ``headers`` of a request or
response will not be rendered onto the wire and trigger a warning being logged instead!
Server
A ``Server`` header is usually added automatically to any response and its value can be configured via the
``akka.http.server.server-header`` setting. Additionally an application can override the configured header with a
custom one by adding it to the response's ``header`` sequence.
User-Agent
A ``User-Agent`` header is usually added automatically to any request and its value can be configured via the
``akka.http.client.user-agent-header`` setting. Additionally an application can override the configured header with a
custom one by adding it to the request's ``header`` sequence.
Date
The ``Date`` response header is added automatically but can be overridden by supplying it manually.
Connection
On the server-side Akka HTTP watches for explicitly added ``Connection: close`` response headers and as such honors
the potential wish of the application to close the connection after the respective response has been sent out.
The actual logic for determining whether to close the connection is quite involved. It takes into account the
request's method, protocol and potential ``Connection`` header as well as the response's protocol, entity and
potential ``Connection`` header. See `this test`__ for a full table of what happens when.
__ @github@/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala#L422
Parsing / Rendering
-------------------
Parsing and rendering of HTTP data structures is heavily optimized and for most types there's currently no public API
provided to parse (or render to) Strings or byte arrays.

View file

@ -3,4 +3,12 @@
Akka HTTP Akka HTTP
========= =========
... .. toctree::
:maxdepth: 2
introduction
configuration
http-model
low-level-server-side-api
routing-dsl/index
client-side/index

View file

@ -0,0 +1,28 @@
Introduction
============
The Akka HTTP modules implement a full server- and client-side HTTP stack on top of *akka-actor* and *akka-stream*. It's
not a web-framework but rather a more general toolkit for providing and consuming HTTP-based services. While interaction
with a browser is of course also in scope it is not the primary focus of Akka HTTP.
Akka HTTP follows a rather open design and many times offers several different API levels for "doing the same thing".
You get to pick the API level of abstraction that is most suitable for your application.
This means that, if you have trouble achieving something using a high-level API, there's a good chance that you can get
it done with a low-level API, which offers more flexibility but might require you do write more application code.
Akka HTTP is structured into several modules:
akka-http-core
A complete, mostly low-level, server- and client-side implementation of HTTP (incl. WebSockets)
akka-http
Higher-level functionality, like (un)marshalling, (de)compression as well as a powerful DSL
for defining HTTP-based APIs on the server-side
akka-http-testkit
A test harness and set of utilities for verifying server-side service implementations
akka-http-jackson
Predefined glue-code for (de)serializing custom types from/to JSON with jackson_
.. _jackson: https://github.com/FasterXML/jackson

View file

@ -0,0 +1,154 @@
.. _http-low-level-server-side-api-java:
Low-Level Server-Side API
=========================
Apart from the :ref:`HTTP Client <http-client-side-java>` Akka HTTP also provides an embedded,
`Reactive-Streams`_-based, fully asynchronous HTTP/1.1 server implemented on top of :ref:`Akka Stream <streams-java>`.
It sports the following features:
- Full support for `HTTP persistent connections`_
- Full support for `HTTP pipelining`_
- Full support for asynchronous HTTP streaming including "chunked" transfer encoding accessible through an idiomatic API
- Optional SSL/TLS encryption
- Websocket support
.. _HTTP persistent connections: http://en.wikipedia.org/wiki/HTTP_persistent_connection
.. _HTTP pipelining: http://en.wikipedia.org/wiki/HTTP_pipelining
.. _Reactive-Streams: http://www.reactive-streams.org/
The server-side components of Akka HTTP are split into two layers:
1. The basic low-level server implementation in the ``akka-http-core`` module
2. Higher-level functionality in the ``akka-http`` module
The low-level server (1) is scoped with a clear focus on the essential functionality of an HTTP/1.1 server:
- Connection management
- Parsing and rendering of messages and headers
- Timeout management (for requests and connections)
- Response ordering (for transparent pipelining support)
All non-core features of typical HTTP servers (like request routing, file serving, compression, etc.) are left to
the higher layers, they are not implemented by the ``akka-http-core``-level server itself.
Apart from general focus this design keeps the server core small and light-weight as well as easy to understand and
maintain.
Depending on your needs you can either use the low-level API directly or rely on the high-level
:ref:`Routing DSL <http-high-level-server-side-api-java>` which can make the definition of more complex service logic much
easier.
Streams and HTTP
----------------
The Akka HTTP server is implemented on top of :ref:`Akka Stream <streams-java>` and makes heavy use of it - in its
implementation as well as on all levels of its API.
On the connection level Akka HTTP offers basically the same kind of interface as :ref:`Akka Stream IO <stream-io-java>`:
A socket binding is represented as a stream of incoming connections. The application pulls connections from this stream
source and, for each of them, provides a ``Flow<HttpRequest, HttpResponse, ?>`` to "translate" requests into responses.
Apart from regarding a socket bound on the server-side as a ``Source<IncomingConnection>`` and each connection as a
``Source<HttpRequest>`` with a ``Sink<HttpResponse>`` the stream abstraction is also present inside a single HTTP
message: The entities of HTTP requests and responses are generally modeled as a ``Source<ByteString>``. See also
the :ref:`http-model-java` for more information on how HTTP messages are represented in Akka HTTP.
Starting and Stopping
---------------------
On the most basic level an Akka HTTP server is bound by invoking the ``bind`` method of the `akka.http.javadsl.Http`_
extension:
.. includecode:: ../code/docs/http/javadsl/HttpServerExampleSpec.java
:include: binding-example
Arguments to the ``Http().bind`` method specify the interface and port to bind to and register interest in handling
incoming HTTP connections. Additionally, the method also allows for the definition of socket options as well as a larger
number of settings for configuring the server according to your needs.
The result of the ``bind`` method is a ``Source<Http.IncomingConnection>`` which must be drained by the application in
order to accept incoming connections.
The actual binding is not performed before this source is materialized as part of a processing pipeline. In
case the bind fails (e.g. because the port is already busy) the materialized stream will immediately be terminated with
a respective exception.
The binding is released (i.e. the underlying socket unbound) when the subscriber of the incoming
connection source has cancelled its subscription. Alternatively one can use the ``unbind()`` method of the
``Http.ServerBinding`` instance that is created as part of the connection source's materialization process.
The ``Http.ServerBinding`` also provides a way to get a hold of the actual local address of the bound socket, which is
useful for example when binding to port zero (and thus letting the OS pick an available port).
.. _akka.http.javadsl.Http: @github@/akka-http-core/src/main/scala/akka/http/javadsl/Http.scala
Request-Response Cycle
----------------------
When a new connection has been accepted it will be published as an ``Http.IncomingConnection`` which consists
of the remote address and methods to provide a ``Flow<HttpRequest, HttpResponse, ?>`` to handle requests coming in over
this connection.
Requests are handled by calling one of the ``handleWithXXX`` methods with a handler, which can either be
- a ``Flow<HttpRequest, HttpResponse, ?>`` for ``handleWith``,
- a function ``Function<HttpRequest, HttpResponse>`` for ``handleWithSyncHandler``,
- a function ``Function<HttpRequest, Future<HttpResponse>>`` for ``handleWithAsyncHandler``.
Here is a complete example:
.. includecode:: ../code/docs/http/javadsl/HttpServerExampleSpec.java
:include: full-server-example
In this example, a request is handled by transforming the request stream with a function ``Function<HttpRequest, HttpResponse>``
using ``handleWithSyncHandler`` (or equivalently, Akka Stream's ``map`` operator). Depending on the use case many
other ways of providing a request handler are conceivable using Akka Stream's combinators.
If the application provides a ``Flow`` it is also the responsibility of the application to generate exactly one response
for every request and that the ordering of responses matches the ordering of the associated requests (which is relevant
if HTTP pipelining is enabled where processing of multiple incoming requests may overlap). When relying on
``handleWithSyncHandler`` or ``handleWithAsyncHandler``, or the ``map`` or ``mapAsync`` stream operators, this
requirement will be automatically fulfilled.
Streaming Request/Response Entities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Streaming of HTTP message entities is supported through subclasses of ``HttpEntity``. The application needs to be able
to deal with streamed entities when receiving a request as well as, in many cases, when constructing responses.
See :ref:`HttpEntity-java` for a description of the alternatives.
Closing a connection
~~~~~~~~~~~~~~~~~~~~
The HTTP connection will be closed when the handling ``Flow`` cancels its upstream subscription or the peer closes the
connection. An often times more convenient alternative is to explicitly add a ``Connection: close`` header to an
``HttpResponse``. This response will then be the last one on the connection and the server will actively close the
connection when it has been sent out.
.. _serverSideHTTPS-java:
Server-Side HTTPS Support
-------------------------
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS-java>`.
The central vehicle for configuring encryption is the ``HttpsContext``, which can be created using ``HttpsContext.create``
which is defined like this:
.. includecode:: /../../akka-http-core/src/main/java/akka/http/javadsl/HttpsContext.java
:include: http-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).
Stand-Alone HTTP Layer Usage
----------------------------
// TODO

View file

@ -0,0 +1,11 @@
.. _http-high-level-server-side-api-java:
High-level Server-Side API
==========================
...
.. toctree::
:maxdepth: 1
overview

View file

@ -0,0 +1,4 @@
Routing DSL Overview
====================
...

View file

@ -72,8 +72,8 @@ Here are some examples how to construct an ``HttpResponse``:
.. includecode:: ../../code/docs/http/scaladsl/ModelSpec.scala .. includecode:: ../../code/docs/http/scaladsl/ModelSpec.scala
:include: construct-response :include: construct-response
In addition to the simple ``HttpEntity`` constructors create an entity from a fixed ``String`` or ``ByteString`` shown In addition to the simple ``HttpEntity`` constructors which create an entity from a fixed ``String`` or ``ByteString``
as here the Akka HTTP model defines a number of subclasses of ``HttpEntity`` which allow body data to be specified as a as shown here the Akka HTTP model defines a number of subclasses of ``HttpEntity`` which allow body data to be specified as a
stream of bytes. stream of bytes.
@ -93,9 +93,9 @@ HttpEntity.Strict
HttpEntity.Default HttpEntity.Default
The general, unchunked HTTP/1.1 message entity. The general, unchunked HTTP/1.1 message entity.
It has a known length and presents its data as a ``Source[ByteString]`` which can only materialized once. It has a known length and presents its data as a ``Source[ByteString]`` which can be only materialized once.
It is an error if the provided source doesn't produce exactly as many bytes as specified. It is an error if the provided source doesn't produce exactly as many bytes as specified.
On the wire, a ``Strict`` entity and a ``Default`` entity cannot be distinguished. The distinction of ``Strict`` and ``Default`` is an API-only one. One the wire, both kinds of entities look the same.
HttpEntity.Chunked HttpEntity.Chunked

View file

@ -12,6 +12,7 @@ It sports the following features:
- Full support for `HTTP pipelining`_ - Full support for `HTTP pipelining`_
- Full support for asynchronous HTTP streaming including "chunked" transfer encoding accessible through an idiomatic API - Full support for asynchronous HTTP streaming including "chunked" transfer encoding accessible through an idiomatic API
- Optional SSL/TLS encryption - Optional SSL/TLS encryption
- Websocket support
.. _HTTP persistent connections: http://en.wikipedia.org/wiki/HTTP_persistent_connection .. _HTTP persistent connections: http://en.wikipedia.org/wiki/HTTP_persistent_connection
.. _HTTP pipelining: http://en.wikipedia.org/wiki/HTTP_pipelining .. _HTTP pipelining: http://en.wikipedia.org/wiki/HTTP_pipelining
@ -26,7 +27,7 @@ The server-side components of Akka HTTP are split into two layers:
The low-level server (1) is scoped with a clear focus on the essential functionality of an HTTP/1.1 server: The low-level server (1) is scoped with a clear focus on the essential functionality of an HTTP/1.1 server:
- Connection management - Connection management
- Parsing messages and headers - Parsing and rendering of messages and headers
- Timeout management (for requests and connections) - Timeout management (for requests and connections)
- Response ordering (for transparent pipelining support) - Response ordering (for transparent pipelining support)

View file

@ -23,13 +23,16 @@ public abstract class HttpsContext {
public abstract Option<ClientAuth> getClientAuth(); public abstract Option<ClientAuth> getClientAuth();
public abstract Option<SSLParameters> getSslParameters(); public abstract Option<SSLParameters> getSslParameters();
//#http-context-creation
public static HttpsContext create(SSLContext sslContext, public static HttpsContext create(SSLContext sslContext,
Option<Collection<String>> enabledCipherSuites, Option<Collection<String>> enabledCipherSuites,
Option<Collection<String>> enabledProtocols, Option<Collection<String>> enabledProtocols,
Option<ClientAuth> clientAuth, Option<ClientAuth> clientAuth,
Option<SSLParameters> sslParameters) { Option<SSLParameters> sslParameters)
//#http-context-creation
{
return akka.http.scaladsl.HttpsContext.create(sslContext, enabledCipherSuites, enabledProtocols, return akka.http.scaladsl.HttpsContext.create(sslContext, enabledCipherSuites, enabledProtocols,
clientAuth, sslParameters); clientAuth, sslParameters);
} }
} }