From 9c80a8810759c9ed19606547c5aaa47aa1699be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sat, 26 Nov 2016 12:58:19 +0100 Subject: Add Ranch 1.3 and various small fixes --- _build/Makefile | 2 +- .../content/articles/erlang-validate-utf8.asciidoc | 4 +- .../content/articles/erlang.mk-and-relx.asciidoc | 4 +- _build/content/articles/ranch-ftp.asciidoc | 2 +- _build/data/projects/ranch.toml | 4 +- articles/cowboy2-qs/index.html | 2 +- articles/erlang-scalability/index.html | 2 +- articles/erlang-validate-utf8/index.html | 6 +- articles/erlang.mk-and-relx/index.html | 2 +- .../index.html | 2 +- articles/erlanger-playbook/index.html | 2 +- articles/farwest-funded/index.html | 2 +- articles/index.html | 78 +- articles/index.xml | 10 +- articles/january-2014-status/index.html | 2 +- articles/ml-archives/index.html | 2 +- articles/on-open-source/index.html | 2 +- articles/page/1/index.html | 2 +- articles/ranch-ftp/index.html | 4 +- articles/the-story-so-far/index.html | 2 +- articles/tictactoe/index.html | 2 +- articles/website-update/index.html | 2 +- articles/xerl-0.1-empty-modules/index.html | 2 +- articles/xerl-0.2-two-modules/index.html | 2 +- articles/xerl-0.3-atomic-expressions/index.html | 2 +- articles/xerl-0.4-expression-separator/index.html | 2 +- articles/xerl-0.5-intermediate-module/index.html | 2 +- categories/index.html | 2 +- docs/en/cowboy/1.0/index.html | 2 +- docs/en/cowboy/2.0/guide/architecture/index.html | 2 +- docs/en/cowboy/2.0/guide/broken_clients/index.html | 2 +- docs/en/cowboy/2.0/guide/constraints/index.html | 2 +- docs/en/cowboy/2.0/guide/cookies/index.html | 2 +- docs/en/cowboy/2.0/guide/erlang_web/index.html | 2 +- docs/en/cowboy/2.0/guide/flow_diagram/index.html | 2 +- .../en/cowboy/2.0/guide/getting_started/index.html | 2 +- docs/en/cowboy/2.0/guide/handlers/index.html | 2 +- docs/en/cowboy/2.0/guide/hooks/index.html | 2 +- docs/en/cowboy/2.0/guide/index.html | 2 +- docs/en/cowboy/2.0/guide/introduction/index.html | 2 +- docs/en/cowboy/2.0/guide/listeners/index.html | 2 +- docs/en/cowboy/2.0/guide/loop_handlers/index.html | 2 +- docs/en/cowboy/2.0/guide/middlewares/index.html | 2 +- docs/en/cowboy/2.0/guide/modern_web/index.html | 2 +- docs/en/cowboy/2.0/guide/multipart/index.html | 2 +- docs/en/cowboy/2.0/guide/overview/index.html | 2 +- docs/en/cowboy/2.0/guide/req/index.html | 2 +- docs/en/cowboy/2.0/guide/req_body/index.html | 2 +- .../en/cowboy/2.0/guide/resource_design/index.html | 2 +- docs/en/cowboy/2.0/guide/resp/index.html | 2 +- .../en/cowboy/2.0/guide/rest_flowcharts/index.html | 2 +- docs/en/cowboy/2.0/guide/rest_handlers/index.html | 2 +- .../en/cowboy/2.0/guide/rest_principles/index.html | 2 +- docs/en/cowboy/2.0/guide/routing/index.html | 2 +- docs/en/cowboy/2.0/guide/static_files/index.html | 2 +- docs/en/cowboy/2.0/guide/sub_protocols/index.html | 2 +- docs/en/cowboy/2.0/guide/ws_handlers/index.html | 2 +- docs/en/cowboy/2.0/guide/ws_protocol/index.html | 2 +- docs/en/cowboy/2.0/index.html | 2 +- .../en/cowboy/2.0/manual/cowboy.set_env/index.html | 2 +- .../2.0/manual/cowboy.start_clear/index.html | 2 +- .../cowboy/2.0/manual/cowboy.start_tls/index.html | 2 +- .../2.0/manual/cowboy.stop_listener/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_app/index.html | 2 +- .../en/cowboy/2.0/manual/cowboy_handler/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_loop/index.html | 2 +- .../cowboy/2.0/manual/cowboy_middleware/index.html | 2 +- .../cowboy/2.0/manual/cowboy_protocol/index.html | 2 +- .../2.0/manual/cowboy_req.binding/index.html | 2 +- .../2.0/manual/cowboy_req.bindings/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.header/index.html | 2 +- .../2.0/manual/cowboy_req.headers/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.host/index.html | 2 +- .../2.0/manual/cowboy_req.host_info/index.html | 2 +- .../2.0/manual/cowboy_req.match_cookies/index.html | 2 +- .../2.0/manual/cowboy_req.match_qs/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.method/index.html | 2 +- .../2.0/manual/cowboy_req.parse_cookies/index.html | 2 +- .../2.0/manual/cowboy_req.parse_header/index.html | 2 +- .../2.0/manual/cowboy_req.parse_qs/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.path/index.html | 2 +- .../2.0/manual/cowboy_req.path_info/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.peer/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.port/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_req.qs/index.html | 2 +- .../cowboy/2.0/manual/cowboy_req.scheme/index.html | 2 +- .../en/cowboy/2.0/manual/cowboy_req.uri/index.html | 2 +- .../2.0/manual/cowboy_req.version/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_req/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_rest/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_router/index.html | 2 +- docs/en/cowboy/2.0/manual/cowboy_static/index.html | 2 +- .../2.0/manual/cowboy_sub_protocol/index.html | 2 +- .../cowboy/2.0/manual/cowboy_websocket/index.html | 2 +- .../cowboy/2.0/manual/http_status_codes/index.html | 2 +- docs/en/cowboy/2.0/manual/index.html | 2 +- docs/en/cowboy/HEAD/guide/index.html | 2 +- docs/en/cowboy/HEAD/index.html | 2 +- docs/en/cowboy/HEAD/manual/index.html | 2 +- docs/en/cowboy/index.html | 2 +- docs/en/erlang.mk/1/guide/app/index.html | 2 +- docs/en/erlang.mk/1/guide/asciidoc/index.html | 2 +- docs/en/erlang.mk/1/guide/ci/index.html | 2 +- docs/en/erlang.mk/1/guide/common_test.asciidoc | 6 + docs/en/erlang.mk/1/guide/common_test/index.html | 6 +- docs/en/erlang.mk/1/guide/compat/index.html | 2 +- docs/en/erlang.mk/1/guide/contributing/index.html | 2 +- docs/en/erlang.mk/1/guide/coverage/index.html | 2 +- docs/en/erlang.mk/1/guide/deps/index.html | 2 +- docs/en/erlang.mk/1/guide/dialyzer/index.html | 2 +- docs/en/erlang.mk/1/guide/edoc/index.html | 2 +- docs/en/erlang.mk/1/guide/escripts/index.html | 2 +- docs/en/erlang.mk/1/guide/eunit/index.html | 2 +- .../erlang.mk/1/guide/external_plugins/index.html | 2 +- .../1/guide/external_plugins_list/index.html | 2 +- .../erlang.mk/1/guide/getting_started/index.html | 2 +- docs/en/erlang.mk/1/guide/history/index.html | 2 +- docs/en/erlang.mk/1/guide/index.html | 2 +- docs/en/erlang.mk/1/guide/installation/index.html | 2 +- docs/en/erlang.mk/1/guide/limitations/index.html | 2 +- docs/en/erlang.mk/1/guide/overview/index.html | 2 +- docs/en/erlang.mk/1/guide/ports/index.html | 2 +- docs/en/erlang.mk/1/guide/releases/index.html | 2 +- docs/en/erlang.mk/1/guide/sfx/index.html | 2 +- docs/en/erlang.mk/1/guide/shell/index.html | 2 +- docs/en/erlang.mk/1/guide/updating/index.html | 2 +- docs/en/erlang.mk/1/guide/why/index.html | 2 +- docs/en/erlang.mk/1/guide/xref/index.html | 2 +- docs/en/erlang.mk/1/index.html | 2 +- docs/en/erlang.mk/index.html | 2 +- docs/en/gun/1.0/guide/connect/index.html | 2 +- docs/en/gun/1.0/guide/http/index.html | 2 +- docs/en/gun/1.0/guide/index.html | 2 +- docs/en/gun/1.0/guide/introduction.asciidoc | 4 + docs/en/gun/1.0/guide/introduction/index.html | 8 +- docs/en/gun/1.0/guide/protocols/index.html | 2 +- docs/en/gun/1.0/guide/start/index.html | 2 +- docs/en/gun/1.0/guide/websocket/index.html | 2 +- docs/en/gun/1.0/index.html | 2 +- docs/en/gun/1.0/manual/gun/index.html | 2 +- docs/en/gun/1.0/manual/gun_app/index.html | 2 +- docs/en/gun/1.0/manual/index.html | 2 +- docs/en/gun/index.html | 2 +- docs/en/index.html | 2 +- docs/en/ranch/1.2/guide/embedded/index.html | 4 +- docs/en/ranch/1.2/guide/index.html | 4 +- docs/en/ranch/1.2/guide/internals/index.html | 4 +- docs/en/ranch/1.2/guide/introduction/index.html | 4 +- docs/en/ranch/1.2/guide/listeners.asciidoc | 20 +- docs/en/ranch/1.2/guide/listeners/index.html | 25 +- docs/en/ranch/1.2/guide/parsers/index.html | 4 +- docs/en/ranch/1.2/guide/protocols/index.html | 4 +- docs/en/ranch/1.2/guide/ssl_auth.asciidoc | 2 +- docs/en/ranch/1.2/guide/ssl_auth/index.html | 6 +- docs/en/ranch/1.2/guide/transports/index.html | 4 +- docs/en/ranch/1.2/index.html | 2 +- docs/en/ranch/1.2/manual/index.html | 4 +- docs/en/ranch/1.2/manual/ranch/index.html | 12 +- docs/en/ranch/1.2/manual/ranch_app/index.html | 4 +- docs/en/ranch/1.2/manual/ranch_protocol/index.html | 4 +- docs/en/ranch/1.2/manual/ranch_ssl/index.html | 40 +- docs/en/ranch/1.2/manual/ranch_tcp/index.html | 13 +- .../en/ranch/1.2/manual/ranch_transport/index.html | 4 +- docs/en/ranch/1.3/guide/embedded.asciidoc | 48 + docs/en/ranch/1.3/guide/embedded/index.html | 205 ++++ docs/en/ranch/1.3/guide/index.html | 186 ++++ docs/en/ranch/1.3/guide/internals.asciidoc | 94 ++ docs/en/ranch/1.3/guide/internals/index.html | 246 +++++ docs/en/ranch/1.3/guide/introduction.asciidoc | 28 + docs/en/ranch/1.3/guide/introduction/index.html | 187 ++++ docs/en/ranch/1.3/guide/listeners.asciidoc | 302 ++++++ docs/en/ranch/1.3/guide/listeners/index.html | 503 +++++++++ docs/en/ranch/1.3/guide/parsers.asciidoc | 92 ++ docs/en/ranch/1.3/guide/parsers/index.html | 266 +++++ docs/en/ranch/1.3/guide/protocols.asciidoc | 99 ++ docs/en/ranch/1.3/guide/protocols/index.html | 261 +++++ docs/en/ranch/1.3/guide/ssl_auth.asciidoc | 120 ++ docs/en/ranch/1.3/guide/ssl_auth/index.html | 315 ++++++ docs/en/ranch/1.3/guide/transports.asciidoc | 161 +++ docs/en/ranch/1.3/guide/transports/index.html | 336 ++++++ docs/en/ranch/1.3/manual/index.html | 176 +++ docs/en/ranch/1.3/manual/ranch/index.html | 696 ++++++++++++ docs/en/ranch/1.3/manual/ranch_app/index.html | 179 +++ docs/en/ranch/1.3/manual/ranch_protocol/index.html | 221 ++++ docs/en/ranch/1.3/manual/ranch_ssl/index.html | 523 +++++++++ docs/en/ranch/1.3/manual/ranch_tcp/index.html | 421 +++++++ .../en/ranch/1.3/manual/ranch_transport/index.html | 632 +++++++++++ docs/en/ranch/index.html | 2 +- docs/index.html | 9 +- docs/index.xml | 366 ++----- donate/index.html | 1144 +++++++++++++------- index.html | 40 +- index.xml | 6 +- services/index.html | 803 +++++++++++++- sitemap.xml | 68 ++ slogan/index.html | 2 +- support/index.html | 2 +- tags/index.html | 2 +- talks/index.html | 2 +- training/index.html | 2 +- 201 files changed, 8334 insertions(+), 977 deletions(-) create mode 100644 docs/en/ranch/1.3/guide/embedded.asciidoc create mode 100644 docs/en/ranch/1.3/guide/embedded/index.html create mode 100644 docs/en/ranch/1.3/guide/index.html create mode 100644 docs/en/ranch/1.3/guide/internals.asciidoc create mode 100644 docs/en/ranch/1.3/guide/internals/index.html create mode 100644 docs/en/ranch/1.3/guide/introduction.asciidoc create mode 100644 docs/en/ranch/1.3/guide/introduction/index.html create mode 100644 docs/en/ranch/1.3/guide/listeners.asciidoc create mode 100644 docs/en/ranch/1.3/guide/listeners/index.html create mode 100644 docs/en/ranch/1.3/guide/parsers.asciidoc create mode 100644 docs/en/ranch/1.3/guide/parsers/index.html create mode 100644 docs/en/ranch/1.3/guide/protocols.asciidoc create mode 100644 docs/en/ranch/1.3/guide/protocols/index.html create mode 100644 docs/en/ranch/1.3/guide/ssl_auth.asciidoc create mode 100644 docs/en/ranch/1.3/guide/ssl_auth/index.html create mode 100644 docs/en/ranch/1.3/guide/transports.asciidoc create mode 100644 docs/en/ranch/1.3/guide/transports/index.html create mode 100644 docs/en/ranch/1.3/manual/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch_app/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch_protocol/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch_ssl/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch_tcp/index.html create mode 100644 docs/en/ranch/1.3/manual/ranch_transport/index.html diff --git a/_build/Makefile b/_build/Makefile index dc3cf23a..35b0148d 100644 --- a/_build/Makefile +++ b/_build/Makefile @@ -26,7 +26,7 @@ define docs-version-target .PHONY: docs-$1-$2 docs-$1-$2: tmp/$1 - cd tmp/$1 && git checkout $4 + cd tmp/$1 && git checkout $4 && git reset --hard $4 if [ -f tmp/$1/doc/src/guide/book.asciidoc ]; then \ mkdir -p content/docs/en/$1/$3/guide/; \ echo "+++" > content/docs/en/$1/$3/guide.asciidoc; \ diff --git a/_build/content/articles/erlang-validate-utf8.asciidoc b/_build/content/articles/erlang-validate-utf8.asciidoc index 383afcc6..dd0c1e10 100644 --- a/_build/content/articles/erlang-validate-utf8.asciidoc +++ b/_build/content/articles/erlang-validate-utf8.asciidoc @@ -13,8 +13,8 @@ change in the way the code validates UTF-8 data] When looking into why the permessage-deflate tests in autobahntestsuite were taking such a long time, I found that autobahn is using an adaptation of the -algorithm named Flexible -and Economical UTF-8 Decoder. This is the C99 +algorithm named http://bjoern.hoehrmann.de/utf-8/decoder/dfa/[Flexible +and Economical UTF-8 Decoder]. This is the C99 implementation: [source,c] diff --git a/_build/content/articles/erlang.mk-and-relx.asciidoc b/_build/content/articles/erlang.mk-and-relx.asciidoc index e8a667a8..b6f3b25f 100644 --- a/_build/content/articles/erlang.mk-and-relx.asciidoc +++ b/_build/content/articles/erlang.mk-and-relx.asciidoc @@ -50,8 +50,8 @@ this website. I only removed a few targets that were off-topic. PROJECT = ninenines DEPS = cowboy erlydtl -dep_cowboy = https://github.com/extend/cowboy.git 0.8.5 -dep_erlydtl = https://github.com/evanmiller/erlydtl.git 4d0dc8fb +dep_cowboy_commit = 0.8.5 +dep_erlydtl_commit = 4d0dc8fb .PHONY: release clean-release diff --git a/_build/content/articles/ranch-ftp.asciidoc b/_build/content/articles/ranch-ftp.asciidoc index 19209ccc..056e3102 100644 --- a/_build/content/articles/ranch-ftp.asciidoc +++ b/_build/content/articles/ranch-ftp.asciidoc @@ -197,7 +197,7 @@ loop(Socket, Transport, Buffer) -> Buffer2 = << Buffer/binary, Data/binary >>, {Commands, Rest} = split(Buffer2), [handle(Socket, Transport, C) || C <- Commands], - loop(Socket, Transport); + loop(Socket, Transport, Rest); {error, _} -> io:format("The client disconnected~n") end. diff --git a/_build/data/projects/ranch.toml b/_build/data/projects/ranch.toml index 1f3cb624..fccaed4a 100644 --- a/_build/data/projects/ranch.toml +++ b/_build/data/projects/ranch.toml @@ -3,8 +3,8 @@ catchphrase = "The holy cow of servers." description = "Ranch is a socket acceptor pool for building awesome TCP and TLS servers." name = "ranch" repository = "https://github.com/ninenines/ranch" -versions = ["1.2"] -branches = ["master"] +versions = ["1.3", "1.2"] +branches = ["master", "1.2.1"] has_source = true has_guide = true has_manual = true diff --git a/articles/cowboy2-qs/index.html b/articles/cowboy2-qs/index.html index b9dcdbe4..435cd076 100644 --- a/articles/cowboy2-qs/index.html +++ b/articles/cowboy2-qs/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Cowboy 2.0 and query strings diff --git a/articles/erlang-scalability/index.html b/articles/erlang-scalability/index.html index 836e2a99..b970dd20 100644 --- a/articles/erlang-scalability/index.html +++ b/articles/erlang-scalability/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Erlang Scalability diff --git a/articles/erlang-validate-utf8/index.html b/articles/erlang-validate-utf8/index.html index 44e0f42f..9e6ad29a 100644 --- a/articles/erlang-validate-utf8/index.html +++ b/articles/erlang-validate-utf8/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Validating UTF-8 binaries with Erlang @@ -84,8 +84,8 @@ change in the way the code validates UTF-8 data

When looking into why the permessage-deflate tests in autobahntestsuite were taking such a long time, I found that autobahn is using an adaptation of the -algorithm named <a href="http://bjoern.hoehrmann.de/utf-8/decoder/dfa/">Flexible -and Economical UTF-8 Decoder</a>. This is the C99 +algorithm named Flexible +and Economical UTF-8 Decoder. This is the C99 implementation:

Buffer2 = << Buffer/binary, Data/binary >>, {Commands, Rest} = split(Buffer2), [handle(Socket, Transport, C) || C <- Commands], - loop(Socket, Transport); + loop(Socket, Transport, Rest); {error, _} -> io:format("The client disconnected~n") end.
diff --git a/articles/the-story-so-far/index.html b/articles/the-story-so-far/index.html index 7b3a2451..1a3f8d83 100644 --- a/articles/the-story-so-far/index.html +++ b/articles/the-story-so-far/index.html @@ -7,7 +7,7 @@ - + Nine Nines: The story so far diff --git a/articles/tictactoe/index.html b/articles/tictactoe/index.html index 416050b0..c03838b1 100644 --- a/articles/tictactoe/index.html +++ b/articles/tictactoe/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Erlang Tic Tac Toe diff --git a/articles/website-update/index.html b/articles/website-update/index.html index 486a2b8f..8662b475 100644 --- a/articles/website-update/index.html +++ b/articles/website-update/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Website update diff --git a/articles/xerl-0.1-empty-modules/index.html b/articles/xerl-0.1-empty-modules/index.html index 0fac4a40..9a88a351 100644 --- a/articles/xerl-0.1-empty-modules/index.html +++ b/articles/xerl-0.1-empty-modules/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xerl: empty modules diff --git a/articles/xerl-0.2-two-modules/index.html b/articles/xerl-0.2-two-modules/index.html index 44d60915..9f754929 100644 --- a/articles/xerl-0.2-two-modules/index.html +++ b/articles/xerl-0.2-two-modules/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xerl: two modules diff --git a/articles/xerl-0.3-atomic-expressions/index.html b/articles/xerl-0.3-atomic-expressions/index.html index 40f3250e..456b34ad 100644 --- a/articles/xerl-0.3-atomic-expressions/index.html +++ b/articles/xerl-0.3-atomic-expressions/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xerl: atomic expressions diff --git a/articles/xerl-0.4-expression-separator/index.html b/articles/xerl-0.4-expression-separator/index.html index 19eae3f2..404c8d70 100644 --- a/articles/xerl-0.4-expression-separator/index.html +++ b/articles/xerl-0.4-expression-separator/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xerl: expression separator diff --git a/articles/xerl-0.5-intermediate-module/index.html b/articles/xerl-0.5-intermediate-module/index.html index d35d333a..9381796f 100644 --- a/articles/xerl-0.5-intermediate-module/index.html +++ b/articles/xerl-0.5-intermediate-module/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xerl: intermediate module diff --git a/categories/index.html b/categories/index.html index f6690448..b5bb69f9 100644 --- a/categories/index.html +++ b/categories/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Categories diff --git a/docs/en/cowboy/1.0/index.html b/docs/en/cowboy/1.0/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/1.0/index.html +++ b/docs/en/cowboy/1.0/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/cowboy/2.0/guide/architecture/index.html b/docs/en/cowboy/2.0/guide/architecture/index.html index 0b3f8cb7..67a10e88 100644 --- a/docs/en/cowboy/2.0/guide/architecture/index.html +++ b/docs/en/cowboy/2.0/guide/architecture/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Architecture diff --git a/docs/en/cowboy/2.0/guide/broken_clients/index.html b/docs/en/cowboy/2.0/guide/broken_clients/index.html index 3860e51e..331dc36c 100644 --- a/docs/en/cowboy/2.0/guide/broken_clients/index.html +++ b/docs/en/cowboy/2.0/guide/broken_clients/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Dealing with broken clients diff --git a/docs/en/cowboy/2.0/guide/constraints/index.html b/docs/en/cowboy/2.0/guide/constraints/index.html index 10a80953..edfc51c9 100644 --- a/docs/en/cowboy/2.0/guide/constraints/index.html +++ b/docs/en/cowboy/2.0/guide/constraints/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Constraints diff --git a/docs/en/cowboy/2.0/guide/cookies/index.html b/docs/en/cowboy/2.0/guide/cookies/index.html index 2ea3e430..bac2c244 100644 --- a/docs/en/cowboy/2.0/guide/cookies/index.html +++ b/docs/en/cowboy/2.0/guide/cookies/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Using cookies diff --git a/docs/en/cowboy/2.0/guide/erlang_web/index.html b/docs/en/cowboy/2.0/guide/erlang_web/index.html index bd578340..b7f926c1 100644 --- a/docs/en/cowboy/2.0/guide/erlang_web/index.html +++ b/docs/en/cowboy/2.0/guide/erlang_web/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Erlang and the Web diff --git a/docs/en/cowboy/2.0/guide/flow_diagram/index.html b/docs/en/cowboy/2.0/guide/flow_diagram/index.html index 7ec5684f..25f2b799 100644 --- a/docs/en/cowboy/2.0/guide/flow_diagram/index.html +++ b/docs/en/cowboy/2.0/guide/flow_diagram/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Flow diagram diff --git a/docs/en/cowboy/2.0/guide/getting_started/index.html b/docs/en/cowboy/2.0/guide/getting_started/index.html index 03e1dea7..cbfd7b58 100644 --- a/docs/en/cowboy/2.0/guide/getting_started/index.html +++ b/docs/en/cowboy/2.0/guide/getting_started/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Getting started diff --git a/docs/en/cowboy/2.0/guide/handlers/index.html b/docs/en/cowboy/2.0/guide/handlers/index.html index b68527d9..a9d21a16 100644 --- a/docs/en/cowboy/2.0/guide/handlers/index.html +++ b/docs/en/cowboy/2.0/guide/handlers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Handlers diff --git a/docs/en/cowboy/2.0/guide/hooks/index.html b/docs/en/cowboy/2.0/guide/hooks/index.html index 00cf2d9e..7f3252a2 100644 --- a/docs/en/cowboy/2.0/guide/hooks/index.html +++ b/docs/en/cowboy/2.0/guide/hooks/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Hooks diff --git a/docs/en/cowboy/2.0/guide/index.html b/docs/en/cowboy/2.0/guide/index.html index 0d0a92e5..d07f9ba6 100644 --- a/docs/en/cowboy/2.0/guide/index.html +++ b/docs/en/cowboy/2.0/guide/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Cowboy User Guide diff --git a/docs/en/cowboy/2.0/guide/introduction/index.html b/docs/en/cowboy/2.0/guide/introduction/index.html index 8aff6c8c..5ab7823f 100644 --- a/docs/en/cowboy/2.0/guide/introduction/index.html +++ b/docs/en/cowboy/2.0/guide/introduction/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Introduction diff --git a/docs/en/cowboy/2.0/guide/listeners/index.html b/docs/en/cowboy/2.0/guide/listeners/index.html index 40f1f1a3..8dc05c30 100644 --- a/docs/en/cowboy/2.0/guide/listeners/index.html +++ b/docs/en/cowboy/2.0/guide/listeners/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Listeners diff --git a/docs/en/cowboy/2.0/guide/loop_handlers/index.html b/docs/en/cowboy/2.0/guide/loop_handlers/index.html index 5445f1cf..64dc4b31 100644 --- a/docs/en/cowboy/2.0/guide/loop_handlers/index.html +++ b/docs/en/cowboy/2.0/guide/loop_handlers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Loop handlers diff --git a/docs/en/cowboy/2.0/guide/middlewares/index.html b/docs/en/cowboy/2.0/guide/middlewares/index.html index 0bf012b3..53a751d1 100644 --- a/docs/en/cowboy/2.0/guide/middlewares/index.html +++ b/docs/en/cowboy/2.0/guide/middlewares/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Middlewares diff --git a/docs/en/cowboy/2.0/guide/modern_web/index.html b/docs/en/cowboy/2.0/guide/modern_web/index.html index 7067288b..8fd8163a 100644 --- a/docs/en/cowboy/2.0/guide/modern_web/index.html +++ b/docs/en/cowboy/2.0/guide/modern_web/index.html @@ -7,7 +7,7 @@ - + Nine Nines: The modern Web diff --git a/docs/en/cowboy/2.0/guide/multipart/index.html b/docs/en/cowboy/2.0/guide/multipart/index.html index 76ab89c1..e16dc5a9 100644 --- a/docs/en/cowboy/2.0/guide/multipart/index.html +++ b/docs/en/cowboy/2.0/guide/multipart/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Multipart requests diff --git a/docs/en/cowboy/2.0/guide/overview/index.html b/docs/en/cowboy/2.0/guide/overview/index.html index 3d40ee48..365bd2e8 100644 --- a/docs/en/cowboy/2.0/guide/overview/index.html +++ b/docs/en/cowboy/2.0/guide/overview/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Request overview diff --git a/docs/en/cowboy/2.0/guide/req/index.html b/docs/en/cowboy/2.0/guide/req/index.html index 5ba6b035..80960092 100644 --- a/docs/en/cowboy/2.0/guide/req/index.html +++ b/docs/en/cowboy/2.0/guide/req/index.html @@ -7,7 +7,7 @@ - + Nine Nines: The Req object diff --git a/docs/en/cowboy/2.0/guide/req_body/index.html b/docs/en/cowboy/2.0/guide/req_body/index.html index 139712a1..33502cae 100644 --- a/docs/en/cowboy/2.0/guide/req_body/index.html +++ b/docs/en/cowboy/2.0/guide/req_body/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Reading the request body diff --git a/docs/en/cowboy/2.0/guide/resource_design/index.html b/docs/en/cowboy/2.0/guide/resource_design/index.html index bc37e2a4..895f22b3 100644 --- a/docs/en/cowboy/2.0/guide/resource_design/index.html +++ b/docs/en/cowboy/2.0/guide/resource_design/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Designing a resource handler diff --git a/docs/en/cowboy/2.0/guide/resp/index.html b/docs/en/cowboy/2.0/guide/resp/index.html index 6bf3cd8e..b2dbb622 100644 --- a/docs/en/cowboy/2.0/guide/resp/index.html +++ b/docs/en/cowboy/2.0/guide/resp/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Sending a response diff --git a/docs/en/cowboy/2.0/guide/rest_flowcharts/index.html b/docs/en/cowboy/2.0/guide/rest_flowcharts/index.html index 77af893e..8e737143 100644 --- a/docs/en/cowboy/2.0/guide/rest_flowcharts/index.html +++ b/docs/en/cowboy/2.0/guide/rest_flowcharts/index.html @@ -7,7 +7,7 @@ - + Nine Nines: REST flowcharts diff --git a/docs/en/cowboy/2.0/guide/rest_handlers/index.html b/docs/en/cowboy/2.0/guide/rest_handlers/index.html index 2f656c70..a0691398 100644 --- a/docs/en/cowboy/2.0/guide/rest_handlers/index.html +++ b/docs/en/cowboy/2.0/guide/rest_handlers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: REST handlers diff --git a/docs/en/cowboy/2.0/guide/rest_principles/index.html b/docs/en/cowboy/2.0/guide/rest_principles/index.html index a78b08ef..070ee688 100644 --- a/docs/en/cowboy/2.0/guide/rest_principles/index.html +++ b/docs/en/cowboy/2.0/guide/rest_principles/index.html @@ -7,7 +7,7 @@ - + Nine Nines: REST principles diff --git a/docs/en/cowboy/2.0/guide/routing/index.html b/docs/en/cowboy/2.0/guide/routing/index.html index ab7fe6a7..87bb766f 100644 --- a/docs/en/cowboy/2.0/guide/routing/index.html +++ b/docs/en/cowboy/2.0/guide/routing/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Routing diff --git a/docs/en/cowboy/2.0/guide/static_files/index.html b/docs/en/cowboy/2.0/guide/static_files/index.html index 49a93eff..5b924da7 100644 --- a/docs/en/cowboy/2.0/guide/static_files/index.html +++ b/docs/en/cowboy/2.0/guide/static_files/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Static files diff --git a/docs/en/cowboy/2.0/guide/sub_protocols/index.html b/docs/en/cowboy/2.0/guide/sub_protocols/index.html index d2437876..6293bc08 100644 --- a/docs/en/cowboy/2.0/guide/sub_protocols/index.html +++ b/docs/en/cowboy/2.0/guide/sub_protocols/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Sub protocols diff --git a/docs/en/cowboy/2.0/guide/ws_handlers/index.html b/docs/en/cowboy/2.0/guide/ws_handlers/index.html index b8bf8d33..5e484272 100644 --- a/docs/en/cowboy/2.0/guide/ws_handlers/index.html +++ b/docs/en/cowboy/2.0/guide/ws_handlers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Websocket handlers diff --git a/docs/en/cowboy/2.0/guide/ws_protocol/index.html b/docs/en/cowboy/2.0/guide/ws_protocol/index.html index 8d4d35e9..3525de69 100644 --- a/docs/en/cowboy/2.0/guide/ws_protocol/index.html +++ b/docs/en/cowboy/2.0/guide/ws_protocol/index.html @@ -7,7 +7,7 @@ - + Nine Nines: The Websocket protocol diff --git a/docs/en/cowboy/2.0/index.html b/docs/en/cowboy/2.0/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/2.0/index.html +++ b/docs/en/cowboy/2.0/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/cowboy/2.0/manual/cowboy.set_env/index.html b/docs/en/cowboy/2.0/manual/cowboy.set_env/index.html index ea6c5a1c..d1302c35 100644 --- a/docs/en/cowboy/2.0/manual/cowboy.set_env/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy.set_env/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy:set_env(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy.start_clear/index.html b/docs/en/cowboy/2.0/manual/cowboy.start_clear/index.html index 239b36c0..0d01dce8 100644 --- a/docs/en/cowboy/2.0/manual/cowboy.start_clear/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy.start_clear/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy:start_clear(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy.start_tls/index.html b/docs/en/cowboy/2.0/manual/cowboy.start_tls/index.html index c31bbcc6..888895d7 100644 --- a/docs/en/cowboy/2.0/manual/cowboy.start_tls/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy.start_tls/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy:start_tls(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy.stop_listener/index.html b/docs/en/cowboy/2.0/manual/cowboy.stop_listener/index.html index 832f9362..5da3b2be 100644 --- a/docs/en/cowboy/2.0/manual/cowboy.stop_listener/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy.stop_listener/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy:stop_listener(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy/index.html b/docs/en/cowboy/2.0/manual/cowboy/index.html index 2d8b5978..0bb23f2b 100644 --- a/docs/en/cowboy/2.0/manual/cowboy/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_app/index.html b/docs/en/cowboy/2.0/manual/cowboy_app/index.html index a251adc8..a0d35316 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_app/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_app/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy(7) diff --git a/docs/en/cowboy/2.0/manual/cowboy_handler/index.html b/docs/en/cowboy/2.0/manual/cowboy_handler/index.html index ba64c876..73b7738e 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_handler/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_handler/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_handler(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_loop/index.html b/docs/en/cowboy/2.0/manual/cowboy_loop/index.html index df16397a..e5d69511 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_loop/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_loop/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_loop(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_middleware/index.html b/docs/en/cowboy/2.0/manual/cowboy_middleware/index.html index 20e6731c..ebc7ba07 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_middleware/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_middleware/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_middleware(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_protocol/index.html b/docs/en/cowboy/2.0/manual/cowboy_protocol/index.html index bfe03a1f..e934d308 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_protocol/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_protocol/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_protocol(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.binding/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.binding/index.html index 97c35cca..948f8133 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.binding/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.binding/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:binding(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.bindings/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.bindings/index.html index 04d058a3..65c3435a 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.bindings/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.bindings/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:bindings(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.header/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.header/index.html index 06a441a5..241f4172 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.header/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.header/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:header(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.headers/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.headers/index.html index f601d1ef..72edc169 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.headers/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.headers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:headers(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.host/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.host/index.html index 8a0f4bd8..f9536bab 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.host/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.host/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:host(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.host_info/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.host_info/index.html index 995831fa..3b4ceb51 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.host_info/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.host_info/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:host_info(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.match_cookies/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.match_cookies/index.html index f0b3fb86..5c6f5ce8 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.match_cookies/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.match_cookies/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:match_cookies(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.match_qs/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.match_qs/index.html index 592d69df..885859b7 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.match_qs/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.match_qs/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:match_qs(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.method/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.method/index.html index 0d9b2b5f..e95aa546 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.method/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.method/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:method(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.parse_cookies/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.parse_cookies/index.html index 1b34f7f6..10154a52 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.parse_cookies/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.parse_cookies/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:parse_cookies(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.parse_header/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.parse_header/index.html index f2973e68..a49eda43 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.parse_header/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.parse_header/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:parse_header(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.parse_qs/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.parse_qs/index.html index 7e091405..6608047c 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.parse_qs/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.parse_qs/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:parse_qs(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.path/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.path/index.html index bedb39cc..b5969bdf 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.path/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.path/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:path(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.path_info/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.path_info/index.html index 9cb02a02..d136a852 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.path_info/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.path_info/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:path_info(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.peer/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.peer/index.html index 79ace331..a225ea10 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.peer/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.peer/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:peer(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.port/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.port/index.html index 0457d82b..75d4d52a 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.port/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.port/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:port(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.qs/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.qs/index.html index 5ac89c60..ab58d986 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.qs/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.qs/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:qs(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.scheme/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.scheme/index.html index 3f38c9c1..3d84e0b7 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.scheme/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.scheme/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:scheme(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.uri/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.uri/index.html index ae15f9b1..02eb12ec 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.uri/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.uri/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:uri(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req.version/index.html b/docs/en/cowboy/2.0/manual/cowboy_req.version/index.html index d44ed468..2a1705bf 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req.version/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req.version/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req:version(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_req/index.html b/docs/en/cowboy/2.0/manual/cowboy_req/index.html index cc425f2b..514a6179 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_req/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_req/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_req(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_rest/index.html b/docs/en/cowboy/2.0/manual/cowboy_rest/index.html index 12ed4c05..48fcec78 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_rest/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_rest/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_rest(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_router/index.html b/docs/en/cowboy/2.0/manual/cowboy_router/index.html index 850d81a0..2f4186f3 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_router/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_router/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_router(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_static/index.html b/docs/en/cowboy/2.0/manual/cowboy_static/index.html index 0b4ad099..90d20fdb 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_static/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_static/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_static(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_sub_protocol/index.html b/docs/en/cowboy/2.0/manual/cowboy_sub_protocol/index.html index b897cac4..8a76b50d 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_sub_protocol/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_sub_protocol/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_sub_protocol(3) diff --git a/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html b/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html index 5802a5d8..8274fbf8 100644 --- a/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html +++ b/docs/en/cowboy/2.0/manual/cowboy_websocket/index.html @@ -7,7 +7,7 @@ - + Nine Nines: cowboy_websocket(3) diff --git a/docs/en/cowboy/2.0/manual/http_status_codes/index.html b/docs/en/cowboy/2.0/manual/http_status_codes/index.html index d2f7ac55..c07963e8 100644 --- a/docs/en/cowboy/2.0/manual/http_status_codes/index.html +++ b/docs/en/cowboy/2.0/manual/http_status_codes/index.html @@ -7,7 +7,7 @@ - + Nine Nines: HTTP status codes(7) diff --git a/docs/en/cowboy/2.0/manual/index.html b/docs/en/cowboy/2.0/manual/index.html index 4d74dfa5..ec5c63e0 100644 --- a/docs/en/cowboy/2.0/manual/index.html +++ b/docs/en/cowboy/2.0/manual/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Cowboy Function Reference diff --git a/docs/en/cowboy/HEAD/guide/index.html b/docs/en/cowboy/HEAD/guide/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/HEAD/guide/index.html +++ b/docs/en/cowboy/HEAD/guide/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/cowboy/HEAD/index.html b/docs/en/cowboy/HEAD/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/HEAD/index.html +++ b/docs/en/cowboy/HEAD/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/cowboy/HEAD/manual/index.html b/docs/en/cowboy/HEAD/manual/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/HEAD/manual/index.html +++ b/docs/en/cowboy/HEAD/manual/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/cowboy/index.html b/docs/en/cowboy/index.html index ea24e654..d87c4243 100644 --- a/docs/en/cowboy/index.html +++ b/docs/en/cowboy/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/erlang.mk/1/guide/app/index.html b/docs/en/erlang.mk/1/guide/app/index.html index 6131b394..b6fbf4f7 100644 --- a/docs/en/erlang.mk/1/guide/app/index.html +++ b/docs/en/erlang.mk/1/guide/app/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Building diff --git a/docs/en/erlang.mk/1/guide/asciidoc/index.html b/docs/en/erlang.mk/1/guide/asciidoc/index.html index 98f19d51..9cb17dba 100644 --- a/docs/en/erlang.mk/1/guide/asciidoc/index.html +++ b/docs/en/erlang.mk/1/guide/asciidoc/index.html @@ -7,7 +7,7 @@ - + Nine Nines: AsciiDoc documentation diff --git a/docs/en/erlang.mk/1/guide/ci/index.html b/docs/en/erlang.mk/1/guide/ci/index.html index 5f1fc30c..a7050ae7 100644 --- a/docs/en/erlang.mk/1/guide/ci/index.html +++ b/docs/en/erlang.mk/1/guide/ci/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Continuous integration diff --git a/docs/en/erlang.mk/1/guide/common_test.asciidoc b/docs/en/erlang.mk/1/guide/common_test.asciidoc index aec8747e..f8f0de3d 100644 --- a/docs/en/erlang.mk/1/guide/common_test.asciidoc +++ b/docs/en/erlang.mk/1/guide/common_test.asciidoc @@ -35,6 +35,12 @@ is `http`: [source,make] CT_SUITES = http ws +The `CT_LOGS_DIR` variable can be used to set where HTML +log files are to be written. This defaults to 'logs/'. + +[source,make] +CT_LOGS_DIR = ct_output_log_dir + === Usage To run all tests (including Common Test): diff --git a/docs/en/erlang.mk/1/guide/common_test/index.html b/docs/en/erlang.mk/1/guide/common_test/index.html index 56de0f4c..a1b12f81 100644 --- a/docs/en/erlang.mk/1/guide/common_test/index.html +++ b/docs/en/erlang.mk/1/guide/common_test/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Common Test @@ -100,6 +100,10 @@ If the file is named http_SUITE.erl, the test suite is http:

+

The CT_LOGS_DIR variable can be used to set where HTML +log files are to be written. This defaults to logs/.

+
+
diff --git a/docs/en/erlang.mk/1/guide/compat/index.html b/docs/en/erlang.mk/1/guide/compat/index.html index c46daeff..a84bd3cc 100644 --- a/docs/en/erlang.mk/1/guide/compat/index.html +++ b/docs/en/erlang.mk/1/guide/compat/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Compatibility with other build tools diff --git a/docs/en/erlang.mk/1/guide/contributing/index.html b/docs/en/erlang.mk/1/guide/contributing/index.html index f735cbc6..3175a7c9 100644 --- a/docs/en/erlang.mk/1/guide/contributing/index.html +++ b/docs/en/erlang.mk/1/guide/contributing/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Contributing diff --git a/docs/en/erlang.mk/1/guide/coverage/index.html b/docs/en/erlang.mk/1/guide/coverage/index.html index 440f7abf..8e07138b 100644 --- a/docs/en/erlang.mk/1/guide/coverage/index.html +++ b/docs/en/erlang.mk/1/guide/coverage/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Code coverage diff --git a/docs/en/erlang.mk/1/guide/deps/index.html b/docs/en/erlang.mk/1/guide/deps/index.html index cc8d737d..e551a607 100644 --- a/docs/en/erlang.mk/1/guide/deps/index.html +++ b/docs/en/erlang.mk/1/guide/deps/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Packages and dependencies diff --git a/docs/en/erlang.mk/1/guide/dialyzer/index.html b/docs/en/erlang.mk/1/guide/dialyzer/index.html index 454d176e..3fb9d47d 100644 --- a/docs/en/erlang.mk/1/guide/dialyzer/index.html +++ b/docs/en/erlang.mk/1/guide/dialyzer/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Dialyzer diff --git a/docs/en/erlang.mk/1/guide/edoc/index.html b/docs/en/erlang.mk/1/guide/edoc/index.html index 6e8ed6f8..52eb84ef 100644 --- a/docs/en/erlang.mk/1/guide/edoc/index.html +++ b/docs/en/erlang.mk/1/guide/edoc/index.html @@ -7,7 +7,7 @@ - + Nine Nines: EDoc comments diff --git a/docs/en/erlang.mk/1/guide/escripts/index.html b/docs/en/erlang.mk/1/guide/escripts/index.html index f3ba738f..88e0320e 100644 --- a/docs/en/erlang.mk/1/guide/escripts/index.html +++ b/docs/en/erlang.mk/1/guide/escripts/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Escripts diff --git a/docs/en/erlang.mk/1/guide/eunit/index.html b/docs/en/erlang.mk/1/guide/eunit/index.html index f0a9f4d4..f53290fe 100644 --- a/docs/en/erlang.mk/1/guide/eunit/index.html +++ b/docs/en/erlang.mk/1/guide/eunit/index.html @@ -7,7 +7,7 @@ - + Nine Nines: EUnit diff --git a/docs/en/erlang.mk/1/guide/external_plugins/index.html b/docs/en/erlang.mk/1/guide/external_plugins/index.html index 735e4820..c91f5198 100644 --- a/docs/en/erlang.mk/1/guide/external_plugins/index.html +++ b/docs/en/erlang.mk/1/guide/external_plugins/index.html @@ -7,7 +7,7 @@ - + Nine Nines: External plugins diff --git a/docs/en/erlang.mk/1/guide/external_plugins_list/index.html b/docs/en/erlang.mk/1/guide/external_plugins_list/index.html index 9b26460d..0aa40b1e 100644 --- a/docs/en/erlang.mk/1/guide/external_plugins_list/index.html +++ b/docs/en/erlang.mk/1/guide/external_plugins_list/index.html @@ -7,7 +7,7 @@ - + Nine Nines: List of plugins diff --git a/docs/en/erlang.mk/1/guide/getting_started/index.html b/docs/en/erlang.mk/1/guide/getting_started/index.html index 10bc1ab3..fc30a227 100644 --- a/docs/en/erlang.mk/1/guide/getting_started/index.html +++ b/docs/en/erlang.mk/1/guide/getting_started/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Getting started diff --git a/docs/en/erlang.mk/1/guide/history/index.html b/docs/en/erlang.mk/1/guide/history/index.html index 37125ee4..54c3e9da 100644 --- a/docs/en/erlang.mk/1/guide/history/index.html +++ b/docs/en/erlang.mk/1/guide/history/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Short history diff --git a/docs/en/erlang.mk/1/guide/index.html b/docs/en/erlang.mk/1/guide/index.html index dd2d6927..59ada5e4 100644 --- a/docs/en/erlang.mk/1/guide/index.html +++ b/docs/en/erlang.mk/1/guide/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Erlang.mk User Guide diff --git a/docs/en/erlang.mk/1/guide/installation/index.html b/docs/en/erlang.mk/1/guide/installation/index.html index 2d711d0f..f9e33c18 100644 --- a/docs/en/erlang.mk/1/guide/installation/index.html +++ b/docs/en/erlang.mk/1/guide/installation/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Installation diff --git a/docs/en/erlang.mk/1/guide/limitations/index.html b/docs/en/erlang.mk/1/guide/limitations/index.html index 8b88d8ae..27f69b3b 100644 --- a/docs/en/erlang.mk/1/guide/limitations/index.html +++ b/docs/en/erlang.mk/1/guide/limitations/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Limitations diff --git a/docs/en/erlang.mk/1/guide/overview/index.html b/docs/en/erlang.mk/1/guide/overview/index.html index 8c838898..95bcb794 100644 --- a/docs/en/erlang.mk/1/guide/overview/index.html +++ b/docs/en/erlang.mk/1/guide/overview/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Overview diff --git a/docs/en/erlang.mk/1/guide/ports/index.html b/docs/en/erlang.mk/1/guide/ports/index.html index 83ad5dd4..f6e71a7a 100644 --- a/docs/en/erlang.mk/1/guide/ports/index.html +++ b/docs/en/erlang.mk/1/guide/ports/index.html @@ -7,7 +7,7 @@ - + Nine Nines: NIFs and port drivers diff --git a/docs/en/erlang.mk/1/guide/releases/index.html b/docs/en/erlang.mk/1/guide/releases/index.html index fc98819e..923a0d4e 100644 --- a/docs/en/erlang.mk/1/guide/releases/index.html +++ b/docs/en/erlang.mk/1/guide/releases/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Releases diff --git a/docs/en/erlang.mk/1/guide/sfx/index.html b/docs/en/erlang.mk/1/guide/sfx/index.html index 8433ab9c..d90cc8bf 100644 --- a/docs/en/erlang.mk/1/guide/sfx/index.html +++ b/docs/en/erlang.mk/1/guide/sfx/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Self-extracting releases diff --git a/docs/en/erlang.mk/1/guide/shell/index.html b/docs/en/erlang.mk/1/guide/shell/index.html index 2581a699..295caf48 100644 --- a/docs/en/erlang.mk/1/guide/shell/index.html +++ b/docs/en/erlang.mk/1/guide/shell/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Erlang shell diff --git a/docs/en/erlang.mk/1/guide/updating/index.html b/docs/en/erlang.mk/1/guide/updating/index.html index bf039a6d..fbb3fffc 100644 --- a/docs/en/erlang.mk/1/guide/updating/index.html +++ b/docs/en/erlang.mk/1/guide/updating/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Updating Erlang.mk diff --git a/docs/en/erlang.mk/1/guide/why/index.html b/docs/en/erlang.mk/1/guide/why/index.html index 8619e04a..02c57035 100644 --- a/docs/en/erlang.mk/1/guide/why/index.html +++ b/docs/en/erlang.mk/1/guide/why/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Why Erlang.mk diff --git a/docs/en/erlang.mk/1/guide/xref/index.html b/docs/en/erlang.mk/1/guide/xref/index.html index a65124a1..45e89ff7 100644 --- a/docs/en/erlang.mk/1/guide/xref/index.html +++ b/docs/en/erlang.mk/1/guide/xref/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Xref diff --git a/docs/en/erlang.mk/1/index.html b/docs/en/erlang.mk/1/index.html index ea24e654..d87c4243 100644 --- a/docs/en/erlang.mk/1/index.html +++ b/docs/en/erlang.mk/1/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/erlang.mk/index.html b/docs/en/erlang.mk/index.html index ea24e654..d87c4243 100644 --- a/docs/en/erlang.mk/index.html +++ b/docs/en/erlang.mk/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/gun/1.0/guide/connect/index.html b/docs/en/gun/1.0/guide/connect/index.html index aeebd80e..4ace37e6 100644 --- a/docs/en/gun/1.0/guide/connect/index.html +++ b/docs/en/gun/1.0/guide/connect/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Connection diff --git a/docs/en/gun/1.0/guide/http/index.html b/docs/en/gun/1.0/guide/http/index.html index fa12b51c..9b345ae1 100644 --- a/docs/en/gun/1.0/guide/http/index.html +++ b/docs/en/gun/1.0/guide/http/index.html @@ -7,7 +7,7 @@ - + Nine Nines: HTTP diff --git a/docs/en/gun/1.0/guide/index.html b/docs/en/gun/1.0/guide/index.html index 127591f6..9348953a 100644 --- a/docs/en/gun/1.0/guide/index.html +++ b/docs/en/gun/1.0/guide/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Gun User Guide diff --git a/docs/en/gun/1.0/guide/introduction.asciidoc b/docs/en/gun/1.0/guide/introduction.asciidoc index 81a7c7f4..2914ef62 100644 --- a/docs/en/gun/1.0/guide/introduction.asciidoc +++ b/docs/en/gun/1.0/guide/introduction.asciidoc @@ -26,3 +26,7 @@ to lowercase, and expects your application to provide lowercase header names. The same applies to any other case insensitive value. + +=== Versioning + +Gun uses [Semantic Versioning 2.0.0](http://semver.org/). diff --git a/docs/en/gun/1.0/guide/introduction/index.html b/docs/en/gun/1.0/guide/introduction/index.html index 010f7aef..5dfc3d5f 100644 --- a/docs/en/gun/1.0/guide/introduction/index.html +++ b/docs/en/gun/1.0/guide/introduction/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Introduction @@ -97,6 +97,12 @@ names.

The same applies to any other case insensitive value.

+
+

Versioning

+
+

Gun uses [Semantic Versioning 2.0.0](http://semver.org/).

+
+
diff --git a/docs/en/gun/1.0/guide/protocols/index.html b/docs/en/gun/1.0/guide/protocols/index.html index d8d48a5d..f2ac3780 100644 --- a/docs/en/gun/1.0/guide/protocols/index.html +++ b/docs/en/gun/1.0/guide/protocols/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Supported protocols diff --git a/docs/en/gun/1.0/guide/start/index.html b/docs/en/gun/1.0/guide/start/index.html index 39992b50..2f84cfe9 100644 --- a/docs/en/gun/1.0/guide/start/index.html +++ b/docs/en/gun/1.0/guide/start/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Starting and stopping diff --git a/docs/en/gun/1.0/guide/websocket/index.html b/docs/en/gun/1.0/guide/websocket/index.html index bec8fb19..44ec4277 100644 --- a/docs/en/gun/1.0/guide/websocket/index.html +++ b/docs/en/gun/1.0/guide/websocket/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Websocket diff --git a/docs/en/gun/1.0/index.html b/docs/en/gun/1.0/index.html index ea24e654..d87c4243 100644 --- a/docs/en/gun/1.0/index.html +++ b/docs/en/gun/1.0/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/gun/1.0/manual/gun/index.html b/docs/en/gun/1.0/manual/gun/index.html index 5c92823c..332b3b30 100644 --- a/docs/en/gun/1.0/manual/gun/index.html +++ b/docs/en/gun/1.0/manual/gun/index.html @@ -7,7 +7,7 @@ - + Nine Nines: gun(3) diff --git a/docs/en/gun/1.0/manual/gun_app/index.html b/docs/en/gun/1.0/manual/gun_app/index.html index ae3b83c8..6adca335 100644 --- a/docs/en/gun/1.0/manual/gun_app/index.html +++ b/docs/en/gun/1.0/manual/gun_app/index.html @@ -7,7 +7,7 @@ - + Nine Nines: gun(7) diff --git a/docs/en/gun/1.0/manual/index.html b/docs/en/gun/1.0/manual/index.html index a5789a95..8629cdb2 100644 --- a/docs/en/gun/1.0/manual/index.html +++ b/docs/en/gun/1.0/manual/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Gun Function Reference diff --git a/docs/en/gun/index.html b/docs/en/gun/index.html index ea24e654..d87c4243 100644 --- a/docs/en/gun/index.html +++ b/docs/en/gun/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/index.html b/docs/en/index.html index ea24e654..d87c4243 100644 --- a/docs/en/index.html +++ b/docs/en/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/ranch/1.2/guide/embedded/index.html b/docs/en/ranch/1.2/guide/embedded/index.html index 13418002..adb1bc81 100644 --- a/docs/en/ranch/1.2/guide/embedded/index.html +++ b/docs/en/ranch/1.2/guide/embedded/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Embedded mode @@ -164,6 +164,8 @@ more details on how Ranch does it.

+
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/index.html b/docs/en/ranch/1.2/guide/index.html index 08552458..f5b25985 100644 --- a/docs/en/ranch/1.2/guide/index.html +++ b/docs/en/ranch/1.2/guide/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Ranch User Guide @@ -145,6 +145,8 @@ +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/internals/index.html b/docs/en/ranch/1.2/guide/internals/index.html index b43eed8f..b7e0b850 100644 --- a/docs/en/ranch/1.2/guide/internals/index.html +++ b/docs/en/ranch/1.2/guide/internals/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Internals @@ -205,6 +205,8 @@ http://www.gnu.org/software/src-highlite --> +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/introduction/index.html b/docs/en/ranch/1.2/guide/introduction/index.html index 4afe8227..6c5ae67c 100644 --- a/docs/en/ranch/1.2/guide/introduction/index.html +++ b/docs/en/ranch/1.2/guide/introduction/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Introduction @@ -144,6 +144,8 @@ modifications but there is no guarantee that it will work as expected.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/listeners.asciidoc b/docs/en/ranch/1.2/guide/listeners.asciidoc index a776a584..ef2d49c7 100644 --- a/docs/en/ranch/1.2/guide/listeners.asciidoc +++ b/docs/en/ranch/1.2/guide/listeners.asciidoc @@ -4,7 +4,7 @@ A listener is a set of processes whose role is to listen on a port for new connections. It manages a pool of acceptor processes, each of them indefinitely accepting connections. When it does, it starts a new process executing the protocol handler code. All the socket -programming is abstracted through the use of transport handlers. +programming is abstracted through the user of transport handlers. The listener takes care of supervising all the acceptor and connection processes, allowing developers to focus on building their application. @@ -203,24 +203,6 @@ ranch:set_max_connections(tcp_echo, MaxConns). The change will occur immediately. -=== When running out of file descriptors - -Operating systems have limits on the number of sockets -which can be opened by applications. When this maximum is -reached the listener can no longer accept new connections. The -accept rate of the listener will be automatically reduced, and a -warning message will be logged. - ----- -=ERROR REPORT==== 13-Jan-2016::12:24:38 === -Ranch acceptor reducing accept rate: out of file descriptors ----- - -If you notice messages like this you should increase the number -of file-descriptors which can be opened by your application. How -this should be done is operating-system dependent. Please consult -the documentation of your operating system. - === Using a supervisor for connection processes Ranch allows you to define the type of process that will be used diff --git a/docs/en/ranch/1.2/guide/listeners/index.html b/docs/en/ranch/1.2/guide/listeners/index.html index ead3c4b8..4d6ccbc0 100644 --- a/docs/en/ranch/1.2/guide/listeners/index.html +++ b/docs/en/ranch/1.2/guide/listeners/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Listeners @@ -73,7 +73,7 @@ for new connections. It manages a pool of acceptor processes, each of them indefinitely accepting connections. When it does, it starts a new process executing the protocol handler code. All the socket -programming is abstracted through the use of transport handlers.

    +programming is abstracted through the user of transport handlers.

    The listener takes care of supervising all the acceptor and connection processes, allowing developers to focus on building their application.

    @@ -302,25 +302,6 @@ http://www.gnu.org/software/src-highlite -->
    -

    When running out of file descriptors

    -
    -

    Operating systems have limits on the number of sockets -which can be opened by applications. When this maximum is -reached the listener can no longer accept new connections. The -accept rate of the listener will be automatically reduced, and a -warning message will be logged.

    -
    -
    -
    =ERROR REPORT==== 13-Jan-2016::12:24:38 ===
    -Ranch acceptor reducing accept rate: out of file descriptors
    -
    -

    If you notice messages like this you should increase the number -of file-descriptors which can be opened by your application. How -this should be done is operating-system dependent. Please consult -the documentation of your operating system.

    -
    -
    -

    Using a supervisor for connection processes

    Ranch allows you to define the type of process that will be used @@ -422,6 +403,8 @@ http://www.gnu.org/software/src-highlite --> +

  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/parsers/index.html b/docs/en/ranch/1.2/guide/parsers/index.html index c6a2ddab..d7849c7f 100644 --- a/docs/en/ranch/1.2/guide/parsers/index.html +++ b/docs/en/ranch/1.2/guide/parsers/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Writing parsers @@ -225,6 +225,8 @@ immediately if any. Otherwise wait for more data.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/protocols/index.html b/docs/en/ranch/1.2/guide/protocols/index.html index e2f313f9..092946b2 100644 --- a/docs/en/ranch/1.2/guide/protocols/index.html +++ b/docs/en/ranch/1.2/guide/protocols/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Protocols @@ -245,6 +245,8 @@ http://www.gnu.org/software/src-highlite --> +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/ssl_auth.asciidoc b/docs/en/ranch/1.2/guide/ssl_auth.asciidoc index de0bbaf0..39f9c3c0 100644 --- a/docs/en/ranch/1.2/guide/ssl_auth.asciidoc +++ b/docs/en/ranch/1.2/guide/ssl_auth.asciidoc @@ -28,7 +28,7 @@ Following are the steps you need to take to create a CAcert.org account, generate a certificate and install it in your favorite browser. -* Open http://cacert.org in your favorite browser +* Open [CAcert.org](http://cacert.org) in your favorite browser * Root Certificate link: install both certificates * Join (Register an account) * Verify your account (check your email inbox!) diff --git a/docs/en/ranch/1.2/guide/ssl_auth/index.html b/docs/en/ranch/1.2/guide/ssl_auth/index.html index cd38f30a..463772c6 100644 --- a/docs/en/ranch/1.2/guide/ssl_auth/index.html +++ b/docs/en/ranch/1.2/guide/ssl_auth/index.html @@ -7,7 +7,7 @@ - + Nine Nines: SSL client authentication @@ -99,7 +99,7 @@ browser.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/guide/transports/index.html b/docs/en/ranch/1.2/guide/transports/index.html index 682cd26b..d3a4affd 100644 --- a/docs/en/ranch/1.2/guide/transports/index.html +++ b/docs/en/ranch/1.2/guide/transports/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Transports @@ -305,6 +305,8 @@ is the transport’s module. See ranch_ssl for an example.

    < +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/index.html b/docs/en/ranch/1.2/index.html index ea24e654..d87c4243 100644 --- a/docs/en/ranch/1.2/index.html +++ b/docs/en/ranch/1.2/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/en/ranch/1.2/manual/index.html b/docs/en/ranch/1.2/manual/index.html index 83666bc9..3f3ddce7 100644 --- a/docs/en/ranch/1.2/manual/index.html +++ b/docs/en/ranch/1.2/manual/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Ranch Function Reference @@ -135,6 +135,8 @@ +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch/index.html b/docs/en/ranch/1.2/manual/ranch/index.html index 7a16695c..78292a1f 100644 --- a/docs/en/ranch/1.2/manual/ranch/index.html +++ b/docs/en/ranch/1.2/manual/ranch/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch(3) @@ -185,7 +185,7 @@ Ranch that it initialized properly and let it perform any additional operations before the socket can be safely used.

    -

    child_spec(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → supervisor:child_spec()

    +

    child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → supervisor:child_spec()

    Ref = ref() @@ -196,7 +196,7 @@ Listener name.

    -NumAcceptors = non_neg_integer() +NbAcceptors = non_neg_integer()

    @@ -405,7 +405,7 @@ New protocol options. Old connections will not receive the new options.

    -

    start_listener(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → {ok, pid()} | {error, badarg}

    +

    start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → {ok, pid()} | {error, badarg}

    Ref = ref() @@ -416,7 +416,7 @@ Listener name.

    -NumAcceptors = non_neg_integer() +NbAcceptors = non_neg_integer()

    @@ -520,6 +520,8 @@ completely stopped.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch_app/index.html b/docs/en/ranch/1.2/manual/ranch_app/index.html index 24123477..202babbc 100644 --- a/docs/en/ranch/1.2/manual/ranch_app/index.html +++ b/docs/en/ranch/1.2/manual/ranch_app/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch(7) @@ -140,6 +140,8 @@ and total.profile. Do not use in production.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch_protocol/index.html b/docs/en/ranch/1.2/manual/ranch_protocol/index.html index 27eb6c9d..8fd069e6 100644 --- a/docs/en/ranch/1.2/manual/ranch_protocol/index.html +++ b/docs/en/ranch/1.2/manual/ranch_protocol/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch_protocol(3) @@ -180,6 +180,8 @@ processes and degrade performance severely.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch_ssl/index.html b/docs/en/ranch/1.2/manual/ranch_ssl/index.html index b486f5ed..1d77a3d5 100644 --- a/docs/en/ranch/1.2/manual/ranch_ssl/index.html +++ b/docs/en/ranch/1.2/manual/ranch_ssl/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch_ssl(3) @@ -92,7 +92,6 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
    ssl_opt() = {alpn_preferred_protocols, [binary()]}
    -        | {beast_mitigation, one_n_minus_one | zero_n | disabled}
             | {cacertfile, string()}
             | {cacerts, [public_key:der_encoded()]}
             | {cert, public_key:der_encoded()}
    @@ -111,18 +110,15 @@ http://www.gnu.org/software/src-highlite -->
             | {keyfile, string()}
             | {log_alert, boolean()}
             | {next_protocols_advertised, [binary()]}
    -        | {padding_check, boolean()}
             | {partial_chain, fun(([public_key:der_encoded()]) -> {trusted_ca, public_key:der_encoded()} | unknown_ca)}
             | {password, string()}
             | {psk_identity, string()}
             | {reuse_session, fun()}
             | {reuse_sessions, boolean()}
             | {secure_renegotiate, boolean()}
    -        | {signature_algs, [{atom(), atom()}]}
             | {sni_fun, fun()}
             | {sni_hosts, [{string(), ssl_opt()}]}
             | {user_lookup_fun, {fun(), any()}}
    -        | {v2_hello_compatible, boolean()}
             | {verify, ssl:verify_type()}
             | {verify_fun, {fun(), any()}}
             | {versions, [atom()]}.
    @@ -154,14 +150,6 @@ alpn_preferred_protocols

    -beast_mitigation -
    -
    -

    - Change the BEAST mitigation strategy for SSL-3.0 and TLS-1.0 to interoperate with legacy software. -

    -
    -
    cacertfile
    @@ -314,14 +302,6 @@ nodelay (true)

    -padding_check -
    -
    -

    - Allow disabling the block cipher padding check for TLS-1.0 to be able to interoperate with legacy software. -

    -
    -
    partial_chain
    @@ -370,14 +350,6 @@ secure_renegotiate (false)

    -signature_algs -
    -
    -

    - The TLS signature algorithm extension may be used, from TLS 1.2, to negotiate which signature algorithm to use during the TLS handshake. -

    -
    -
    sni_fun
    @@ -402,14 +374,6 @@ user_lookup_fun

    -v2_hello_compatible -
    -
    -

    - Accept clients that send hello messages in SSL-2.0 format while offering supported SSL/TLS versions. -

    -
    -
    verify (verify_none)
    @@ -482,6 +446,8 @@ greater control over the client certificate validation.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch_tcp/index.html b/docs/en/ranch/1.2/manual/ranch_tcp/index.html index 44e289c5..bcda73a2 100644 --- a/docs/en/ranch/1.2/manual/ranch_tcp/index.html +++ b/docs/en/ranch/1.2/manual/ranch_tcp/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch_tcp(3) @@ -106,7 +106,6 @@ http://www.gnu.org/software/src-highlite --> | inet | inet6 | {ip, inet:ip_address()} - | {ipv6_v6only, boolean()} | {keepalive, boolean()} | {linger, {boolean(), non_neg_integer()}} | {low_msgq_watermark, non_neg_integer()} @@ -230,14 +229,6 @@ ip

    -ipv6_v6only (false) -
    -
    -

    - Listen on IPv4 and IPv6 (false) or only on IPv6 (true). Use with inet6. -

    -
    -
    keepalive (false)
    @@ -380,6 +371,8 @@ portable. Use with caution.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.2/manual/ranch_transport/index.html b/docs/en/ranch/1.2/manual/ranch_transport/index.html index 9bfb4786..6fab612e 100644 --- a/docs/en/ranch/1.2/manual/ranch_transport/index.html +++ b/docs/en/ranch/1.2/manual/ranch_transport/index.html @@ -7,7 +7,7 @@ - + Nine Nines: ranch_transport(3) @@ -591,6 +591,8 @@ directly.

    +
  • 1.3
  • +
  • 1.2
  • diff --git a/docs/en/ranch/1.3/guide/embedded.asciidoc b/docs/en/ranch/1.3/guide/embedded.asciidoc new file mode 100644 index 00000000..593a8079 --- /dev/null +++ b/docs/en/ranch/1.3/guide/embedded.asciidoc @@ -0,0 +1,48 @@ +== Embedded mode + +Embedded mode allows you to insert Ranch listeners directly +in your supervision tree. This allows for greater fault tolerance +control by permitting the shutdown of a listener due to the +failure of another part of the application and vice versa. + +=== Embedding + +To embed Ranch in your application you can simply add the child specs +to your supervision tree. This can all be done in the `init/1` function +of one of your application supervisors. + +Ranch requires at the minimum two kinds of child specs for embedding. +First, you need to add `ranch_sup` to your supervision tree, only once, +regardless of the number of listeners you will use. Then you need to +add the child specs for each listener. + +Ranch has a convenience function for getting the listeners child specs +called `ranch:child_spec/6`, that works like `ranch:start_listener/6`, +except that it doesn't start anything, it only returns child specs. + +As for `ranch_sup`, the child spec is simple enough to not require a +convenience function. + +The following example adds both `ranch_sup` and one listener to another +application's supervision tree. + +.Embed Ranch directly in your supervision tree + +[source,erlang] +---- +init([]) -> + RanchSupSpec = {ranch_sup, {ranch_sup, start_link, []}, + permanent, 5000, supervisor, [ranch_sup]}, + ListenerSpec = ranch:child_spec(echo, 100, + ranch_tcp, [{port, 5555}], + echo_protocol, [] + ), + {ok, {{one_for_one, 10, 10}, [RanchSupSpec, ListenerSpec]}}. +---- + +Remember, you can add as many listener child specs as needed, but only +one `ranch_sup` spec! + +It is recommended that your architecture makes sure that all listeners +are restarted if `ranch_sup` fails. See the Ranch internals chapter for +more details on how Ranch does it. diff --git a/docs/en/ranch/1.3/guide/embedded/index.html b/docs/en/ranch/1.3/guide/embedded/index.html new file mode 100644 index 00000000..a18a512d --- /dev/null +++ b/docs/en/ranch/1.3/guide/embedded/index.html @@ -0,0 +1,205 @@ + + + + + + + + + + + + Nine Nines: Embedded mode + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Embedded mode

    + +

    Embedded mode allows you to insert Ranch listeners directly +in your supervision tree. This allows for greater fault tolerance +control by permitting the shutdown of a listener due to the +failure of another part of the application and vice versa.

    +
    +

    Embedding

    +
    +

    To embed Ranch in your application you can simply add the child specs +to your supervision tree. This can all be done in the init/1 function +of one of your application supervisors.

    +

    Ranch requires at the minimum two kinds of child specs for embedding. +First, you need to add ranch_sup to your supervision tree, only once, +regardless of the number of listeners you will use. Then you need to +add the child specs for each listener.

    +

    Ranch has a convenience function for getting the listeners child specs +called ranch:child_spec/6, that works like ranch:start_listener/6, +except that it doesn’t start anything, it only returns child specs.

    +

    As for ranch_sup, the child spec is simple enough to not require a +convenience function.

    +

    The following example adds both ranch_sup and one listener to another +application’s supervision tree.

    +
    +
    Embed Ranch directly in your supervision tree
    +
    +
    init([]) ->
    +        RanchSupSpec = {ranch_sup, {ranch_sup, start_link, []},
    +                permanent, 5000, supervisor, [ranch_sup]},
    +        ListenerSpec = ranch:child_spec(echo, 100,
    +                ranch_tcp, [{port, 5555}],
    +                echo_protocol, []
    +        ),
    +        {ok, {{one_for_one, 10, 10}, [RanchSupSpec, ListenerSpec]}}.
    +

    Remember, you can add as many listener child specs as needed, but only +one ranch_sup spec!

    +

    It is recommended that your architecture makes sure that all listeners +are restarted if ranch_sup fails. See the Ranch internals chapter for +more details on how Ranch does it.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/index.html b/docs/en/ranch/1.3/guide/index.html new file mode 100644 index 00000000..95e87dea --- /dev/null +++ b/docs/en/ranch/1.3/guide/index.html @@ -0,0 +1,186 @@ + + + + + + + + + + + + Nine Nines: Ranch User Guide + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Ranch User Guide

    + +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/internals.asciidoc b/docs/en/ranch/1.3/guide/internals.asciidoc new file mode 100644 index 00000000..fa63f1d3 --- /dev/null +++ b/docs/en/ranch/1.3/guide/internals.asciidoc @@ -0,0 +1,94 @@ +== Internals + +This chapter may not apply to embedded Ranch as embedding allows you +to use an architecture specific to your application, which may or may +not be compatible with the description of the Ranch application. + +Note that for everything related to efficiency and performance, +you should perform the benchmarks yourself to get the numbers that +matter to you. Generic benchmarks found on the web may or may not +be of use to you, you can never know until you benchmark your own +system. + +=== Architecture + +Ranch is an OTP application. + +Like all OTP applications, Ranch has a top supervisor. It is responsible +for supervising the `ranch_server` process and all the listeners that +will be started. + +The `ranch_server` gen_server is a central process keeping track of the +listeners and their acceptors. It does so through the use of a public ets +table called `ranch_server`. The table is owned by the top supervisor +to improve fault tolerance. This way if the `ranch_server` gen_server +fails, it doesn't lose any information and the restarted process can +continue as if nothing happened. + +Ranch uses a custom supervisor for managing connections. This supervisor +keeps track of the number of connections and handles connection limits +directly. While it is heavily optimized to perform the task of creating +connection processes for accepted connections, it is still following the +OTP principles and the usual `sys` and `supervisor` calls will work on +it as expected. + +Listeners are grouped into the `ranch_listener_sup` supervisor and +consist of three kinds of processes: the listener gen_server, the +acceptor processes and the connection processes, both grouped under +their own supervisor. All of these processes are registered to the +`ranch_server` gen_server with varying amount of information. + +All socket operations, including listening for connections, go through +transport handlers. Accepted connections are given to the protocol handler. +Transport handlers are simple callback modules for performing operations on +sockets. Protocol handlers start a new process, which receives socket +ownership, with no requirements on how the code should be written inside +that new process. + +=== Number of acceptors + +The second argument to `ranch:start_listener/6` is the number of +processes that will be accepting connections. Care should be taken +when choosing this number. + +First of all, it should not be confused with the maximum number +of connections. Acceptor processes are only used for accepting and +have nothing else in common with connection processes. Therefore +there is nothing to be gained from setting this number too high, +in fact it can slow everything else down. + +Second, this number should be high enough to allow Ranch to accept +connections concurrently. But the number of cores available doesn't +seem to be the only factor for choosing this number, as we can +observe faster accepts if we have more acceptors than cores. It +might be entirely dependent on the protocol, however. + +Our observations suggest that using 100 acceptors on modern hardware +is a good solution, as it's big enough to always have acceptors ready +and it's low enough that it doesn't have a negative impact on the +system's performances. + +=== Platform-specific TCP features + +Some socket options are platform-specific and not supported by `inet`. +They can be of interest because they generally are related to +optimizations provided by the underlying OS. They can still be enabled +thanks to the `raw` option, for which we will see an example. + +One of these features is `TCP_DEFER_ACCEPT` on Linux. It is a simplified +accept mechanism which will wait for application data to come in before +handing out the connection to the Erlang process. + +This is especially useful if you expect many connections to be mostly +idle, perhaps part of a connection pool. They can be handled by the +kernel directly until they send any real data, instead of allocating +resources to idle connections. + +To enable this mechanism, the following option can be used. + +.Using raw transport options + +[source,erlang] +{raw, 6, 9, << 30:32/native >>} + +It means go on layer 6, turn on option 9 with the given integer parameter. diff --git a/docs/en/ranch/1.3/guide/internals/index.html b/docs/en/ranch/1.3/guide/internals/index.html new file mode 100644 index 00000000..2a778619 --- /dev/null +++ b/docs/en/ranch/1.3/guide/internals/index.html @@ -0,0 +1,246 @@ + + + + + + + + + + + + Nine Nines: Internals + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Internals

    + +

    This chapter may not apply to embedded Ranch as embedding allows you +to use an architecture specific to your application, which may or may +not be compatible with the description of the Ranch application.

    +

    Note that for everything related to efficiency and performance, +you should perform the benchmarks yourself to get the numbers that +matter to you. Generic benchmarks found on the web may or may not +be of use to you, you can never know until you benchmark your own +system.

    +
    +

    Architecture

    +
    +

    Ranch is an OTP application.

    +

    Like all OTP applications, Ranch has a top supervisor. It is responsible +for supervising the ranch_server process and all the listeners that +will be started.

    +

    The ranch_server gen_server is a central process keeping track of the +listeners and their acceptors. It does so through the use of a public ets +table called ranch_server. The table is owned by the top supervisor +to improve fault tolerance. This way if the ranch_server gen_server +fails, it doesn’t lose any information and the restarted process can +continue as if nothing happened.

    +

    Ranch uses a custom supervisor for managing connections. This supervisor +keeps track of the number of connections and handles connection limits +directly. While it is heavily optimized to perform the task of creating +connection processes for accepted connections, it is still following the +OTP principles and the usual sys and supervisor calls will work on +it as expected.

    +

    Listeners are grouped into the ranch_listener_sup supervisor and +consist of three kinds of processes: the listener gen_server, the +acceptor processes and the connection processes, both grouped under +their own supervisor. All of these processes are registered to the +ranch_server gen_server with varying amount of information.

    +

    All socket operations, including listening for connections, go through +transport handlers. Accepted connections are given to the protocol handler. +Transport handlers are simple callback modules for performing operations on +sockets. Protocol handlers start a new process, which receives socket +ownership, with no requirements on how the code should be written inside +that new process.

    +
    +
    +
    +

    Number of acceptors

    +
    +

    The second argument to ranch:start_listener/6 is the number of +processes that will be accepting connections. Care should be taken +when choosing this number.

    +

    First of all, it should not be confused with the maximum number +of connections. Acceptor processes are only used for accepting and +have nothing else in common with connection processes. Therefore +there is nothing to be gained from setting this number too high, +in fact it can slow everything else down.

    +

    Second, this number should be high enough to allow Ranch to accept +connections concurrently. But the number of cores available doesn’t +seem to be the only factor for choosing this number, as we can +observe faster accepts if we have more acceptors than cores. It +might be entirely dependent on the protocol, however.

    +

    Our observations suggest that using 100 acceptors on modern hardware +is a good solution, as it’s big enough to always have acceptors ready +and it’s low enough that it doesn’t have a negative impact on the +system’s performances.

    +
    +
    +
    +

    Platform-specific TCP features

    +
    +

    Some socket options are platform-specific and not supported by inet. +They can be of interest because they generally are related to +optimizations provided by the underlying OS. They can still be enabled +thanks to the raw option, for which we will see an example.

    +

    One of these features is TCP_DEFER_ACCEPT on Linux. It is a simplified +accept mechanism which will wait for application data to come in before +handing out the connection to the Erlang process.

    +

    This is especially useful if you expect many connections to be mostly +idle, perhaps part of a connection pool. They can be handled by the +kernel directly until they send any real data, instead of allocating +resources to idle connections.

    +

    To enable this mechanism, the following option can be used.

    +
    +
    Using raw transport options
    +
    +
    {raw, 6, 9, << 30:32/native >>}
    +

    It means go on layer 6, turn on option 9 with the given integer parameter.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/introduction.asciidoc b/docs/en/ranch/1.3/guide/introduction.asciidoc new file mode 100644 index 00000000..ac27862e --- /dev/null +++ b/docs/en/ranch/1.3/guide/introduction.asciidoc @@ -0,0 +1,28 @@ +== Introduction + +Ranch is a socket acceptor pool for TCP protocols. + +Ranch aims to provide everything you need to accept TCP connections +with a small code base and low latency while being easy to use directly +as an application or to embed into your own. + +=== Prerequisites + +It is assumed the developer already knows Erlang and has some experience +with socket programming and TCP protocols. + +=== Supported platforms + +Ranch is tested and supported on Linux, FreeBSD, OSX and Windows. + +Ranch is developed for Erlang/OTP R16B+. + +There are known issues with the SSL application found in Erlang/OTP +18.3.2 and 18.3.3. These versions are therefore not supported. + +Ranch may be compiled on earlier Erlang versions with small source code +modifications but there is no guarantee that it will work as expected. + +=== Versioning + +Ranch uses http://semver.org/[Semantic Versioning 2.0.0] diff --git a/docs/en/ranch/1.3/guide/introduction/index.html b/docs/en/ranch/1.3/guide/introduction/index.html new file mode 100644 index 00000000..7420a70b --- /dev/null +++ b/docs/en/ranch/1.3/guide/introduction/index.html @@ -0,0 +1,187 @@ + + + + + + + + + + + + Nine Nines: Introduction + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Introduction

    + +

    Ranch is a socket acceptor pool for TCP protocols.

    +

    Ranch aims to provide everything you need to accept TCP connections +with a small code base and low latency while being easy to use directly +as an application or to embed into your own.

    +
    +

    Prerequisites

    +
    +

    It is assumed the developer already knows Erlang and has some experience +with socket programming and TCP protocols.

    +
    +
    +
    +

    Supported platforms

    +
    +

    Ranch is tested and supported on Linux, FreeBSD, OSX and Windows.

    +

    Ranch is developed for Erlang/OTP R16B+.

    +

    There are known issues with the SSL application found in Erlang/OTP +18.3.2 and 18.3.3. These versions are therefore not supported.

    +

    Ranch may be compiled on earlier Erlang versions with small source code +modifications but there is no guarantee that it will work as expected.

    +
    +
    +
    +

    Versioning

    + +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/listeners.asciidoc b/docs/en/ranch/1.3/guide/listeners.asciidoc new file mode 100644 index 00000000..1055b804 --- /dev/null +++ b/docs/en/ranch/1.3/guide/listeners.asciidoc @@ -0,0 +1,302 @@ +== Listeners + +A listener is a set of processes whose role is to listen on a port +for new connections. It manages a pool of acceptor processes, each +of them indefinitely accepting connections. When it does, it starts +a new process executing the protocol handler code. All the socket +programming is abstracted through the use of transport handlers. + +The listener takes care of supervising all the acceptor and connection +processes, allowing developers to focus on building their application. + +=== Starting a listener + +Ranch does nothing by default. It is up to the application developer +to request that Ranch listens for connections. + +A listener can be started and stopped at will. + +When starting a listener, a number of different settings are required: + +* A name to identify it locally and be able to interact with it. +* The number of acceptors in the pool. +* A transport handler and its associated options. +* A protocol handler and its associated options. + +Ranch includes both TCP and SSL transport handlers, respectively +`ranch_tcp` and `ranch_ssl`. + +A listener can be started by calling the `ranch:start_listener/6` +function. Before doing so however, you must ensure that the `ranch` +application is started. + +.Starting the Ranch application + +[source,erlang] +ok = application:start(ranch). + +You are then ready to start a listener. Let's call it `tcp_echo`. It will +have a pool of 100 acceptors, use a TCP transport and forward connections +to the `echo_protocol` handler. + +.Starting a listener for TCP connections on port 5555 + +[source,erlang] +{ok, _} = ranch:start_listener(tcp_echo, 100, + ranch_tcp, [{port, 5555}], + echo_protocol, [] +). + +You can try this out by compiling and running the `tcp_echo` example in the +examples directory. To do so, open a shell in the 'examples/tcp_echo/' +directory and run the following command: + +.Building and starting a Ranch example + +[source,bash] +$ make run + +You can then connect to it using telnet and see the echo server reply +everything you send to it. Then when you're done testing, you can use +the `Ctrl+]` key to escape to the telnet command line and type +`quit` to exit. + +.Connecting to the example listener with telnet + +[source,bash] +---- +$ telnet localhost 5555 +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. +Hello! +Hello! +It works! +It works! +^] + +telnet> quit +Connection closed. +---- + +=== Stopping a listener + +All you need to stop a Ranch listener is to call the +`ranch:stop_listener/1` function with the listener's name +as argument. In the previous section we started the listener +named `tcp_echo`. We can now stop it. + +.Stopping a listener + +[source,erlang] +ranch:stop_listener(tcp_echo). + +=== Default transport options + +By default the socket will be set to return `binary` data, with the +options `{active, false}`, `{packet, raw}`, `{reuseaddr, true}` set. +These values can't be overriden when starting the listener, but +they can be overriden using `Transport:setopts/2` in the protocol. + +It will also set `{backlog, 1024}` and `{nodelay, true}`, which +can be overriden at listener startup. + +=== Listening on a random port + +You do not have to specify a specific port to listen on. If you give +the port number 0, or if you omit the port number entirely, Ranch will +start listening on a random port. + +You can retrieve this port number by calling `ranch:get_port/1`. The +argument is the name of the listener you gave in `ranch:start_listener/6`. + +.Starting a listener for TCP connections on a random port + +[source,erlang] +{ok, _} = ranch:start_listener(tcp_echo, 100, + ranch_tcp, [{port, 0}], + echo_protocol, [] +). +Port = ranch:get_port(tcp_echo). + +=== Listening on privileged ports + +Some systems limit access to ports below 1024 for security reasons. +This can easily be identified by an `{error, eacces}` error when trying +to open a listening socket on such a port. + +The methods for listening on privileged ports vary between systems, +please refer to your system's documentation for more information. + +We recommend the use of port rewriting for systems with a single server, +and load balancing for systems with multiple servers. Documenting these +solutions is however out of the scope of this guide. + +=== Accepting connections on an existing socket + +If you want to accept connections on an existing socket, you can use the +`socket` transport option, which should just be the relevant data returned +from the connect function for the transport or the underlying socket library +(`gen_tcp:connect`, `ssl:connect`). The accept function will then be +called on the passed in socket. You should connect the socket in +`{active, false}` mode, as well. + +Note, however, that because of a bug in SSL, you cannot change ownership of an +SSL listen socket prior to R16. Ranch will catch the error thrown, but the +owner of the SSL socket will remain as whatever process created the socket. +However, this will not affect accept behaviour unless the owner process dies, +in which case the socket is closed. Therefore, to use this feature with SSL +with an erlang release prior to R16, ensure that the SSL socket is opened in a +persistant process. + +=== Limiting the number of concurrent connections + +The `max_connections` transport option allows you to limit the number +of concurrent connections. It defaults to 1024. Its purpose is to +prevent your system from being overloaded and ensuring all the +connections are handled optimally. + +.Customizing the maximum number of concurrent connections + +[source,erlang] +{ok, _} = ranch:start_listener(tcp_echo, 100, + ranch_tcp, [{port, 5555}, {max_connections, 100}], + echo_protocol, [] +). + +You can disable this limit by setting its value to the atom `infinity`. + +.Disabling the limit for the number of connections + +[source,erlang] +{ok, _} = ranch:start_listener(tcp_echo, 100, + ranch_tcp, [{port, 5555}, {max_connections, infinity}], + echo_protocol, [] +). + +The maximum number of connections is a soft limit. In practice, it +can reach `max_connections` + the number of acceptors. + +When the maximum number of connections is reached, Ranch will stop +accepting connections. This will not result in further connections +being rejected, as the kernel option allows queueing incoming +connections. The size of this queue is determined by the `backlog` +option and defaults to 1024. Ranch does not know about the number +of connections that are in the backlog. + +You may not always want connections to be counted when checking for +`max_connections`. For example you might have a protocol where both +short-lived and long-lived connections are possible. If the long-lived +connections are mostly waiting for messages, then they don't consume +much resources and can safely be removed from the count. + +To remove the connection from the count, you must call the +`ranch:remove_connection/1` from within the connection process, +with the name of the listener as the only argument. + +.Removing a connection from the count of connections + +[source,erlang] +ranch:remove_connection(Ref). + +As seen in the chapter covering protocols, this pid is received as the +first argument of the protocol's `start_link/4` callback. + +You can modify the `max_connections` value on a running listener by +using the `ranch:set_max_connections/2` function, with the name of the +listener as first argument and the new value as the second. + +.Upgrading the maximum number of connections + +[source,erlang] +ranch:set_max_connections(tcp_echo, MaxConns). + +The change will occur immediately. + +=== When running out of file descriptors + +Operating systems have limits on the number of sockets +which can be opened by applications. When this maximum is +reached the listener can no longer accept new connections. The +accept rate of the listener will be automatically reduced, and a +warning message will be logged. + +---- +=ERROR REPORT==== 13-Jan-2016::12:24:38 === +Ranch acceptor reducing accept rate: out of file descriptors +---- + +If you notice messages like this you should increase the number +of file-descriptors which can be opened by your application. How +this should be done is operating-system dependent. Please consult +the documentation of your operating system. + +=== Using a supervisor for connection processes + +Ranch allows you to define the type of process that will be used +for the connection processes. By default it expects a `worker`. +When the `connection_type` configuration value is set to `supervisor`, +Ranch will consider that the connection process it manages is a +supervisor and will reflect that in its supervision tree. + +Connection processes of type `supervisor` can either handle the +socket directly or through one of their children. In the latter +case the start function for the connection process must return +two pids: the pid of the supervisor you created (that will be +supervised) and the pid of the protocol handling process (that +will receive the socket). + +Instead of returning `{ok, ConnPid}`, simply return +`{ok, SupPid, ConnPid}`. + +It is very important that the connection process be created +under the supervisor process so that everything works as intended. +If not, you will most likely experience issues when the supervised +process is stopped. + +=== Upgrading + +Ranch allows you to upgrade the protocol options. This takes effect +immediately and for all subsequent connections. + +To upgrade the protocol options, call `ranch:set_protocol_options/2` +with the name of the listener as first argument and the new options +as the second. + +.Upgrading the protocol options + +[source,erlang] +ranch:set_protocol_options(tcp_echo, NewOpts). + +All future connections will use the new options. + +You can also retrieve the current options similarly by +calling `ranch:get_protocol_options/1`. + +.Retrieving the current protocol options + +[source,erlang] +Opts = ranch:get_protocol_options(tcp_echo). + +=== Obtain information about listeners + +Ranch provides two functions for retrieving information about the +listeners, for reporting and diagnostic purposes. + +The `ranch:info/0` function will return detailed information +about all listeners. + +.Retrieving detailed information +[source,erlang] +ranch:info(). + +The `ranch:procs/2` function will return all acceptor or listener +processes for a given listener. + +.Get all acceptor processes +[source,erlang] +ranch:procs(tcp_echo, acceptors). + +.Get all connection processes +[source,erlang] +ranch:procs(tcp_echo, connections). diff --git a/docs/en/ranch/1.3/guide/listeners/index.html b/docs/en/ranch/1.3/guide/listeners/index.html new file mode 100644 index 00000000..48143ae5 --- /dev/null +++ b/docs/en/ranch/1.3/guide/listeners/index.html @@ -0,0 +1,503 @@ + + + + + + + + + + + + Nine Nines: Listeners + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Listeners

    + +

    A listener is a set of processes whose role is to listen on a port +for new connections. It manages a pool of acceptor processes, each +of them indefinitely accepting connections. When it does, it starts +a new process executing the protocol handler code. All the socket +programming is abstracted through the use of transport handlers.

    +

    The listener takes care of supervising all the acceptor and connection +processes, allowing developers to focus on building their application.

    +
    +

    Starting a listener

    +
    +

    Ranch does nothing by default. It is up to the application developer +to request that Ranch listens for connections.

    +

    A listener can be started and stopped at will.

    +

    When starting a listener, a number of different settings are required:

    +
      +
    • +

      +A name to identify it locally and be able to interact with it. +

      +
    • +
    • +

      +The number of acceptors in the pool. +

      +
    • +
    • +

      +A transport handler and its associated options. +

      +
    • +
    • +

      +A protocol handler and its associated options. +

      +
    • +
    +

    Ranch includes both TCP and SSL transport handlers, respectively +ranch_tcp and ranch_ssl.

    +

    A listener can be started by calling the ranch:start_listener/6 +function. Before doing so however, you must ensure that the ranch +application is started.

    +
    +
    Starting the Ranch application
    +
    +
    ok = application:start(ranch).
    +

    You are then ready to start a listener. Let’s call it tcp_echo. It will +have a pool of 100 acceptors, use a TCP transport and forward connections +to the echo_protocol handler.

    +
    +
    Starting a listener for TCP connections on port 5555
    +
    +
    {ok, _} = ranch:start_listener(tcp_echo, 100,
    +        ranch_tcp, [{port, 5555}],
    +        echo_protocol, []
    +).
    +

    You can try this out by compiling and running the tcp_echo example in the +examples directory. To do so, open a shell in the examples/tcp_echo/ +directory and run the following command:

    +
    +
    Building and starting a Ranch example
    +
    +
    $ make run
    +

    You can then connect to it using telnet and see the echo server reply +everything you send to it. Then when you’re done testing, you can use +the Ctrl+] key to escape to the telnet command line and type +quit to exit.

    +
    +
    Connecting to the example listener with telnet
    +
    +
    $ telnet localhost 5555
    +Trying 127.0.0.1...
    +Connected to localhost.
    +Escape character is '^]'.
    +Hello!
    +Hello!
    +It works!
    +It works!
    +^]
    +
    +telnet> quit
    +Connection closed.
    +
    +
    +
    +

    Stopping a listener

    +
    +

    All you need to stop a Ranch listener is to call the +ranch:stop_listener/1 function with the listener’s name +as argument. In the previous section we started the listener +named tcp_echo. We can now stop it.

    +
    +
    Stopping a listener
    +
    +
    ranch:stop_listener(tcp_echo).
    +
    +
    +
    +

    Default transport options

    +
    +

    By default the socket will be set to return binary data, with the +options {active, false}, {packet, raw}, {reuseaddr, true} set. +These values can’t be overriden when starting the listener, but +they can be overriden using Transport:setopts/2 in the protocol.

    +

    It will also set {backlog, 1024} and {nodelay, true}, which +can be overriden at listener startup.

    +
    +
    +
    +

    Listening on a random port

    +
    +

    You do not have to specify a specific port to listen on. If you give +the port number 0, or if you omit the port number entirely, Ranch will +start listening on a random port.

    +

    You can retrieve this port number by calling ranch:get_port/1. The +argument is the name of the listener you gave in ranch:start_listener/6.

    +
    +
    Starting a listener for TCP connections on a random port
    +
    +
    {ok, _} = ranch:start_listener(tcp_echo, 100,
    +        ranch_tcp, [{port, 0}],
    +        echo_protocol, []
    +).
    +Port = ranch:get_port(tcp_echo).
    +
    +
    +
    +

    Listening on privileged ports

    +
    +

    Some systems limit access to ports below 1024 for security reasons. +This can easily be identified by an {error, eacces} error when trying +to open a listening socket on such a port.

    +

    The methods for listening on privileged ports vary between systems, +please refer to your system’s documentation for more information.

    +

    We recommend the use of port rewriting for systems with a single server, +and load balancing for systems with multiple servers. Documenting these +solutions is however out of the scope of this guide.

    +
    +
    +
    +

    Accepting connections on an existing socket

    +
    +

    If you want to accept connections on an existing socket, you can use the +socket transport option, which should just be the relevant data returned +from the connect function for the transport or the underlying socket library +(gen_tcp:connect, ssl:connect). The accept function will then be +called on the passed in socket. You should connect the socket in +{active, false} mode, as well.

    +

    Note, however, that because of a bug in SSL, you cannot change ownership of an +SSL listen socket prior to R16. Ranch will catch the error thrown, but the +owner of the SSL socket will remain as whatever process created the socket. +However, this will not affect accept behaviour unless the owner process dies, +in which case the socket is closed. Therefore, to use this feature with SSL +with an erlang release prior to R16, ensure that the SSL socket is opened in a +persistant process.

    +
    +
    +
    +

    Limiting the number of concurrent connections

    +
    +

    The max_connections transport option allows you to limit the number +of concurrent connections. It defaults to 1024. Its purpose is to +prevent your system from being overloaded and ensuring all the +connections are handled optimally.

    +
    +
    Customizing the maximum number of concurrent connections
    +
    +
    {ok, _} = ranch:start_listener(tcp_echo, 100,
    +        ranch_tcp, [{port, 5555}, {max_connections, 100}],
    +        echo_protocol, []
    +).
    +

    You can disable this limit by setting its value to the atom infinity.

    +
    +
    Disabling the limit for the number of connections
    +
    +
    {ok, _} = ranch:start_listener(tcp_echo, 100,
    +        ranch_tcp, [{port, 5555}, {max_connections, infinity}],
    +        echo_protocol, []
    +).
    +

    The maximum number of connections is a soft limit. In practice, it +can reach max_connections + the number of acceptors.

    +

    When the maximum number of connections is reached, Ranch will stop +accepting connections. This will not result in further connections +being rejected, as the kernel option allows queueing incoming +connections. The size of this queue is determined by the backlog +option and defaults to 1024. Ranch does not know about the number +of connections that are in the backlog.

    +

    You may not always want connections to be counted when checking for +max_connections. For example you might have a protocol where both +short-lived and long-lived connections are possible. If the long-lived +connections are mostly waiting for messages, then they don’t consume +much resources and can safely be removed from the count.

    +

    To remove the connection from the count, you must call the +ranch:remove_connection/1 from within the connection process, +with the name of the listener as the only argument.

    +
    +
    Removing a connection from the count of connections
    +
    +
    ranch:remove_connection(Ref).
    +

    As seen in the chapter covering protocols, this pid is received as the +first argument of the protocol’s start_link/4 callback.

    +

    You can modify the max_connections value on a running listener by +using the ranch:set_max_connections/2 function, with the name of the +listener as first argument and the new value as the second.

    +
    +
    Upgrading the maximum number of connections
    +
    +
    ranch:set_max_connections(tcp_echo, MaxConns).
    +

    The change will occur immediately.

    +
    +
    +
    +

    When running out of file descriptors

    +
    +

    Operating systems have limits on the number of sockets +which can be opened by applications. When this maximum is +reached the listener can no longer accept new connections. The +accept rate of the listener will be automatically reduced, and a +warning message will be logged.

    +
    +
    +
    =ERROR REPORT==== 13-Jan-2016::12:24:38 ===
    +Ranch acceptor reducing accept rate: out of file descriptors
    +
    +

    If you notice messages like this you should increase the number +of file-descriptors which can be opened by your application. How +this should be done is operating-system dependent. Please consult +the documentation of your operating system.

    +
    +
    +
    +

    Using a supervisor for connection processes

    +
    +

    Ranch allows you to define the type of process that will be used +for the connection processes. By default it expects a worker. +When the connection_type configuration value is set to supervisor, +Ranch will consider that the connection process it manages is a +supervisor and will reflect that in its supervision tree.

    +

    Connection processes of type supervisor can either handle the +socket directly or through one of their children. In the latter +case the start function for the connection process must return +two pids: the pid of the supervisor you created (that will be +supervised) and the pid of the protocol handling process (that +will receive the socket).

    +

    Instead of returning {ok, ConnPid}, simply return +{ok, SupPid, ConnPid}.

    +

    It is very important that the connection process be created +under the supervisor process so that everything works as intended. +If not, you will most likely experience issues when the supervised +process is stopped.

    +
    +
    +
    +

    Upgrading

    +
    +

    Ranch allows you to upgrade the protocol options. This takes effect +immediately and for all subsequent connections.

    +

    To upgrade the protocol options, call ranch:set_protocol_options/2 +with the name of the listener as first argument and the new options +as the second.

    +
    +
    Upgrading the protocol options
    +
    +
    ranch:set_protocol_options(tcp_echo, NewOpts).
    +

    All future connections will use the new options.

    +

    You can also retrieve the current options similarly by +calling ranch:get_protocol_options/1.

    +
    +
    Retrieving the current protocol options
    +
    +
    Opts = ranch:get_protocol_options(tcp_echo).
    +
    +
    +
    +

    Obtain information about listeners

    +
    +

    Ranch provides two functions for retrieving information about the +listeners, for reporting and diagnostic purposes.

    +

    The ranch:info/0 function will return detailed information +about all listeners.

    +
    +
    Retrieving detailed information
    +
    +
    ranch:info().
    +

    The ranch:procs/2 function will return all acceptor or listener +processes for a given listener.

    +
    +
    Get all acceptor processes
    +
    +
    ranch:procs(tcp_echo, acceptors).
    +
    +
    Get all connection processes
    +
    +
    ranch:procs(tcp_echo, connections).
    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/parsers.asciidoc b/docs/en/ranch/1.3/guide/parsers.asciidoc new file mode 100644 index 00000000..9eacbfa9 --- /dev/null +++ b/docs/en/ranch/1.3/guide/parsers.asciidoc @@ -0,0 +1,92 @@ +== Writing parsers + +There are three kinds of protocols: + +* Text protocols +* Schema-less binary protocols +* Schema-based binary protocols + +This chapter introduces the first two kinds. It will not cover +more advanced topics such as continuations or parser generators. + +This chapter isn't specifically about Ranch, we assume here that +you know how to read data from the socket. The data you read and +the data that hasn't been parsed is saved in a buffer. Every +time you read from the socket, the data read is appended to the +buffer. What happens next depends on the kind of protocol. We +will only cover the first two. + +=== Parsing text + +Text protocols are generally line based. This means that we can't +do anything with them until we receive the full line. + +A simple way to get a full line is to use `binary:split/{2,3}`. + +.Using binary:split/2 to get a line of input + +[source,erlang] +case binary:split(Buffer, <<"\n">>) of + [_] -> + get_more_data(Buffer); + [Line, Rest] -> + handle_line(Line, Rest) +end. + +In the above example, we can have two results. Either there was +a line break in the buffer and we get it split into two parts, +the line and the rest of the buffer; or there was no line break +in the buffer and we need to get more data from the socket. + +Next, we need to parse the line. The simplest way is to again +split, here on space. The difference is that we want to split +on all spaces character, as we want to tokenize the whole string. + +.Using binary:split/3 to split text + +[source,erlang] +case binary:split(Line, <<" ">>, [global]) of + [<<"HELLO">>] -> + be_polite(); + [<<"AUTH">>, User, Password] -> + authenticate_user(User, Password); + [<<"QUIT">>, Reason] -> + quit(Reason) + %% ... +end. + +Pretty simple, right? Match on the command name, get the rest +of the tokens in variables and call the respective functions. + +After doing this, you will want to check if there is another +line in the buffer, and handle it immediately if any. +Otherwise wait for more data. + +=== Parsing binary + +Binary protocols can be more varied, although most of them are +pretty similar. The first four bytes of a frame tend to be +the size of the frame, which is followed by a certain number +of bytes for the type of frame and then various parameters. + +Sometimes the size of the frame includes the first four bytes, +sometimes not. Other times this size is encoded over two bytes. +And even other times little-endian is used instead of big-endian. + +The general idea stays the same though. + +.Using binary pattern matching to split frames + +[source,erlang] +<< Size:32, _/bits >> = Buffer, +case Buffer of + << Frame:Size/binary, Rest/bits >> -> + handle_frame(Frame, Rest); + _ -> + get_more_data(Buffer) +end. + +You will then need to parse this frame using binary pattern +matching, and handle it. Then you will want to check if there +is another frame fully received in the buffer, and handle it +immediately if any. Otherwise wait for more data. diff --git a/docs/en/ranch/1.3/guide/parsers/index.html b/docs/en/ranch/1.3/guide/parsers/index.html new file mode 100644 index 00000000..96660915 --- /dev/null +++ b/docs/en/ranch/1.3/guide/parsers/index.html @@ -0,0 +1,266 @@ + + + + + + + + + + + + Nine Nines: Writing parsers + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Writing parsers

    + +

    There are three kinds of protocols:

    +
      +
    • +

      +Text protocols +

      +
    • +
    • +

      +Schema-less binary protocols +

      +
    • +
    • +

      +Schema-based binary protocols +

      +
    • +
    +

    This chapter introduces the first two kinds. It will not cover +more advanced topics such as continuations or parser generators.

    +

    This chapter isn’t specifically about Ranch, we assume here that +you know how to read data from the socket. The data you read and +the data that hasn’t been parsed is saved in a buffer. Every +time you read from the socket, the data read is appended to the +buffer. What happens next depends on the kind of protocol. We +will only cover the first two.

    +
    +

    Parsing text

    +
    +

    Text protocols are generally line based. This means that we can’t +do anything with them until we receive the full line.

    +

    A simple way to get a full line is to use binary:split/{2,3}.

    +
    +
    Using binary:split/2 to get a line of input
    +
    +
    case binary:split(Buffer, <<"\n">>) of
    +        [_] ->
    +                get_more_data(Buffer);
    +        [Line, Rest] ->
    +                handle_line(Line, Rest)
    +end.
    +

    In the above example, we can have two results. Either there was +a line break in the buffer and we get it split into two parts, +the line and the rest of the buffer; or there was no line break +in the buffer and we need to get more data from the socket.

    +

    Next, we need to parse the line. The simplest way is to again +split, here on space. The difference is that we want to split +on all spaces character, as we want to tokenize the whole string.

    +
    +
    Using binary:split/3 to split text
    +
    +
    case binary:split(Line, <<" ">>, [global]) of
    +        [<<"HELLO">>] ->
    +                be_polite();
    +        [<<"AUTH">>, User, Password] ->
    +                authenticate_user(User, Password);
    +        [<<"QUIT">>, Reason] ->
    +                quit(Reason)
    +        %% ...
    +end.
    +

    Pretty simple, right? Match on the command name, get the rest +of the tokens in variables and call the respective functions.

    +

    After doing this, you will want to check if there is another +line in the buffer, and handle it immediately if any. +Otherwise wait for more data.

    +
    +
    +
    +

    Parsing binary

    +
    +

    Binary protocols can be more varied, although most of them are +pretty similar. The first four bytes of a frame tend to be +the size of the frame, which is followed by a certain number +of bytes for the type of frame and then various parameters.

    +

    Sometimes the size of the frame includes the first four bytes, +sometimes not. Other times this size is encoded over two bytes. +And even other times little-endian is used instead of big-endian.

    +

    The general idea stays the same though.

    +
    +
    Using binary pattern matching to split frames
    +
    +
    << Size:32, _/bits >> = Buffer,
    +case Buffer of
    +        << Frame:Size/binary, Rest/bits >> ->
    +                handle_frame(Frame, Rest);
    +        _ ->
    +                get_more_data(Buffer)
    +end.
    +

    You will then need to parse this frame using binary pattern +matching, and handle it. Then you will want to check if there +is another frame fully received in the buffer, and handle it +immediately if any. Otherwise wait for more data.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/protocols.asciidoc b/docs/en/ranch/1.3/guide/protocols.asciidoc new file mode 100644 index 00000000..48c74ef5 --- /dev/null +++ b/docs/en/ranch/1.3/guide/protocols.asciidoc @@ -0,0 +1,99 @@ +== Protocols + +A protocol handler starts a connection process and defines the +protocol logic executed in this process. + +=== Writing a protocol handler + +All protocol handlers must implement the `ranch_protocol` behavior +which defines a single callback, `start_link/4`. This callback is +responsible for spawning a new process for handling the connection. +It receives four arguments: the name of the listener, the socket, the +transport handler being used and the protocol options defined in +the call to `ranch:start_listener/6`. This callback must +return `{ok, Pid}`, with `Pid` the pid of the new process. + +The newly started process can then freely initialize itself. However, +it must call `ranch:accept_ack/1` before doing any socket operation. +This will ensure the connection process is the owner of the socket. +It expects the listener's name as argument. + +.Acknowledge accepting the socket + +[source,erlang] +ok = ranch:accept_ack(Ref). + +If your protocol code requires specific socket options, you should +set them while initializing your connection process, after +calling `ranch:accept_ack/1`. You can use `Transport:setopts/2` +for that purpose. + +Following is the complete protocol code for the example found +in `examples/tcp_echo/`. + +.Protocol module that echoes everything it receives + +[source,erlang] +---- +-module(echo_protocol). +-behaviour(ranch_protocol). + +-export([start_link/4]). +-export([init/4]). + +start_link(Ref, Socket, Transport, Opts) -> + Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]), + {ok, Pid}. + +init(Ref, Socket, Transport, _Opts = []) -> + ok = ranch:accept_ack(Ref), + loop(Socket, Transport). + +loop(Socket, Transport) -> + case Transport:recv(Socket, 0, 5000) of + {ok, Data} -> + Transport:send(Socket, Data), + loop(Socket, Transport); + _ -> + ok = Transport:close(Socket) + end. +---- + +=== Using gen_server + +Special processes like the ones that use the `gen_server` or `gen_fsm` +behaviours have the particularity of having their `start_link` call not +return until the `init` function returns. This is problematic, because +you won't be able to call `ranch:accept_ack/1` from the `init` callback +as this would cause a deadlock to happen. + +Use the `gen_server:enter_loop/3` function. It allows you to start your process +normally (although it must be started with `proc_lib` like all special +processes), then perform any needed operations before falling back into +the normal `gen_server` execution loop. + +.Use a gen_server for protocol handling + +[source,erlang] +---- +-module(my_protocol). +-behaviour(gen_server). +-behaviour(ranch_protocol). + +-export([start_link/4]). +-export([init/1]). +%% Exports of other gen_server callbacks here. + +start_link(Ref, Socket, Transport, Opts) -> + {ok, proc_lib:spawn_link(?MODULE, init, [{Ref, Socket, Transport, Opts}])}. + +init({Ref, Socket, Transport, _Opts = []}) -> + %% Perform any required state initialization here. + ok = ranch:accept_ack(Ref), + ok = Transport:setopts(Socket, [{active, once}]), + gen_server:enter_loop(?MODULE, [], {state, Socket, Transport}). + +%% Other gen_server callbacks here. +---- + +Check the `tcp_reverse` example for a complete example. diff --git a/docs/en/ranch/1.3/guide/protocols/index.html b/docs/en/ranch/1.3/guide/protocols/index.html new file mode 100644 index 00000000..e2f3d946 --- /dev/null +++ b/docs/en/ranch/1.3/guide/protocols/index.html @@ -0,0 +1,261 @@ + + + + + + + + + + + + Nine Nines: Protocols + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Protocols

    + +

    A protocol handler starts a connection process and defines the +protocol logic executed in this process.

    +
    +

    Writing a protocol handler

    +
    +

    All protocol handlers must implement the ranch_protocol behavior +which defines a single callback, start_link/4. This callback is +responsible for spawning a new process for handling the connection. +It receives four arguments: the name of the listener, the socket, the +transport handler being used and the protocol options defined in +the call to ranch:start_listener/6. This callback must +return {ok, Pid}, with Pid the pid of the new process.

    +

    The newly started process can then freely initialize itself. However, +it must call ranch:accept_ack/1 before doing any socket operation. +This will ensure the connection process is the owner of the socket. +It expects the listener’s name as argument.

    +
    +
    Acknowledge accepting the socket
    +
    +
    ok = ranch:accept_ack(Ref).
    +

    If your protocol code requires specific socket options, you should +set them while initializing your connection process, after +calling ranch:accept_ack/1. You can use Transport:setopts/2 +for that purpose.

    +

    Following is the complete protocol code for the example found +in examples/tcp_echo/.

    +
    +
    Protocol module that echoes everything it receives
    +
    +
    -module(echo_protocol).
    +-behaviour(ranch_protocol).
    +
    +-export([start_link/4]).
    +-export([init/4]).
    +
    +start_link(Ref, Socket, Transport, Opts) ->
    +        Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]),
    +        {ok, Pid}.
    +
    +init(Ref, Socket, Transport, _Opts = []) ->
    +        ok = ranch:accept_ack(Ref),
    +        loop(Socket, Transport).
    +
    +loop(Socket, Transport) ->
    +        case Transport:recv(Socket, 0, 5000) of
    +                {ok, Data} ->
    +                        Transport:send(Socket, Data),
    +                        loop(Socket, Transport);
    +                _ ->
    +                        ok = Transport:close(Socket)
    +        end.
    +
    +
    +
    +

    Using gen_server

    +
    +

    Special processes like the ones that use the gen_server or gen_fsm +behaviours have the particularity of having their start_link call not +return until the init function returns. This is problematic, because +you won’t be able to call ranch:accept_ack/1 from the init callback +as this would cause a deadlock to happen.

    +

    Use the gen_server:enter_loop/3 function. It allows you to start your process +normally (although it must be started with proc_lib like all special +processes), then perform any needed operations before falling back into +the normal gen_server execution loop.

    +
    +
    Use a gen_server for protocol handling
    +
    +
    -module(my_protocol).
    +-behaviour(gen_server).
    +-behaviour(ranch_protocol).
    +
    +-export([start_link/4]).
    +-export([init/1]).
    +%% Exports of other gen_server callbacks here.
    +
    +start_link(Ref, Socket, Transport, Opts) ->
    +        {ok, proc_lib:spawn_link(?MODULE, init, [{Ref, Socket, Transport, Opts}])}.
    +
    +init({Ref, Socket, Transport, _Opts = []}) ->
    +        %% Perform any required state initialization here.
    +        ok = ranch:accept_ack(Ref),
    +        ok = Transport:setopts(Socket, [{active, once}]),
    +        gen_server:enter_loop(?MODULE, [], {state, Socket, Transport}).
    +
    +%% Other gen_server callbacks here.
    +

    Check the tcp_reverse example for a complete example.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/ssl_auth.asciidoc b/docs/en/ranch/1.3/guide/ssl_auth.asciidoc new file mode 100644 index 00000000..de0bbaf0 --- /dev/null +++ b/docs/en/ranch/1.3/guide/ssl_auth.asciidoc @@ -0,0 +1,120 @@ +== SSL client authentication + +=== Purpose + +SSL client authentication is a mechanism allowing applications to +identify certificates. This allows your application to make sure that +the client is an authorized certificate, but makes no claim about +whether the user can be trusted. This can be combined with a password +based authentication to attain greater security. + +The server only needs to retain the certificate serial number and +the certificate issuer to authenticate the certificate. Together, +they can be used to uniquely identify a certicate. + +As Ranch allows the same protocol code to be used for both SSL and +non-SSL transports, you need to make sure you are in an SSL context +before attempting to perform an SSL client authentication. This +can be done by checking the return value of `Transport:name/0`. + +=== Obtaining client certificates + +You can obtain client certificates from various sources. You can +generate them yourself, or you can use a service like CAcert.org +which allows you to generate client and server certificates for +free. + +Following are the steps you need to take to create a CAcert.org +account, generate a certificate and install it in your favorite +browser. + +* Open http://cacert.org in your favorite browser +* Root Certificate link: install both certificates +* Join (Register an account) +* Verify your account (check your email inbox!) +* Log in +* Client Certificates: New +* Follow instructions to create the certificate +* Install the certificate in your browser + +You can optionally save the certificate for later use, for example +to extract the `IssuerID` information as will be detailed later on. + +=== Transport configuration + +The SSL transport does not request a client certificate by default. +You need to specify the `{verify, verify_peer}` option when starting +the listener to enable this behavior. + +.Configure a listener for SSL authentication + +[source,erlang] +{ok, _} = ranch:start_listener(my_ssl, 100, + ranch_ssl, [ + {port, SSLPort}, + {certfile, PathToCertfile}, + {cacertfile, PathToCACertfile}, + {verify, verify_peer} + ], + my_protocol, [] +). + +In this example we set the required `port` and `certfile`, but also +the `cacertfile` containing the CACert.org root certificate, and +the option to request the client certificate. + +If you enable the `{verify, verify_peer}` option and the client does +not have a client certificate configured for your domain, then no +certificate will be sent. This allows you to use SSL for more than +just authenticated clients. + +=== Authentication + +To authenticate users, you must first save the certificate information +required. If you have your users' certificate files, you can simply +load the certificate and retrieve the information directly. + +.Retrieve the issuer ID from a certificate + +[source,erlang] +---- +certfile_to_issuer_id(Filename) -> + {ok, Data} = file:read_file(Filename), + [{'Certificate', Cert, not_encrypted}] = public_key:pem_decode(Data), + {ok, IssuerID} = public_key:pkix_issuer_id(Cert, self), + IssuerID. +---- + +The `IssuerID` variable contains both the certificate serial number +and the certificate issuer stored in a tuple, so this value alone can +be used to uniquely identify the user certificate. You can save this +value in a database, a configuration file or any other place where an +Erlang term can be stored and retrieved. + +To retrieve the `IssuerID` from a running connection, you need to first +retrieve the client certificate and then extract this information from +it. Ranch does not provide a function to retrieve the client certificate. +Instead you can use the `ssl:peercert/1` function. Once you have the +certificate, you can again use the `public_key:pkix_issuer_id/2` to +extract the `IssuerID` value. + +The following function returns the `IssuerID` or `false` if no client +certificate was found. This snippet is intended to be used from your +protocol code. + +.Retrieve the issuer ID from the certificate for the current connection + +[source,erlang] +---- +socket_to_issuer_id(Socket) -> + case ssl:peercert(Socket) of + {error, no_peercert} -> + false; + {ok, Cert} -> + {ok, IssuerID} = public_key:pkix_issuer_id(Cert, self), + IssuerID + end. +---- + +You then only need to match the `IssuerID` value to authenticate the +user. diff --git a/docs/en/ranch/1.3/guide/ssl_auth/index.html b/docs/en/ranch/1.3/guide/ssl_auth/index.html new file mode 100644 index 00000000..868c2d1e --- /dev/null +++ b/docs/en/ranch/1.3/guide/ssl_auth/index.html @@ -0,0 +1,315 @@ + + + + + + + + + + + + Nine Nines: SSL client authentication + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    SSL client authentication

    + +
    +

    Purpose

    +
    +

    SSL client authentication is a mechanism allowing applications to +identify certificates. This allows your application to make sure that +the client is an authorized certificate, but makes no claim about +whether the user can be trusted. This can be combined with a password +based authentication to attain greater security.

    +

    The server only needs to retain the certificate serial number and +the certificate issuer to authenticate the certificate. Together, +they can be used to uniquely identify a certicate.

    +

    As Ranch allows the same protocol code to be used for both SSL and +non-SSL transports, you need to make sure you are in an SSL context +before attempting to perform an SSL client authentication. This +can be done by checking the return value of Transport:name/0.

    +
    +
    +
    +

    Obtaining client certificates

    +
    +

    You can obtain client certificates from various sources. You can +generate them yourself, or you can use a service like CAcert.org +which allows you to generate client and server certificates for +free.

    +

    Following are the steps you need to take to create a CAcert.org +account, generate a certificate and install it in your favorite +browser.

    +
      +
    • +

      +Open http://cacert.org in your favorite browser +

      +
    • +
    • +

      +Root Certificate link: install both certificates +

      +
    • +
    • +

      +Join (Register an account) +

      +
    • +
    • +

      +Verify your account (check your email inbox!) +

      +
    • +
    • +

      +Log in +

      +
    • +
    • +

      +Client Certificates: New +

      +
    • +
    • +

      +Follow instructions to create the certificate +

      +
    • +
    • +

      +Install the certificate in your browser +

      +
    • +
    +

    You can optionally save the certificate for later use, for example +to extract the IssuerID information as will be detailed later on.

    +
    +
    +
    +

    Transport configuration

    +
    +

    The SSL transport does not request a client certificate by default. +You need to specify the {verify, verify_peer} option when starting +the listener to enable this behavior.

    +
    +
    Configure a listener for SSL authentication
    +
    +
    {ok, _} = ranch:start_listener(my_ssl, 100,
    +        ranch_ssl, [
    +                {port, SSLPort},
    +                {certfile, PathToCertfile},
    +                {cacertfile, PathToCACertfile},
    +                {verify, verify_peer}
    +        ],
    +        my_protocol, []
    +).
    +

    In this example we set the required port and certfile, but also +the cacertfile containing the CACert.org root certificate, and +the option to request the client certificate.

    +

    If you enable the {verify, verify_peer} option and the client does +not have a client certificate configured for your domain, then no +certificate will be sent. This allows you to use SSL for more than +just authenticated clients.

    +
    +
    +
    +

    Authentication

    +
    +

    To authenticate users, you must first save the certificate information +required. If you have your users' certificate files, you can simply +load the certificate and retrieve the information directly.

    +
    +
    Retrieve the issuer ID from a certificate
    +
    +
    certfile_to_issuer_id(Filename) ->
    +        {ok, Data} = file:read_file(Filename),
    +        [{'Certificate', Cert, not_encrypted}] = public_key:pem_decode(Data),
    +        {ok, IssuerID} = public_key:pkix_issuer_id(Cert, self),
    +        IssuerID.
    +

    The IssuerID variable contains both the certificate serial number +and the certificate issuer stored in a tuple, so this value alone can +be used to uniquely identify the user certificate. You can save this +value in a database, a configuration file or any other place where an +Erlang term can be stored and retrieved.

    +

    To retrieve the IssuerID from a running connection, you need to first +retrieve the client certificate and then extract this information from +it. Ranch does not provide a function to retrieve the client certificate. +Instead you can use the ssl:peercert/1 function. Once you have the +certificate, you can again use the public_key:pkix_issuer_id/2 to +extract the IssuerID value.

    +

    The following function returns the IssuerID or false if no client +certificate was found. This snippet is intended to be used from your +protocol code.

    +
    +
    Retrieve the issuer ID from the certificate for the current connection
    +
    +
    socket_to_issuer_id(Socket) ->
    +        case ssl:peercert(Socket) of
    +                {error, no_peercert} ->
    +                        false;
    +                {ok, Cert} ->
    +                        {ok, IssuerID} = public_key:pkix_issuer_id(Cert, self),
    +                        IssuerID
    +        end.
    +

    You then only need to match the IssuerID value to authenticate the +user.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/guide/transports.asciidoc b/docs/en/ranch/1.3/guide/transports.asciidoc new file mode 100644 index 00000000..f5bb17eb --- /dev/null +++ b/docs/en/ranch/1.3/guide/transports.asciidoc @@ -0,0 +1,161 @@ +== Transports + +A transport defines the interface to interact with a socket. + +Transports can be used for connecting, listening and accepting +connections, but also for receiving and sending data. Both +passive and active mode are supported, although all sockets +are initialized as passive. + +=== TCP transport + +The TCP transport is a thin wrapper around `gen_tcp`. + +=== SSL transport + +The SSL transport is a thin wrapper around `ssl`. + +Ranch depends on `ssl` by default so any necessary +dependencies will start when Ranch is started. It is +possible to remove the dependency when the SSL transport +will not be used. Refer to your release build tool's +documentation for more information. + +When embedding Ranch listeners that have an SSL transport, +your application must depend on the `ssl` application for +proper behavior. + +=== Sending and receiving data + +This section assumes that `Transport` is a valid transport handler +(like `ranch_tcp` or `ranch_ssl`) and `Socket` is a connected +socket obtained through the listener. + +You can send data to a socket by calling the `Transport:send/2` +function. The data can be given as `iodata()`, which is defined as +`binary() | iolist()`. All the following calls will work: + +.Sending data to the socket + +[source,erlang] +---- +Transport:send(Socket, <<"Ranch is cool!">>). +Transport:send(Socket, "Ranch is cool!"). +Transport:send(Socket, ["Ranch", ["is", "cool!"]]). +Transport:send(Socket, ["Ranch", [<<"is">>, "cool!"]]). +---- + +You can receive data either in passive or in active mode. Passive mode +means that you will perform a blocking `Transport:recv/3` call, while +active mode means that you will receive the data as a message. + +By default, all data will be received as binary. It is possible to +receive data as strings, although this is not recommended as binaries +are a more efficient construct, especially for binary protocols. + +Receiving data using passive mode requires a single function call. The +first argument is the socket, and the third argument is a timeout duration +before the call returns with `{error, timeout}`. + +The second argument is the amount of data in bytes that we want to receive. +The function will wait for data until it has received exactly this amount. +If you are not expecting a precise size, you can specify 0 which will make +this call return as soon as data was read, regardless of its size. + +.Receiving data from the socket in passive mode + +[source,erlang] +{ok, Data} = Transport:recv(Socket, 0, 5000). + +Active mode requires you to inform the socket that you want to receive +data as a message and to write the code to actually receive it. + +There are two kinds of active modes: `{active, once}` and +`{active, true}`. The first will send a single message before going +back to passive mode; the second will send messages indefinitely. +We recommend not using the `{active, true}` mode as it could quickly +flood your process mailbox. It's better to keep the data in the socket +and read it only when required. + +Three different messages can be received: + +* `{OK, Socket, Data}` +* `{Closed, Socket}` +* `{Error, Socket, Reason}` + +The value of `OK`, `Closed` and `Error` can be different +depending on the transport being used. To be able to properly match +on them you must first call the `Transport:messages/0` function. + +.Retrieving the transport's active message identifiers + +[source,erlang] +{OK, Closed, Error} = Transport:messages(). + +To start receiving messages you will need to call the `Transport:setopts/2` +function, and do so every time you want to receive data. + +.Receiving messages from the socket in active mode + +[source,erlang] +---- +{OK, Closed, Error} = Transport:messages(), +Transport:setopts(Socket, [{active, once}]), +receive + {OK, Socket, Data} -> + io:format("data received: ~p~n", [Data]); + {Closed, Socket} -> + io:format("socket got closed!~n"); + {Error, Socket, Reason} -> + io:format("error happened: ~p~n", [Reason]) +end. +---- + +You can easily integrate active sockets with existing Erlang code as all +you really need is just a few more clauses when receiving messages. + +=== Sending files + +As in the previous section it is assumed `Transport` is a valid transport +handler and `Socket` is a connected socket obtained through the listener. + +To send a whole file, with name `Filename`, over a socket: + +.Sending a file by filename + +[source,erlang] +{ok, SentBytes} = Transport:sendfile(Socket, Filename). + +Or part of a file, with `Offset` greater than or equal to 0, `Bytes` number of +bytes and chunks of size `ChunkSize`: + +.Sending part of a file by filename in chunks + +[source,erlang] +Opts = [{chunk_size, ChunkSize}], +{ok, SentBytes} = Transport:sendfile(Socket, Filename, Offset, Bytes, Opts). + +To improve efficiency when sending multiple parts of the same file it is also +possible to use a file descriptor opened in raw mode: + +.Sending a file opened in raw mode + +[source,erlang] +{ok, RawFile} = file:open(Filename, [raw, read, binary]), +{ok, SentBytes} = Transport:sendfile(Socket, RawFile, Offset, Bytes, Opts). + +=== Writing a transport handler + +A transport handler is a module implementing the `ranch_transport` behavior. +It defines a certain number of callbacks that must be written in order to +allow transparent usage of the transport handler. + +The behavior doesn't define the socket options available when opening a +socket. These do not need to be common to all transports as it's easy enough +to write different initialization functions for the different transports that +will be used. With one exception though. The `setopts/2` function *must* +implement the `{active, once}` and the `{active, true}` options. + +If the transport handler doesn't have a native implementation of `sendfile/5` a +fallback is available, `ranch_transport:sendfile/6`. The extra first argument +is the transport's module. See `ranch_ssl` for an example. diff --git a/docs/en/ranch/1.3/guide/transports/index.html b/docs/en/ranch/1.3/guide/transports/index.html new file mode 100644 index 00000000..b96517ac --- /dev/null +++ b/docs/en/ranch/1.3/guide/transports/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + + + Nine Nines: Transports + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Transports

    + +

    A transport defines the interface to interact with a socket.

    +

    Transports can be used for connecting, listening and accepting +connections, but also for receiving and sending data. Both +passive and active mode are supported, although all sockets +are initialized as passive.

    +
    +

    TCP transport

    +
    +

    The TCP transport is a thin wrapper around gen_tcp.

    +
    +
    +
    +

    SSL transport

    +
    +

    The SSL transport is a thin wrapper around ssl.

    +

    Ranch depends on ssl by default so any necessary +dependencies will start when Ranch is started. It is +possible to remove the dependency when the SSL transport +will not be used. Refer to your release build tool’s +documentation for more information.

    +

    When embedding Ranch listeners that have an SSL transport, +your application must depend on the ssl application for +proper behavior.

    +
    +
    +
    +

    Sending and receiving data

    +
    +

    This section assumes that Transport is a valid transport handler +(like ranch_tcp or ranch_ssl) and Socket is a connected +socket obtained through the listener.

    +

    You can send data to a socket by calling the Transport:send/2 +function. The data can be given as iodata(), which is defined as +binary() | iolist(). All the following calls will work:

    +
    +
    Sending data to the socket
    +
    +
    Transport:send(Socket, <<"Ranch is cool!">>).
    +Transport:send(Socket, "Ranch is cool!").
    +Transport:send(Socket, ["Ranch", ["is", "cool!"]]).
    +Transport:send(Socket, ["Ranch", [<<"is">>, "cool!"]]).
    +

    You can receive data either in passive or in active mode. Passive mode +means that you will perform a blocking Transport:recv/3 call, while +active mode means that you will receive the data as a message.

    +

    By default, all data will be received as binary. It is possible to +receive data as strings, although this is not recommended as binaries +are a more efficient construct, especially for binary protocols.

    +

    Receiving data using passive mode requires a single function call. The +first argument is the socket, and the third argument is a timeout duration +before the call returns with {error, timeout}.

    +

    The second argument is the amount of data in bytes that we want to receive. +The function will wait for data until it has received exactly this amount. +If you are not expecting a precise size, you can specify 0 which will make +this call return as soon as data was read, regardless of its size.

    +
    +
    Receiving data from the socket in passive mode
    +
    +
    {ok, Data} = Transport:recv(Socket, 0, 5000).
    +

    Active mode requires you to inform the socket that you want to receive +data as a message and to write the code to actually receive it.

    +

    There are two kinds of active modes: {active, once} and +{active, true}. The first will send a single message before going +back to passive mode; the second will send messages indefinitely. +We recommend not using the {active, true} mode as it could quickly +flood your process mailbox. It’s better to keep the data in the socket +and read it only when required.

    +

    Three different messages can be received:

    +
      +
    • +

      +{OK, Socket, Data} +

      +
    • +
    • +

      +{Closed, Socket} +

      +
    • +
    • +

      +{Error, Socket, Reason} +

      +
    • +
    +

    The value of OK, Closed and Error can be different +depending on the transport being used. To be able to properly match +on them you must first call the Transport:messages/0 function.

    +
    +
    Retrieving the transport’s active message identifiers
    +
    +
    {OK, Closed, Error} = Transport:messages().
    +

    To start receiving messages you will need to call the Transport:setopts/2 +function, and do so every time you want to receive data.

    +
    +
    Receiving messages from the socket in active mode
    +
    +
    {OK, Closed, Error} = Transport:messages(),
    +Transport:setopts(Socket, [{active, once}]),
    +receive
    +        {OK, Socket, Data} ->
    +                io:format("data received: ~p~n", [Data]);
    +        {Closed, Socket} ->
    +                io:format("socket got closed!~n");
    +        {Error, Socket, Reason} ->
    +                io:format("error happened: ~p~n", [Reason])
    +end.
    +

    You can easily integrate active sockets with existing Erlang code as all +you really need is just a few more clauses when receiving messages.

    +
    +
    +
    +

    Sending files

    +
    +

    As in the previous section it is assumed Transport is a valid transport +handler and Socket is a connected socket obtained through the listener.

    +

    To send a whole file, with name Filename, over a socket:

    +
    +
    Sending a file by filename
    +
    +
    {ok, SentBytes} = Transport:sendfile(Socket, Filename).
    +

    Or part of a file, with Offset greater than or equal to 0, Bytes number of +bytes and chunks of size ChunkSize:

    +
    +
    Sending part of a file by filename in chunks
    +
    +
    Opts = [{chunk_size, ChunkSize}],
    +{ok, SentBytes} = Transport:sendfile(Socket, Filename, Offset, Bytes, Opts).
    +

    To improve efficiency when sending multiple parts of the same file it is also +possible to use a file descriptor opened in raw mode:

    +
    +
    Sending a file opened in raw mode
    +
    +
    {ok, RawFile} = file:open(Filename, [raw, read, binary]),
    +{ok, SentBytes} = Transport:sendfile(Socket, RawFile, Offset, Bytes, Opts).
    +
    +
    +
    +

    Writing a transport handler

    +
    +

    A transport handler is a module implementing the ranch_transport behavior. +It defines a certain number of callbacks that must be written in order to +allow transparent usage of the transport handler.

    +

    The behavior doesn’t define the socket options available when opening a +socket. These do not need to be common to all transports as it’s easy enough +to write different initialization functions for the different transports that +will be used. With one exception though. The setopts/2 function must +implement the {active, once} and the {active, true} options.

    +

    If the transport handler doesn’t have a native implementation of sendfile/5 a +fallback is available, ranch_transport:sendfile/6. The extra first argument +is the transport’s module. See ranch_ssl for an example.

    +
    +
    + + + + + + + + + + + + +
    + +
    + + +

    + Ranch + 1.3 + + User Guide +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/index.html b/docs/en/ranch/1.3/manual/index.html new file mode 100644 index 00000000..df038c0e --- /dev/null +++ b/docs/en/ranch/1.3/manual/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + + + Nine Nines: Ranch Function Reference + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Ranch Function Reference

    + +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch/index.html b/docs/en/ranch/1.3/manual/ranch/index.html new file mode 100644 index 00000000..ef89eff1 --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch/index.html @@ -0,0 +1,696 @@ + + + + + + + + + + + + Nine Nines: ranch(3) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch(3)

    + +
    +

    Name

    +
    +

    ranch - socket acceptor pool

    +
    +
    +
    +

    Description

    +
    +

    The ranch module provides functions for starting and +manipulating Ranch listeners.

    +
    +
    +
    +

    Types

    +
    +
    +

    max_conns() = non_neg_integer() | infinity

    +

    Maximum number of connections allowed on this listener.

    +

    This is a soft limit. The actual number of connections +might be slightly above the limit due to concurrency +when accepting new connections. Some connections may +also be removed from this count explicitly by the user +code.

    +
    +
    +

    opt()

    +
    +
    +
    opt() = {ack_timeout, timeout()}
    +        | {connection_type, worker | supervisor}
    +        | {max_connections, max_conns()}
    +        | {shutdown, timeout() | brutal_kill}
    +        | {socket, any()}
    +

    Ranch-specific transport options.

    +

    These options are not passed on to the transports. +They are used by Ranch while setting up the listeners.

    +
    +
    +

    ref() = any()

    +

    Unique name used to refer to a listener.

    +
    +
    +
    +
    +

    Option descriptions

    +
    +

    None of the options are required.

    +
    +
    +ack_timeout (5000) +
    +
    +

    + Maximum allowed time for the ranch:accept_ack/1 call to finish. +

    +
    +
    +connection_type (worker) +
    +
    +

    + Type of process that will handle the connection. +

    +
    +
    +max_connections (1024) +
    +
    +

    + Maximum number of active connections. Soft limit. Using infinity will disable the limit entirely. +

    +
    +
    +shutdown (5000) +
    +
    +

    + Maximum allowed time for children to stop on listener shutdown. +

    +
    +
    +socket +
    +
    +

    + Listening socket opened externally to be used instead of calling Transport:listen/1. +

    +
    +
    +
    +
    +
    +

    Exports

    +
    +
    +

    accept_ack(Ref) → ok

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +

    Acknowledge that the connection is accepted.

    +

    This function MUST be used by a connection process to inform +Ranch that it initialized properly and let it perform any +additional operations before the socket can be safely used.

    +
    +
    +

    child_spec(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → supervisor:child_spec()

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +NumAcceptors = non_neg_integer() +
    +
    +

    +Number of acceptor processes. +

    +
    +
    +Transport = module() +
    +
    +

    +Transport module. +

    +
    +
    +TransOpts = any() +
    +
    +

    +Transport options. +

    +
    +
    +Protocol = module() +
    +
    +

    +Protocol module. +

    +
    +
    +ProtoOpts = any() +
    +
    +

    +Protocol options. +

    +
    +
    +

    Return child specifications for a new listener.

    +

    This function can be used to embed a listener directly +in an application instead of letting Ranch handle it.

    +
    +
    +

    get_addr(Ref) → {IP, Port}

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +IP = inet:ip_address() +
    +
    +

    +IP of the interface used by this listener. +

    +
    +
    +Port = inet:port_number() +
    +
    +

    +Port number used by this listener. +

    +
    +
    +

    Return the IP address and port for the given listener.

    +
    +
    +

    get_max_connections(Ref) → MaxConns

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +MaxConns = max_conns() +
    +
    +

    +Current maximum number of connections. +

    +
    +
    +

    Return the max number of connections allowed for the given listener.

    +
    +
    +

    get_port(Ref) → Port

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +Port = inet:port_number() +
    +
    +

    +Port number used by this listener. +

    +
    +
    +

    Return the port for the given listener.

    +
    +
    +

    get_protocol_options(Ref) → ProtoOpts

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +ProtoOpts = any() +
    +
    +

    +Current protocol options. +

    +
    +
    +

    Return the protocol options set for the given listener.

    +
    +
    +

    info() → [{Ref, [{Key, Value}]}]

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +Key = atom() +
    +
    +

    +Information key. +

    +
    +
    +Value = any() +
    +
    +

    +Information value. +

    +
    +
    +

    Return detailed information about all Ranch listeners.

    +

    The following keys are defined:

    +
    +
    +pid +
    +
    +

    +Pid of the listener’s top-level supervisor. +

    +
    +
    +ip +
    +
    +

    +Interface Ranch listens on. +

    +
    +
    +port +
    +
    +

    +Port number Ranch listens on. +

    +
    +
    +num_acceptors +
    +
    +

    +Number of acceptor processes. +

    +
    +
    +max_connections +
    +
    +

    +Maximum number of connections. +

    +
    +
    +active_connections +
    +
    +

    +Number of active connections. +

    +
    +
    +all_connections +
    +
    +

    +Number of connections, including those removed from the count. +

    +
    +
    +transport +
    +
    +

    +Transport module. +

    +
    +
    +transport_options +
    +
    +

    +Transport options. +

    +
    +
    +protocol +
    +
    +

    +Protocol module. +

    +
    +
    +protocol_options +
    +
    +

    +Protocol options. +

    +
    +
    +
    +
    +

    procs(Ref, acceptors | connections) → [pid()]

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +

    Return all acceptor or connection processes for one listener.

    +
    +
    +

    remove_connection(Ref) → ok

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +

    Do not count this connection when limiting the number of connections.

    +

    You can use this function for long-running connection processes +which spend most of their time idling rather than consuming +resources. This allows Ranch to accept a lot more connections +without sacrificing the latency of the system.

    +

    This function may only be called from a connection process.

    +
    +
    +

    set_max_connections(Ref, MaxConns) → ok

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +MaxConns = max_conns() +
    +
    +

    +New maximum number of connections. +

    +
    +
    +

    Set the max number of connections for the given listener.

    +

    The change will be applied immediately. If the new value is +smaller than the previous one, Ranch will not kill the extra +connections, but will wait for them to terminate properly.

    +
    +
    +

    set_protocol_options(Ref, ProtoOpts) → ok

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +ProtoOpts = any() +
    +
    +

    +New protocol options. +

    +
    +
    +

    Set the protocol options for the given listener.

    +

    The change will be applied immediately for all new connections. +Old connections will not receive the new options.

    +
    +
    +

    start_listener(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) → {ok, pid()} | {error, badarg}

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +NumAcceptors = non_neg_integer() +
    +
    +

    +Number of acceptor processes. +

    +
    +
    +Transport = module() +
    +
    +

    +Transport module. +

    +
    +
    +TransOpts = any() +
    +
    +

    +Transport options. +

    +
    +
    +Protocol = module() +
    +
    +

    +Protocol module. +

    +
    +
    +ProtoOpts = any() +
    +
    +

    +Protocol options. +

    +
    +
    +

    Start listening for connections using the given transport +and protocol. Returns the pid for this listener’s supervisor.

    +

    There are additional transport options that apply +regardless of transport. They allow configuring how the +connections are supervised, rate limited and more. Please +consult the previous section for more details.

    +
    +
    +

    stop_listener(Ref) → ok | {error, not_found}

    +
    +
    +Ref = ref() +
    +
    +

    +Listener name. +

    +
    +
    +

    Stop the given listener.

    +

    The listener is stopped gracefully, first by closing the +listening port, then by stopping the connection processes. +These processes are stopped according to the shutdown +transport option, which may be set to brutally kill all +connection processes or give them some time to stop properly.

    +

    This function does not return until the listener is +completely stopped.

    +
    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch_app/index.html b/docs/en/ranch/1.3/manual/ranch_app/index.html new file mode 100644 index 00000000..c5ce74d1 --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch_app/index.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + Nine Nines: ranch(7) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch(7)

    + +
    +

    Name

    +
    +

    ranch - Socket acceptor pool for TCP protocols.

    +
    +
    +
    +

    Dependencies

    +
    +

    The ranch application depends on the ssl application to +start. It is used for handling secure connections, when the +transport is ranch_ssl. It can be disabled if SSL is not +used.

    +
    +
    +
    +

    Environment

    +
    +

    The ranch application defines one application environment +configuration parameter.

    +
    +
    +profile (false) +
    +
    +

    + When enabled, Ranch will start eprof profiling automatically. +

    +
    +
    +

    You can use the ranch_app:profile_output/0 function to stop +profiling and output the results to the files procs.profile +and total.profile. Do not use in production.

    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch_protocol/index.html b/docs/en/ranch/1.3/manual/ranch_protocol/index.html new file mode 100644 index 00000000..05c77ee1 --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch_protocol/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + + + Nine Nines: ranch_protocol(3) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch_protocol(3)

    + +
    +

    Name

    +
    +

    ranch_protocol - behaviour for protocol modules

    +
    +
    +
    +

    Description

    +
    +

    The ranch_protocol behaviour defines the interface used +by Ranch protocols.

    +
    +
    +
    +

    Types

    +
    +

    None.

    +
    +
    +
    +

    Callbacks

    +
    +
    + +
    +
    +Ref = ranch:ref() +
    +
    +

    +Listener name. +

    +
    +
    +Socket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +Transport = module() +
    +
    +

    +Transport module for this socket. +

    +
    +
    +ProtoOpts = any() +
    +
    +

    +Protocol options. +

    +
    +
    +

    Start a new connection process for the given socket.

    +

    The only purpose of this callback is to start a process that +will handle the socket. It must spawn the process, link and +then return the new pid. This function will always be called +from inside a supervisor.

    +

    This callback can also return two pids. The first pid is the +pid of the process that will be supervised. The second pid is +the pid of the process that will receive ownership of the +socket. This second process must be a child of the first. This +form is only available when connection_type is set to +supervisor.

    +

    If any other value is returned, the supervisor will close the +socket and assume no process has been started.

    +

    Do not perform any operations in this callback, as this would +block the supervisor responsible for starting connection +processes and degrade performance severely.

    +
    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch_ssl/index.html b/docs/en/ranch/1.3/manual/ranch_ssl/index.html new file mode 100644 index 00000000..c54a9dbe --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch_ssl/index.html @@ -0,0 +1,523 @@ + + + + + + + + + + + + Nine Nines: ranch_ssl(3) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch_ssl(3)

    + +
    +

    Name

    +
    +

    ranch_ssl - SSL transport module

    +
    +
    +
    +

    Description

    +
    +

    The ranch_ssl module implements an SSL Ranch transport.

    +
    +
    +
    +

    Types

    +
    +
    +

    ssl_opt()

    +
    +
    +
    ssl_opt() = {alpn_preferred_protocols, [binary()]}
    +        | {beast_mitigation, one_n_minus_one | zero_n | disabled}
    +        | {cacertfile, string()}
    +        | {cacerts, [public_key:der_encoded()]}
    +        | {cert, public_key:der_encoded()}
    +        | {certfile, string()}
    +        | {ciphers, [ssl:erl_cipher_suite()] | string()}
    +        | {client_renegotiation, boolean()}
    +        | {crl_cache, {module(), {internal | any(), list()}}}
    +        | {crl_check, boolean() | peer | best_effort}
    +        | {depth, 0..255}
    +        | {dh, public_key:der_encoded()}
    +        | {dhfile, string()}
    +        | {fail_if_no_peer_cert, boolean()}
    +        | {hibernate_after, integer() | undefined}
    +        | {honor_cipher_order, boolean()}
    +        | {key, {'RSAPrivateKey' | 'DSAPrivateKey' | 'PrivateKeyInfo', public_key:der_encoded()}}
    +        | {keyfile, string()}
    +        | {log_alert, boolean()}
    +        | {next_protocols_advertised, [binary()]}
    +        | {padding_check, boolean()}
    +        | {partial_chain, fun(([public_key:der_encoded()]) -> {trusted_ca, public_key:der_encoded()} | unknown_ca)}
    +        | {password, string()}
    +        | {psk_identity, string()}
    +        | {reuse_session, fun()}
    +        | {reuse_sessions, boolean()}
    +        | {secure_renegotiate, boolean()}
    +        | {signature_algs, [{atom(), atom()}]}
    +        | {sni_fun, fun()}
    +        | {sni_hosts, [{string(), ssl_opt()}]}
    +        | {user_lookup_fun, {fun(), any()}}
    +        | {v2_hello_compatible, boolean()}
    +        | {verify, ssl:verify_type()}
    +        | {verify_fun, {fun(), any()}}
    +        | {versions, [atom()]}.
    +

    SSL-specific listen options.

    +
    +
    +

    opt() = ranch_tcp:opt() | ssl_opt()

    +

    Listen options.

    +
    +
    +

    opts() = [opt()]

    +

    List of listen options.

    +
    +
    +
    +
    +

    Option descriptions

    +
    +

    Specifying a certificate is mandatory, either through the cert +or the certfile option. None of the other options are required.

    +

    The default value is given next to the option name.

    +
    +
    +alpn_preferred_protocols +
    +
    +

    + Perform Application-Layer Protocol Negotiation with the given list of preferred protocols. +

    +
    +
    +beast_mitigation +
    +
    +

    + Change the BEAST mitigation strategy for SSL-3.0 and TLS-1.0 to interoperate with legacy software. +

    +
    +
    +cacertfile +
    +
    +

    + Path to PEM encoded trusted certificates file used to verify peer certificates. +

    +
    +
    +cacerts +
    +
    +

    + List of DER encoded trusted certificates. +

    +
    +
    +cert +
    +
    +

    + DER encoded user certificate. +

    +
    +
    +certfile +
    +
    +

    + Path to the PEM encoded user certificate file. May also contain the private key. +

    +
    +
    +ciphers +
    +
    +

    + List of ciphers that clients are allowed to use. +

    +
    +
    +client_renegotiation (true) +
    +
    +

    + Whether to allow client-initiated renegotiation. +

    +
    +
    +crl_cache ({ssl_crl_cache, {internal, []}}) +
    +
    +

    + Customize the module used to cache Certificate Revocation Lists. +

    +
    +
    +crl_check (false) +
    +
    +

    + Whether to perform CRL check on all certificates in the chain during validation. +

    +
    +
    +depth (1) +
    +
    +

    + Maximum of intermediate certificates allowed in the certification path. +

    +
    +
    +dh +
    +
    +

    + DER encoded Diffie-Hellman parameters. +

    +
    +
    +dhfile +
    +
    +

    + Path to the PEM encoded Diffie-Hellman parameters file. +

    +
    +
    +fail_if_no_peer_cert (false) +
    +
    +

    + Whether to refuse the connection if the client sends an empty certificate. +

    +
    +
    +hibernate_after (undefined) +
    +
    +

    + Time in ms after which SSL socket processes go into hibernation to reduce memory usage. +

    +
    +
    +honor_cipher_order (false) +
    +
    +

    + If true, use the server’s preference for cipher selection. If false, use the client’s preference. +

    +
    +
    +key +
    +
    +

    + DER encoded user private key. +

    +
    +
    +keyfile +
    +
    +

    + Path to the PEM encoded private key file, if different than the certfile. +

    +
    +
    +log_alert (true) +
    +
    +

    + If false, error reports will not be displayed. +

    +
    +
    +next_protocols_advertised +
    +
    +

    + List of protocols to send to the client if it supports the Next Protocol extension. +

    +
    +
    +nodelay (true) +
    +
    +

    + Whether to enable TCP_NODELAY. +

    +
    +
    +padding_check +
    +
    +

    + Allow disabling the block cipher padding check for TLS-1.0 to be able to interoperate with legacy software. +

    +
    +
    +partial_chain +
    +
    +

    + Claim an intermediate CA in the chain as trusted. +

    +
    +
    +password +
    +
    +

    + Password to the private key file, if password protected. +

    +
    +
    +psk_identity +
    +
    +

    + Provide the given PSK identity hint to the client during the handshake. +

    +
    +
    +reuse_session +
    +
    +

    + Custom policy to decide whether a session should be reused. +

    +
    +
    +reuse_sessions (false) +
    +
    +

    + Whether to allow session reuse. +

    +
    +
    +secure_renegotiate (false) +
    +
    +

    + Whether to reject renegotiation attempts that do not conform to RFC5746. +

    +
    +
    +signature_algs +
    +
    +

    + The TLS signature algorithm extension may be used, from TLS 1.2, to negotiate which signature algorithm to use during the TLS handshake. +

    +
    +
    +sni_fun +
    +
    +

    + Function called when the client requests a host using Server Name Indication. Returns options to apply. +

    +
    +
    +sni_hosts +
    +
    +

    + Options to apply for the host that matches what the client requested with Server Name Indication. +

    +
    +
    +user_lookup_fun +
    +
    +

    + Function called to determine the shared secret when using PSK, or provide parameters when using SRP. +

    +
    +
    +v2_hello_compatible +
    +
    +

    + Accept clients that send hello messages in SSL-2.0 format while offering supported SSL/TLS versions. +

    +
    +
    +verify (verify_none) +
    +
    +

    + Use verify_peer to request a certificate from the client. +

    +
    +
    +verify_fun +
    +
    +

    + Custom policy to decide whether a client certificate is valid. +

    +
    +
    +versions +
    +
    +

    + TLS protocol versions that will be supported. +

    +
    +
    +

    Note that the client will not send a certificate unless the +value for the verify option is set to verify_peer. This +means that the fail_if_no_peer_cert only apply when combined +with the verify option. The verify_fun option allows +greater control over the client certificate validation.

    +

    The options sni_fun and sni_hosts are mutually exclusive.

    +
    +
    +
    +

    Exports

    +
    +

    None.

    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch_tcp/index.html b/docs/en/ranch/1.3/manual/ranch_tcp/index.html new file mode 100644 index 00000000..2b28bb77 --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch_tcp/index.html @@ -0,0 +1,421 @@ + + + + + + + + + + + + Nine Nines: ranch_tcp(3) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch_tcp(3)

    + +
    +

    Name

    +
    +

    ranch_tcp - TCP transport module

    +
    +
    +
    +

    Description

    +
    +

    The ranch_tcp module implements a TCP Ranch transport.

    +

    Note that due to bugs in OTP up to at least R16B02, it is +recommended to disable async threads when using the +sendfile function of this transport, as it can make +the threads stuck indefinitely.

    +
    +
    +
    +

    Types

    +
    +
    +

    opt()

    +
    +
    +
    opt() = {backlog, non_neg_integer()}
    +        | {buffer, non_neg_integer()}
    +        | {delay_send, boolean()}
    +        | {dontroute, boolean()}
    +        | {exit_on_close, boolean()}
    +        | {fd, non_neg_integer()}
    +        | {high_msgq_watermark, non_neg_integer()}
    +        | {high_watermark, non_neg_integer()}
    +        | inet
    +        | inet6
    +        | {ip, inet:ip_address()}
    +        | {ipv6_v6only, boolean()}
    +        | {keepalive, boolean()}
    +        | {linger, {boolean(), non_neg_integer()}}
    +        | {low_msgq_watermark, non_neg_integer()}
    +        | {low_watermark, non_neg_integer()}
    +        | {nodelay, boolean()}
    +        | {port, inet:port_number()}
    +        | {priority, integer()}
    +        | {raw, non_neg_integer(), non_neg_integer(), binary()}
    +        | {recbuf, non_neg_integer()}
    +        | {send_timeout, timeout()}
    +        | {send_timeout_close, boolean()}
    +        | {sndbuf, non_neg_integer()}
    +        | {tos, integer()}
    +

    Listen options.

    +

    This does not represent the entirety of the options that can +be set on the socket, but only the options that may be +set independently of protocol implementation.

    +
    +
    +

    opts() = [opt()]

    +

    List of listen options.

    +
    +
    +
    +
    +

    Option descriptions

    +
    +

    None of the options are required.

    +

    Please consult the gen_tcp and inet manuals for a more +thorough description of these options. This manual only aims +to provide a short description along with what the defaults +are. Defaults may be different in Ranch compared to gen_tcp. +Defaults are given next to the option name.

    +
    +
    +backlog (1024) +
    +
    +

    + Max length of the queue of pending connections. +

    +
    +
    +buffer +
    +
    +

    + Size of the buffer used by the Erlang driver. Default is system-dependent. +

    +
    +
    +delay_send (false) +
    +
    +

    + Always queue packets before sending, to send fewer, larger packets over the network. +

    +
    +
    +dontroute (false) +
    +
    +

    + Don’t send via a gateway, only send to directly connected hosts. +

    +
    +
    +exit_on_close (true) +
    +
    +

    + Disable to allow sending data after a close has been detected. +

    +
    +
    +fd +
    +
    +

    + File descriptor of the socket, if it was opened externally. +

    +
    +
    +high_msgq_watermark (8192) +
    +
    +

    + Limit in the amount of data in the socket message queue before the socket queue becomes busy. +

    +
    +
    +high_watermark (8192) +
    +
    +

    + Limit in the amount of data in the ERTS socket implementation’s queue before the socket becomes busy. +

    +
    +
    +inet +
    +
    +

    + Set up the socket for IPv4. +

    +
    +
    +inet6 +
    +
    +

    + Set up the socket for IPv6. +

    +
    +
    +ip +
    +
    +

    + Interface to listen on. Listen on all interfaces by default. +

    +
    +
    +ipv6_v6only (false) +
    +
    +

    + Listen on IPv4 and IPv6 (false) or only on IPv6 (true). Use with inet6. +

    +
    +
    +keepalive (false) +
    +
    +

    + Enable sending of keep-alive messages. +

    +
    +
    +linger ({false, 0}) +
    +
    +

    + Whether to wait and how long to flush data sent before closing the socket. +

    +
    +
    +low_msgq_watermark (4096) +
    +
    +

    + Amount of data in the socket message queue before the socket queue leaves busy state. +

    +
    +
    +low_watermark (4096) +
    +
    +

    + Amount of data in the ERTS socket implementation’s queue before the socket leaves busy state. +

    +
    +
    +nodelay (true) +
    +
    +

    + Whether to enable TCP_NODELAY. +

    +
    +
    +port (0) +
    +
    +

    + TCP port number to listen on. 0 means a random port will be used. +

    +
    +
    +priority (0) +
    +
    +

    + Priority value for all packets to be sent by this socket. +

    +
    +
    +recbuf +
    +
    +

    + Minimum size of the socket’s receive buffer. Default is system-dependent. +

    +
    +
    +send_timeout (30000) +
    +
    +

    + How long the send call may wait for confirmation before returning. +

    +
    +
    +send_timeout_close (true) +
    +
    +

    + Whether to close the socket when the confirmation wasn’t received. +

    +
    +
    +sndbuf +
    +
    +

    + Minimum size of the socket’s send buffer. Default is system-dependent. +

    +
    +
    +tos +
    +
    +

    + Value for the IP_TOS IP level option. Use with caution. +

    +
    +
    +

    In addition, the raw option can be used to set system-specific +options by specifying the protocol level, the option number and +the actual option value specified as a binary. This option is not +portable. Use with caution.

    +
    +
    +
    +

    Exports

    +
    +

    None.

    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/1.3/manual/ranch_transport/index.html b/docs/en/ranch/1.3/manual/ranch_transport/index.html new file mode 100644 index 00000000..299a82a5 --- /dev/null +++ b/docs/en/ranch/1.3/manual/ranch_transport/index.html @@ -0,0 +1,632 @@ + + + + + + + + + + + + Nine Nines: ranch_transport(3) + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    ranch_transport(3)

    + +
    +

    Name

    +
    +

    ranch_transport - behaviour for transport modules

    +
    +
    +
    +

    Description

    +
    +

    The ranch_transport behaviour defines the interface used +by Ranch transports.

    +
    +
    +
    +

    Types

    +
    +
    +

    sendfile_opts() = [{chunk_size, non_neg_integer()}]

    +

    Options used by the sendfile function and callbacks.

    +

    Allows configuring the chunk size, in bytes. Defaults to 8191 bytes.

    +
    +
    +
    +
    +

    Callbacks

    +
    +
    +

    accept(LSocket, Timeout) → {ok, CSocket} | {error, closed | timeout | atom()}

    +
    +
    +LSocket = CSocket = any() +
    +
    +

    +Listening socket. +

    +
    +
    +Timeout = timeout() +
    +
    +

    +Accept timeout. +

    +
    +
    +

    Accept a connection on the given listening socket.

    +

    The accept_ack callback will be used to initialize the socket +after accepting the connection. This is most useful when the +transport is not raw TCP, like with SSL for example.

    +
    +
    +

    accept_ack(CSocket, Timeout) → ok

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +Timeout = timeout() +
    +
    +

    +Ack timeout. +

    +
    +
    +

    Perform post-accept initialization of the connection.

    +

    This function will be called by connection processes +before performing any socket operation. It allows +transports that require extra initialization to perform +their task and make the socket ready to use.

    +
    +
    +

    close(Socket) → ok

    +
    +
    +Socket = any() +
    +
    +

    +Socket opened with listen/1 or accept/2. +

    +
    +
    +

    Close the given socket.

    +
    +
    +

    controlling_process(Socket, Pid) → ok | {error, closed | not_owner | atom()}

    +
    +
    +Socket = any() +
    +
    +

    +Socket opened with listen/1 or accept/2. +

    +
    +
    +Pid = pid() +
    +
    +

    +Pid of the new owner of the socket. +

    +
    +
    +

    Change the controlling process for the given socket.

    +

    The controlling process is the process that is allowed to +perform operations on the socket, and that will receive +messages from the socket when active mode is used. When +the controlling process dies, the socket is closed.

    +
    +
    +

    listen(TransOpts) → {ok, LSocket} | {error, atom()}

    +
    +
    +TransOpts = any() +
    +
    +

    +Transport options. +

    +
    +
    +LSocket = any() +
    +
    +

    +Listening socket. +

    +
    +
    +

    Listen for connections on the given port.

    +

    The port is given as part of the transport options under +the key port. Any other option is transport dependent.

    +

    The socket returned by this call can then be used to +accept connections. It is not possible to send or receive +data from the listening socket.

    +
    +
    +

    messages() → {OK, Closed, Error}

    +
    +
    +OK = Closed = Error = atom() +
    +
    +

    +Tuple names. +

    +
    +
    +

    Return the atoms used to identify messages sent in active mode.

    +
    +
    +

    name() → Name

    +
    +
    +Name = atom() +
    +
    +

    +Transport module name. +

    +
    +
    +

    Return the name of the transport.

    +
    +
    +

    peername(CSocket) → {ok, {IP, Port}} | {error, atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +IP = inet:ip_address() +
    +
    +

    +IP of the remote endpoint. +

    +
    +
    +Port = inet:port_number() +
    +
    +

    +Port of the remote endpoint. +

    +
    +
    +

    Return the IP and port of the remote endpoint.

    +
    +
    +

    recv(CSocket, Length, Timeout) → {ok, Packet} | {error, closed | timeout | atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +Length = non_neg_integer() +
    +
    +

    +Requested length. +

    +
    +
    +Timeout = timeout() +
    +
    +

    +Receive timeout. +

    +
    +
    +Packet = iodata() | any() +
    +
    +

    +Data received. +

    +
    +
    +

    Receive data from the given socket when in passive mode.

    +

    Trying to receive data from a socket that is in active mode +will return an error.

    +

    A length of 0 will return any data available on the socket.

    +

    While it is possible to use the timeout value infinity, +this is highly discouraged as this could cause your process +to get stuck waiting for data that will never come. This may +happen when a socket becomes half-open due to a crash of the +remote endpoint. Wi-Fi going down is another common culprit +of this issue.

    +
    +
    +

    send(CSocket, Packet) → ok | {error, atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +Packet = iodata() +
    +
    +

    +Data to be sent. +

    +
    +
    +

    Send data to the given socket.

    +
    +
    +

    sendfile(CSocket, File) → sendfile(CSocket, File, 0, 0, [])

    +

    Alias of ranch_transport:sendfile/5.

    +
    +
    +

    sendfile(CSocket, File, Offset, Bytes) → sendfile(CSocket, File, Offset, Bytes, [])

    +

    Alias of ranch_transport:sendfile/5.

    +
    +
    +

    sendfile(CSocket, File, Offset, Bytes, SfOpts) → {ok, SentBytes} | {error, atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +File = file:filename_all() | file:fd() +
    +
    +

    +Filename or file descriptor for the file to be sent. +

    +
    +
    +Offset = non_neg_integer() +
    +
    +

    +Begin sending at this position in the file. +

    +
    +
    +Bytes = non_neg_integer() +
    +
    +

    +Send this many bytes. +

    +
    +
    +SentBytes = non_neg_integer() +
    +
    +

    +This many bytes were sent. +

    +
    +
    +SfOpts = sendfile_opts() +
    +
    +

    +Sendfile options. +

    +
    +
    +

    Send data from a file to the given socket.

    +

    The file may be sent full or in parts, and may be specified +by its filename or by an already open file descriptor.

    +

    Transports that manipulate TCP directly may use the +file:sendfile/{2,4,5} function, which calls the sendfile +syscall where applicable (on Linux, for example). Other +transports can use the sendfile/6 function exported from +this module.

    +
    +
    +

    setopts(CSocket, SockOpts) → ok | {error, atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +SockOpts = any() +
    +
    +

    +Socket options. +

    +
    +
    +

    Change options for the given socket.

    +

    This is mainly useful for switching to active or passive mode +or to set protocol-specific options.

    +
    +
    +

    shutdown(CSocket, How) → ok | {error, atom()}

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +How = read | write | read_write +
    +
    +

    +Which side(s) of the socket to close. +

    +
    +
    +

    Immediately close the socket in one or two directions.

    +
    +
    +

    sockname(Socket) → {ok, {IP, Port}} | {error, atom()}

    +
    +
    +Socket = any() +
    +
    +

    +Socket opened with listen/1 or accept/2. +

    +
    +
    +IP = inet:ip_address() +
    +
    +

    +IP of the local endpoint. +

    +
    +
    +Port = inet:port_number() +
    +
    +

    +Port of the local endpoint. +

    +
    +
    +

    Return the IP and port of the local endpoint.

    +
    +
    +
    +
    +

    Exports

    +
    +
    +

    sendfile(Transport, CSocket, File, Offset, Bytes, SfOpts) → {ok, SentBytes} | {error, atom()}

    +
    +
    +Transport = module() +
    +
    +

    +Transport module for this socket. +

    +
    +
    +CSocket = any() +
    +
    +

    +Socket for this connection. +

    +
    +
    +File = file:filename_all() | file:fd() +
    +
    +

    +Filename or file descriptor for the file to be sent. +

    +
    +
    +Offset = non_neg_integer() +
    +
    +

    +Begin sending at this position in the file. +

    +
    +
    +Bytes = non_neg_integer() +
    +
    +

    +Send this many bytes. +

    +
    +
    +SentBytes = non_neg_integer() +
    +
    +

    +This many bytes were sent. +

    +
    +
    +SfOpts = sendfile_opts() +
    +
    +

    +Sendfile options. +

    +
    +
    +

    Send data from a file to the given socket.

    +

    This function emulates the function file:sendfile/{2,4,5} +and may be used when transports are not manipulating TCP +directly.

    +
    +
    +
    + + + + + +
    + +
    + + +

    + Ranch + 1.3 + Function Reference + +

    + + + +

    Navigation

    + +

    Version select

    + + +
    +
    +
    +
    + + + + + + + + + + + + diff --git a/docs/en/ranch/index.html b/docs/en/ranch/index.html index ea24e654..d87c4243 100644 --- a/docs/en/ranch/index.html +++ b/docs/en/ranch/index.html @@ -1 +1 @@ - \ No newline at end of file +https://ninenines.eu/docs/ \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index e3f50323..849efa1c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,7 +7,7 @@ - + Nine Nines: Documentation @@ -125,6 +125,13 @@