Packages
ace
0.16.3
0.19.0
0.18.10
0.18.9
0.18.8
0.18.7
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.1
0.17.0
0.16.8
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
retired
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
retired
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.0
0.3.0
0.2.0
HTTP web server and client, supports http1 and http2
Current section
Files
Jump to
Current section
Files
README.md
# Ace
**HTTP web server and client, supports http1 and http2**
[](https://hex.pm/packages/ace)
[](https://travis-ci.org/CrowdHailer/Ace)
[](LICENSE)
- [Install from Hex](https://hex.pm/packages/ace)
- [Documentation available on hexdoc](https://hexdocs.pm/ace)
- [Discuss on slack](https://elixir-lang.slack.com/messages/C56H3TBH8/)
## Get started
#### Hello, World!
```elixir
defmodule MyApp do
use Ace.HTTP.Service, [port: 8080, cleartext: true]
@impl Raxx.Server
def handle_request(%{method: :GET, path: []}, %{greeting: greeting}) do
response(:ok)
|> set_header("content-type", "text/plain")
|> set_body("#{greeting}, World!")
end
end
```
*The arguments given to use Ace.HTTP.Service are default values when starting the service.*
#### Start the service
```elixir
config = %{greeting: "Hello"}
MyApp.start_link(config, [port: 1234])
```
*Here the default port value has been overridden at startup*
#### Raxx
Ace implements the Raxx HTTP interface.
This allows applications to be built with any components from the Raxx ecosystem.
Raxx has tooling for streaming, server-push, routing, api documentation and more. See [documentation](https://hexdocs.pm/raxx/readme.html) for details.
*The correct version of raxx is included with ace, raxx does not need to be added as a dependency.*
#### TLS/SSL
If a service is started without the `cleartext` it will start using TLS. This requires a certificate and key.
```elixir
config = %{greeting: "Hello"}
options = [port: 8443, certfile: "path/to/certificate", keyfile: "path/to/key"]
MyApp.start_link(application, options)
```
*TLS is required to serve content via HTTP/2.*
#### Supervising services
The normal way to run services is as part of a projects supervision tree. When starting a new project use the `--sup` flag.
```sh
mix new my_app --sup
```
Add the services to be supervised in the application file `lib/my_app/application.ex`.
```elixir
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(MyApp, [%{greeting: "Hello"}]),
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
```
Start project using `iex -S mix` and visit [http://localhost:8080](http://localhost:8080).
## Features
- [x] Consistent server and client interfaces
- [x] Stream isolation; one process per stream
- [x] Bidirectional streaming; send and receive streamed data
- [x] Server push; to reduce latency
- [x] Automatic flow control; at stream and connection level
- [x] Secure data transport; TLS(SSL) support via ALPN
- [x] Verified against [h2spec](https://github.com/summerwind/h2spec) (*143/146*)
- [x] Simple request/response interactions; [Raxx](https://github.com/crowdhailer/raxx) interface
- [x] HTTP upgrade mechanisms
- [ ] HTTP/1.1 pipelining
*View progress on the [roadmap](https://github.com/CrowdHailer/Ace/projects/1).*
## Testing
Run [h2spec](https://github.com/summerwind/h2spec) against the example `hello_http2` application.
1. Start the example app.
```
cd examples/hello_http2
iex -S mix
```
2. Run h2spec from docker
```
sudo docker run --net="host" summerwind/h2spec --port 8443 -t -k -S
```