Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for server push usage #1190

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/ssl_push/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PROJECT = ssl_push
PROJECT_DESCRIPTION = Cowboy HTTP/2 push example
PROJECT_VERSION = 1

DEPS = cowboy
LOCAL_DEPS = ssl
dep_cowboy_commit = master

include ../../erlang.mk
122 changes: 122 additions & 0 deletions examples/ssl_push/README.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
= HTTP/2 push example

To try this example, you need GNU `make` and `git` in your PATH.

To build and run the example, use the following command:

[source,bash]
$ make run

Then point your browser to https://localhost:8443

You will need to temporarily trust the root certificate authority,
which can also be found in `priv/ssl/cowboy-ca.crt`.

Recent browsers will communicate using HTTP/2. Older browsers
will use HTTP/1.1.

== HTTP/1.1 example output

[source,bash]
----
$ curl --cacert priv/ssl/cowboy-ca.crt -i https://localhost:8443
HTTP/1.1 200 OK
content-length: 117
content-type: text/html
date: Wed, 26 Jul 2017 08:07:13 GMT
server: Cowboy

<html>
<head>
<link href="/static/style.css" rel="stylesheet" />
</head>
<body>
<h1>Hello world!</h1>
</body>
----

== HTTP/2 example output

[source,bash]
----
$ nghttp -v https://localhost:8443
[ 0.001] Connected
The negotiated protocol: h2
[ 0.014] recv SETTINGS frame <length=0, flags=0x00, stream_id=0>
(niv=0)
[ 0.014] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.014] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.014] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.014] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.014] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.014] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.014] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.014] send HEADERS frame <length=42, flags=0x25, stream_id=13>
; END_STREAM | END_HEADERS | PRIORITY
(padlen=0, dep_stream_id=11, weight=16, exclusive=0)
; Open new stream
:method: GET
:path: /
:scheme: https
:authority: localhost:8443
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.19.0-DEV
[ 0.014] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.014] recv (stream_id=13) :authority: localhost:8443
[ 0.014] recv (stream_id=13) :method: GET
[ 0.014] recv (stream_id=13) :path: /static/style.css
[ 0.014] recv (stream_id=13) :scheme: https
[ 0.014] recv (stream_id=13) accept: text/css
[ 0.014] recv PUSH_PROMISE frame <length=40, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0, promised_stream_id=2)
[ 0.014] recv (stream_id=13) :status: 200
[ 0.014] recv (stream_id=13) content-length: 117
[ 0.014] recv (stream_id=13) content-type: text/html
[ 0.014] recv (stream_id=13) date: Wed, 26 Jul 2017 08:08:03 GMT
[ 0.014] recv (stream_id=13) server: Cowboy
[ 0.014] recv HEADERS frame <length=45, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0)
; First response header
<html>
<head>
<link href="/static/style.css" rel="stylesheet" />
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>[ 0.014] recv DATA frame <length=117, flags=0x01, stream_id=13>
; END_STREAM
[ 0.015] recv (stream_id=2) :status: 200
[ 0.015] recv (stream_id=2) content-length: 21
[ 0.015] recv (stream_id=2) content-type: text/css
[ 0.015] recv (stream_id=2) date: Wed, 26 Jul 2017 08:08:03 GMT
[ 0.015] recv (stream_id=2) etag: "2003476335"
[ 0.015] recv (stream_id=2) last-modified: Wed, 26 Jul 2017 08:01:45 GMT
[ 0.015] recv (stream_id=2) server: Cowboy
[ 0.015] recv HEADERS frame <length=51, flags=0x04, stream_id=2>
; END_HEADERS
(padlen=0)
; First push response header
h1 {
color: red;
}
[ 0.015] recv DATA frame <length=21, flags=0x01, stream_id=2>
; END_STREAM
[ 0.015] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
----
16 changes: 16 additions & 0 deletions examples/ssl_push/priv/ssl/cowboy-ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICeDCCAeGgAwIBAgIJAOvpU0y2e5J4MA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczETMBEGA1UECgwKTmluZSBOaW5lczEPMA0G
A1UECwwGQ293Ym95MRAwDgYDVQQDDAdST09UIENBMB4XDTEzMDIyODA1MTAwMVoX
DTMzMDIyMzA1MTAwMVowVTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRMw
EQYDVQQKDApOaW5lIE5pbmVzMQ8wDQYDVQQLDAZDb3dib3kxEDAOBgNVBAMMB1JP
T1QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMzmY7Us06yjyUbpqwPx
Iv+xh/g3V7we07ClC9GEYnvr3OQvdA1jFEHccMBUUjRoQ8DPd6uSyK5UkixABs08
Tt5B3VsnGKr0DIN+IO4SN2PkmBqIU/BN3KdcwN65YNr3iM0KsKWeFtAZdYx4CakX
7REbO0wjK20AH3xSBn3uFGiBAgMBAAGjUDBOMB0GA1UdDgQWBBRKfZ8KF2jlLBDm
NL6IuEuGY0pdbzAfBgNVHSMEGDAWgBRKfZ8KF2jlLBDmNL6IuEuGY0pdbzAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG1I0kBxXiLkM1b7rl2zPLizREYg
1m+ajb6rWzPOBg6TXjv58Be+H4tqoHIL/M/crixew5emftBkuAGjiKMhbIokjvan
aPTCV8U6HHvNvz9c68HpESWbd+56cHqfsS5XCKp1OpW5tbL2UQYpFKMP4qmbv3Ea
pBfPPmSFMBb1i2AI
-----END CERTIFICATE-----
17 changes: 17 additions & 0 deletions examples/ssl_push/priv/ssl/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpTCCAg6gAwIBAgIJAOvpU0y2e5J5MA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczETMBEGA1UECgwKTmluZSBOaW5lczEPMA0G
A1UECwwGQ293Ym95MRAwDgYDVQQDDAdST09UIENBMB4XDTEzMDIyODA1MjMzNFoX
DTMzMDIyMzA1MjMzNFowVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRMw
EQYDVQQKDApOaW5lIE5pbmVzMQ8wDQYDVQQLDAZDb3dib3kxEjAQBgNVBAMMCWxv
Y2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzbW1GjECzHUc/WST
qLiAGqjCNccR5saVS+yoz2SPRhpoyf0/qBrX5BY0tzmgozoTiRfE4wCiVD99Cc+D
rp/FM49r4EpZdocIovprmOmv/gwkoj95zaA6PKNn1OdmDp2hwJsX2Zm3kpbGUZTx
jDkkccmgUb4EjL7qNHq7saQtivUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB
hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE
FB6jTEIWI8T1ckORA4GezbyYxtbvMB8GA1UdIwQYMBaAFEp9nwoXaOUsEOY0voi4
S4ZjSl1vMA0GCSqGSIb3DQEBBQUAA4GBACMboVQjrx8u/fk3gl/sR0tbA0Wf/NcS
2Dzsy2czndgVUAG4Sqb+hfgn0dqAyUKghRrj3JDcYxYksGPIklDfPzZb7yJ39l16
6x5ZiIzhp8CAVdPvRxRznw5rZwaXesryXu1jVSZxTr3MYZdkG6KaAM0t90+YlGLZ
UG8fAicx0Bf+
-----END CERTIFICATE-----
15 changes: 15 additions & 0 deletions examples/ssl_push/priv/ssl/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDNtbUaMQLMdRz9ZJOouIAaqMI1xxHmxpVL7KjPZI9GGmjJ/T+o
GtfkFjS3OaCjOhOJF8TjAKJUP30Jz4Oun8Uzj2vgSll2hwii+muY6a/+DCSiP3nN
oDo8o2fU52YOnaHAmxfZmbeSlsZRlPGMOSRxyaBRvgSMvuo0eruxpC2K9QIDAQAB
AoGAaD85c/h6bpq7Aj7CBbLaWKhFI3OqwsTITB22vsM7SE+B4zsP02UnG1OVi3UM
zytTUxpUkKV1njQ+bYZYOVqGWF4Up8tTqUglHn0FTPok1AIemELWtz3sXvdSHC1T
lqvFBAZ9kibn13qGyVOiyCFaMwfOM/05RvV7p3jfUMTWnNECQQDs7yCJZ8Ol8MyH
TGZzvkjoN2zg1KwmTbSD1hkP6QAJtPdRuqFbjlEru0/PefgOXsWLRIa3/3v0qw2G
xGkV6AXTAkEA3kNbFisqUydjPnZIYv/P6SvPdUimHJEjXbAbfNfzS9dzszrOVJd2
XqGH7z5yzjoH3IyaIMW8GnubVzGDSjrHFwJAKSU5vELlygpwKkrNO+pelN0TLlQg
dSJnZ8GlZorq88SWcn37iX/EftivenNO7YftvEqxLoDSkOGnnrC7Iw/A+wJBAIEe
L/QY72WPJCBNJpAce/PA96vyoE1II3txqwZDjZspdpVQPDz4IFOpEwbxCFC1dYuy
Qnd3Z2cbF4r3wIWGz9ECQQCJGNhUNtY+Om1ELdqPcquxE2VRV/pucnvJSTKwyo2C
Rvm6H7kFDwPDuN23YnTOlTiho0zzCkclcIukhIVJ+dKz
-----END RSA PRIVATE KEY-----
3 changes: 3 additions & 0 deletions examples/ssl_push/priv/static_files/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
h1 {
color: red;
}
2 changes: 2 additions & 0 deletions examples/ssl_push/relx.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{release, {ssl_push_example, "1"}, [ssl_push]}.
{extended_start_script, true}.
30 changes: 30 additions & 0 deletions examples/ssl_push/src/ssl_push_app.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
%% Feel free to use, reuse and abuse the code in this file.

%% @private
-module(ssl_push_app).
-behaviour(application).

%% API.
-export([start/2]).
-export([stop/1]).

%% API.

start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/static/[...]", cowboy_static, {priv_dir, ssl_push, "static_files"}},
{"/", toppage_handler, []}
]}
]),
PrivDir = code:priv_dir(ssl_push),
{ok, _} = cowboy:start_tls(https, [
{port, 8443},
{cacertfile, PrivDir ++ "/ssl/cowboy-ca.crt"},
{certfile, PrivDir ++ "/ssl/server.crt"},
{keyfile, PrivDir ++ "/ssl/server.key"}
], #{env => #{dispatch => Dispatch}}),
ssl_push_sup:start_link().

stop(_State) ->
ok.
23 changes: 23 additions & 0 deletions examples/ssl_push/src/ssl_push_sup.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
%% Feel free to use, reuse and abuse the code in this file.

%% @private
-module(ssl_push_sup).
-behaviour(supervisor).

%% API.
-export([start_link/0]).

%% supervisor.
-export([init/1]).

%% API.

-spec start_link() -> {ok, pid()}.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% supervisor.

init([]) ->
Procs = [],
{ok, {{one_for_one, 10, 10}, Procs}}.
20 changes: 20 additions & 0 deletions examples/ssl_push/src/toppage_handler.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
%% Feel free to use, reuse and abuse the code in this file.

%% @doc Hello world handler.
-module(toppage_handler).

-export([init/2]).

init(Req0, Opts) ->
cowboy_req:push("/static/style.css", #{<<"accept">> => <<"text/css">>}, Req0),
Req = cowboy_req:reply(200, #{
<<"content-type">> => <<"text/html">>
}, <<"<html>
<head>
<link href=\"/static/style.css\" rel=\"stylesheet\" />
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>">>, Req0),
{ok, Req, Opts}.