mirror of
https://github.com/aantron/dream.git
synced 2025-06-25 00:03:31 -04:00
Compare commits
No commits in common. "master" and "1.0.0-alpha7" have entirely different histories.
master
...
1.0.0-alph
127
.github/workflows/test.yml
vendored
127
.github/workflows/test.yml
vendored
@ -7,98 +7,101 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
# Until https://github.com/ocaml/setup-ocaml/issues/872.
|
- ubuntu-latest
|
||||||
# When fixing, search for other instances of this string in this file.
|
|
||||||
- ubuntu-22.04
|
|
||||||
ocaml:
|
ocaml:
|
||||||
- 5.2.x
|
- 5.0.x
|
||||||
- 4.14.x
|
- 4.14.x
|
||||||
|
- 4.13.x
|
||||||
|
- 4.12.x
|
||||||
|
- 4.11.x
|
||||||
|
- 4.10.x
|
||||||
|
- 4.09.x
|
||||||
|
- 4.08.x
|
||||||
include:
|
include:
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
ocaml: 4.14.x
|
ocaml: 4.12.x
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
ocaml: 4.14.x
|
ocaml: 4.14.x
|
||||||
|
|
||||||
runs-on: ${{matrix.os}}
|
runs-on: ${{matrix.os}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- uses: ocaml/setup-ocaml@v3
|
- uses: avsm/setup-ocaml@v2
|
||||||
|
if: runner.os != 'Windows'
|
||||||
with:
|
with:
|
||||||
ocaml-compiler: ${{matrix.ocaml}}
|
ocaml-compiler: ${{matrix.ocaml}}
|
||||||
dune-cache: true
|
|
||||||
|
|
||||||
# For Caqti PostgreSQL examples. opam does actually install PostgreSQL for
|
- uses: avsm/setup-ocaml@v2
|
||||||
# us. However, Homebrew doesn't link it by default, so we have to install
|
|
||||||
# and link it manually.
|
|
||||||
- run: brew install postgresql@15 && brew link --overwrite postgresql@15
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
|
|
||||||
# Workaround https://github.com/savonet/ocaml-ssl/issues/155 and/or
|
|
||||||
# https://github.com/ocaml/setup-ocaml/issues/856.
|
|
||||||
- run: opam pin add ssl 0.6.0 --no-action
|
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
|
with:
|
||||||
|
ocaml-compiler: ${{matrix.ocaml}}
|
||||||
|
opam-repositories: |
|
||||||
|
opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
|
||||||
|
default: https://github.com/ocaml/opam-repository.git
|
||||||
|
|
||||||
- run: opam exec -- make deps
|
- run: opam depext --yes conf-sqlite3
|
||||||
|
- run: opam depext --yes conf-postgresql
|
||||||
- run: opam exec -- make
|
- run: opam depext --yes conf-libev
|
||||||
|
|
||||||
# Tests on Windows are disabled because of a difference in ppx_expect
|
|
||||||
# output. See https://github.com/aantron/dream/pull/282. This difference
|
|
||||||
# remains as of ppx_expect 0.16.
|
|
||||||
- run: opam exec -- make test
|
|
||||||
if: runner.os != 'Windows'
|
if: runner.os != 'Windows'
|
||||||
|
|
||||||
- run: opam lint --recursive example
|
# The tests require ppx_expect. The latest versions of it introduced changes
|
||||||
|
# in the formatting of the output, and also require OCaml >= 4.10, which
|
||||||
- name: Build examples
|
# makes testing on < 4.10 awkward. So, we skip tests on < 4.10.
|
||||||
if: runner.os != 'Windows'
|
- shell: bash
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
set -x
|
set -x
|
||||||
EXCLUDED_EXAMPLES='w-mirage*|r-tyxml|w-dream-html'
|
|
||||||
EXAMPLES=$(find example -maxdepth 1 -type d | grep -Ev $EXCLUDED_EXAMPLES | grep -v "^example/0" | grep -v "^example$" | sort)
|
|
||||||
shopt -s nullglob
|
|
||||||
for EXAMPLE in $EXAMPLES
|
|
||||||
do
|
|
||||||
FILE=$(find $EXAMPLE -maxdepth 1 -type f -and -path "${EXAMPLE}/*.ml")
|
|
||||||
FILE+=$(find $EXAMPLE -maxdepth 1 -type f -and -path "${EXAMPLE}/*.re")
|
|
||||||
FILE+=$(find $EXAMPLE -maxdepth 2 -type f -and -path "${EXAMPLE}/server/*.ml")
|
|
||||||
FILE+=$(find $EXAMPLE -maxdepth 2 -type f -and -path "${EXAMPLE}/server/*.re")
|
|
||||||
|
|
||||||
if [[ "$FILE" == "" ]]; then
|
WITH_TEST=--with-test
|
||||||
continue
|
case ${{matrix.ocaml}} in
|
||||||
|
4.09.x) WITH_TEST=;;
|
||||||
|
4.08.x) WITH_TEST=;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Tests on Windows are disabled because of a difference in ppx_expect
|
||||||
|
# output. See https://github.com/aantron/dream/pull/282.
|
||||||
|
case ${{runner.os}} in
|
||||||
|
Windows) WITH_TEST=;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
OPAM=$(which opam || true)
|
||||||
|
if [ -z "$OPAM" ]
|
||||||
|
then
|
||||||
|
OPAM=D:\\cygwin\\wrapperbin\\opam.cmd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
$OPAM install --yes --deps-only $WITH_TEST ./dream-pure.opam ./dream-httpaf.opam ./dream.opam
|
||||||
|
|
||||||
|
if [ ! -z "$WITH_TEST" ]
|
||||||
|
then
|
||||||
|
$OPAM exec -- dune runtest
|
||||||
|
|
||||||
|
EXAMPLES=$(find example -maxdepth 1 -type d -not -name "w-mirage*" -not -name "r-tyxml" | grep -v "^example/0" | grep -v "^example$" | sort)
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
for EXAMPLE in $EXAMPLES
|
||||||
|
do
|
||||||
|
FILE=$(ls $EXAMPLE/*.ml $EXAMPLE/*.re $EXAMPLE/server/*.ml $EXAMPLE/server/*.re)
|
||||||
EXE=$(echo $FILE | sed 's/\..*$/.exe/g')
|
EXE=$(echo $FILE | sed 's/\..*$/.exe/g')
|
||||||
echo dune build $EXE
|
echo dune build $EXE
|
||||||
opam exec -- dune build $EXE
|
$OPAM exec -- dune build $EXE
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
quickstart:
|
quickstart:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- ubuntu-22.04
|
- ubuntu-latest
|
||||||
ocaml:
|
- macos-latest
|
||||||
- 5.2.x
|
|
||||||
- 4.14.x
|
|
||||||
include:
|
|
||||||
- os: macos-latest
|
|
||||||
ocaml: 4.14.x
|
|
||||||
|
|
||||||
runs-on: ${{matrix.os}}
|
runs-on: ${{matrix.os}}
|
||||||
steps:
|
steps:
|
||||||
- uses: ocaml/setup-ocaml@v3
|
- name: Quick start
|
||||||
with:
|
|
||||||
ocaml-compiler: ${{matrix.ocaml}}
|
|
||||||
dune-cache: true
|
|
||||||
|
|
||||||
- name: Run quickstart.sh
|
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
touch output
|
touch output
|
||||||
@ -114,29 +117,25 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
mirage:
|
mirage:
|
||||||
if: false
|
runs-on: ubuntu-latest
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- run: mkdir ../repo-copy
|
- run: mkdir ../repo-copy
|
||||||
- run: cp -r * ../repo-copy/
|
- run: cp -r * ../repo-copy/
|
||||||
- uses: ocaml/setup-ocaml@v3
|
- uses: avsm/setup-ocaml@v2
|
||||||
with:
|
with:
|
||||||
ocaml-compiler: 4.14.x
|
ocaml-compiler: 4.14.x
|
||||||
dune-cache: true
|
|
||||||
# Needed until https://github.com/robur-coop/ocaml-letsencrypt/pull/34.
|
|
||||||
- run: opam pin add letsencrypt git+https://github.com/hannesm/ocaml-letsencrypt.git#no-cstruct --no-action
|
|
||||||
- run: opam install --yes --deps-only ./dream-pure.opam ./dream-httpaf.opam ./dream.opam ./dream-mirage.opam
|
- run: opam install --yes --deps-only ./dream-pure.opam ./dream-httpaf.opam ./dream.opam ./dream-mirage.opam
|
||||||
- run: opam install --yes mirage mirage-clock-unix mirage-crypto-rng-mirage
|
- run: opam install --yes mirage mirage-clock-unix
|
||||||
- run: cd example/w-mirage && mv config.ml config.ml.backup
|
- run: cd example/w-mirage && mv config.ml config.ml.backup
|
||||||
- run: cd example/w-mirage && sed -e 's/package "dream-mirage"//' < config.ml.backup > config.ml
|
- run: cd example/w-mirage && sed -e 's/package "dream-mirage"//' < config.ml.backup > config.ml
|
||||||
- run: cd example/w-mirage && opam exec -- mirage configure -t unix
|
- run: cd example/w-mirage && opam exec -- mirage configure -t unix
|
||||||
- run: cd example/w-mirage && opam exec -- make depends
|
- run: cd example/w-mirage && opam exec -- make depends
|
||||||
- run: cd example/w-mirage && ls duniverse
|
- run: cd example/w-mirage && ls duniverse
|
||||||
- run: cp -r ../repo-copy example/w-mirage/duniverse/dream
|
- run: cp -r ../repo-copy example/w-mirage/duniverse/dream
|
||||||
- run: cd example/w-mirage/duniverse && rm -rf ocaml-cstruct logs ke fmt lwt bytes seq mirage-flow sexplib0 ptime tls domain-name ocaml-ipaddr mirage-clock ocplib-endian digestif eqaf mirage-crypto mirage-runtime
|
- run: cd example/w-mirage/duniverse && rm -rf ocaml-cstruct logs ke fmt lwt bytes seq mirage-flow sexplib0 ptime tls domain-name ocaml-ipaddr mirage-clock ocplib-endian
|
||||||
- run: cd example/w-mirage && mv config.ml.backup config.ml
|
- run: cd example/w-mirage && mv config.ml.backup config.ml
|
||||||
- run: cd example/w-mirage && sed -e 's/(libraries/(libraries dream-mirage/' < dune.build > dune.build.2
|
- run: cd example/w-mirage && sed -e 's/(libraries/(libraries dream-mirage/' < dune.build > dune.build.2
|
||||||
- run: cd example/w-mirage && mv dune.build.2 dune.build
|
- run: cd example/w-mirage && mv dune.build.2 dune.build
|
||||||
|
16
.gitmodules
vendored
Normal file
16
.gitmodules
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[submodule "src/vendor/httpaf"]
|
||||||
|
path = src/vendor/httpaf
|
||||||
|
url = https://github.com/aantron/httpaf.git
|
||||||
|
[submodule "src/vendor/gluten"]
|
||||||
|
path = src/vendor/gluten
|
||||||
|
url = https://github.com/aantron/gluten.git
|
||||||
|
[submodule "src/vendor/websocketaf"]
|
||||||
|
path = src/vendor/websocketaf
|
||||||
|
url = https://github.com/aantron/websocketaf.git
|
||||||
|
[submodule "src/vendor/h2"]
|
||||||
|
path = src/vendor/h2
|
||||||
|
url = https://github.com/aantron/ocaml-h2.git
|
||||||
|
[submodule "src/vendor/paf"]
|
||||||
|
path = src/vendor/paf
|
||||||
|
url = https://github.com/aantron/paf-le-chien.git
|
||||||
|
branch = dream
|
4
Makefile
4
Makefile
@ -165,7 +165,3 @@ release-finish :
|
|||||||
opam pin remove -y dream-pure dream-httpaf dream
|
opam pin remove -y dream-pure dream-httpaf dream
|
||||||
sha256sum $(RELEASE).tar.gz
|
sha256sum $(RELEASE).tar.gz
|
||||||
ls -l $(RELEASE).tar.gz
|
ls -l $(RELEASE).tar.gz
|
||||||
|
|
||||||
.PHONY : release-clean
|
|
||||||
release-clean :
|
|
||||||
rm -rf $(RELEASE) $(RELEASE).tar.gz _release
|
|
||||||
|
46
README.md
46
README.md
@ -77,24 +77,24 @@ Dream binary][one-binary], or use Dream in a subcommand. Dream tries to be as
|
|||||||
functional as possible, touching global runtime state only lazily, when called
|
functional as possible, touching global runtime state only lazily, when called
|
||||||
into.
|
into.
|
||||||
|
|
||||||
[https]: https://github.com/aantron/dream/tree/master/example/l-https#folders-and-files
|
[https]: https://github.com/aantron/dream/tree/master/example/l-https#files
|
||||||
[websocket]: https://github.com/aantron/dream/tree/master/example/k-websocket#folders-and-files
|
[websocket]: https://github.com/aantron/dream/tree/master/example/k-websocket#files
|
||||||
[graphql]: https://github.com/aantron/dream/tree/master/example/w-graphql-subscription#folders-and-files
|
[graphql]: https://github.com/aantron/dream/tree/master/example/w-graphql-subscription#files
|
||||||
[templates]: https://github.com/aantron/dream/tree/master/example/7-template#folders-and-files
|
[templates]: https://github.com/aantron/dream/tree/master/example/7-template#files
|
||||||
[reason-templates]: https://github.com/aantron/dream/tree/master/example/r-template#folders-and-files
|
[reason-templates]: https://github.com/aantron/dream/tree/master/example/r-template#files
|
||||||
[middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files
|
[middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#files
|
||||||
[handler]: https://aantron.github.io/dream/#type-handler
|
[handler]: https://aantron.github.io/dream/#type-handler
|
||||||
[routing]: https://github.com/aantron/dream/tree/master/example/3-router#folders-and-files
|
[routing]: https://github.com/aantron/dream/tree/master/example/3-router#files
|
||||||
[cookies]: https://aantron.github.io/dream/#cookies
|
[cookies]: https://aantron.github.io/dream/#cookies
|
||||||
[forms]: https://aantron.github.io/dream/#forms
|
[forms]: https://aantron.github.io/dream/#forms
|
||||||
[sessions]: https://github.com/aantron/dream/tree/master/example/b-session#folders-and-files
|
[sessions]: https://github.com/aantron/dream/tree/master/example/b-session#files
|
||||||
[back-ends]: https://aantron.github.io/dream/#back-ends
|
[back-ends]: https://aantron.github.io/dream/#back-ends
|
||||||
[errors]: https://github.com/aantron/dream/tree/master/example/9-error#folders-and-files
|
[errors]: https://github.com/aantron/dream/tree/master/example/9-error#files
|
||||||
[crypto]: https://aantron.github.io/dream/#cryptography
|
[crypto]: https://aantron.github.io/dream/#cryptography
|
||||||
[logging]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files
|
[logging]: https://github.com/aantron/dream/tree/master/example/2-middleware#files
|
||||||
[melange]: https://github.com/aantron/dream/tree/master/example/r-fullstack-melange#folders-and-files
|
[melange]: https://github.com/aantron/dream/tree/master/example/r-fullstack-melange#files
|
||||||
[rescript]: https://github.com/aantron/dream/tree/master/example/w-fullstack-rescript#folders-and-files
|
[rescript]: https://github.com/aantron/dream/tree/master/example/w-fullstack-rescript#files
|
||||||
[jsoo]: https://github.com/aantron/dream/tree/master/example/w-fullstack-jsoo#folders-and-files
|
[jsoo]: https://github.com/aantron/dream/tree/master/example/w-fullstack-jsoo#files
|
||||||
[types]: https://aantron.github.io/dream/#types
|
[types]: https://aantron.github.io/dream/#types
|
||||||
[basic-read]: https://aantron.github.io/dream/#val-body
|
[basic-read]: https://aantron.github.io/dream/#val-body
|
||||||
[streaming]: https://aantron.github.io/dream/#streaming
|
[streaming]: https://aantron.github.io/dream/#streaming
|
||||||
@ -102,15 +102,15 @@ into.
|
|||||||
[alpn]: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation
|
[alpn]: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation
|
||||||
[libs]: https://github.com/aantron/dream/tree/master/src
|
[libs]: https://github.com/aantron/dream/tree/master/src
|
||||||
[deploy]: https://github.com/aantron/dream/tree/master/example#deploying
|
[deploy]: https://github.com/aantron/dream/tree/master/example#deploying
|
||||||
[jsx]: https://github.com/aantron/dream/tree/master/example/r-tyxml#folders-and-files
|
[jsx]: https://github.com/aantron/dream/tree/master/example/r-tyxml#files
|
||||||
[one-binary]: https://github.com/aantron/dream/tree/master/example/w-one-binary#folders-and-files
|
[one-binary]: https://github.com/aantron/dream/tree/master/example/w-one-binary#files
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
You can get
|
You can get
|
||||||
[one](https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files)
|
[one](https://github.com/aantron/dream/tree/master/example/2-middleware#files)
|
||||||
of the first [tutorials][tutorial] and build it locally with:
|
of the first [tutorials][tutorial] and build it locally with:
|
||||||
|
|
||||||
<pre><b>bash -c "$(curl -fsSL https://raw.githubusercontent.com/aantron/dream/master/example/quickstart.sh)"</b></pre>
|
<pre><b>bash -c "$(curl -fsSL https://raw.githubusercontent.com/aantron/dream/master/example/quickstart.sh)"</b></pre>
|
||||||
@ -139,10 +139,10 @@ After that, go to any of the [examples][tutorial], such as
|
|||||||
dune exec ./middleware.exe
|
dune exec ./middleware.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
[esy-example]: https://github.com/aantron/dream/tree/master/example/w-esy#folders-and-files
|
[esy-example]: https://github.com/aantron/dream/tree/master/example/w-esy#files
|
||||||
[quickstart.sh]: https://github.com/aantron/dream/blob/master/example/quickstart.sh
|
[quickstart.sh]: https://github.com/aantron/dream/blob/master/example/quickstart.sh
|
||||||
[esy]: https://esy.sh/
|
[esy]: https://esy.sh/
|
||||||
[2-middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files
|
[2-middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#files
|
||||||
|
|
||||||
## esy
|
## esy
|
||||||
|
|
||||||
@ -173,14 +173,14 @@ esy`, and started with `npx esy start`.
|
|||||||
|
|
||||||
[tutorial]: https://github.com/aantron/dream/tree/master/example#readme
|
[tutorial]: https://github.com/aantron/dream/tree/master/example#readme
|
||||||
[examples]: https://github.com/aantron/dream/tree/master/example#examples
|
[examples]: https://github.com/aantron/dream/tree/master/example#examples
|
||||||
[1-hello]: https://github.com/aantron/dream/tree/master/example/1-hello#folders-and-files
|
[1-hello]: https://github.com/aantron/dream/tree/master/example/1-hello#files
|
||||||
[r-hello]: https://github.com/aantron/dream/tree/master/example/r-hello#folders-and-files
|
[r-hello]: https://github.com/aantron/dream/tree/master/example/r-hello#files
|
||||||
[reason-examples]: https://github.com/aantron/dream/tree/master/example#reason
|
[reason-examples]: https://github.com/aantron/dream/tree/master/example#reason
|
||||||
[deploying]: https://github.com/aantron/dream/tree/master/example#deploying
|
[deploying]: https://github.com/aantron/dream/tree/master/example#deploying
|
||||||
[api-main]: https://aantron.github.io/dream/#types
|
[api-main]: https://aantron.github.io/dream/#types
|
||||||
[fullstack]: https://github.com/aantron/dream/tree/master/example#full-stack
|
[fullstack]: https://github.com/aantron/dream/tree/master/example#full-stack
|
||||||
[watch]: https://github.com/aantron/dream/tree/master/example/w-watch#folders-and-files
|
[watch]: https://github.com/aantron/dream/tree/master/example/w-watch#files
|
||||||
[reload]: https://github.com/aantron/dream/tree/master/example/w-live-reload#folders-and-files
|
[reload]: https://github.com/aantron/dream/tree/master/example/w-live-reload#files
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ Apart from the [issues](https://github.com/aantron/dream/issues), good places
|
|||||||
to discuss Dream are...
|
to discuss Dream are...
|
||||||
|
|
||||||
- #dream on the [Reason Discord](https://discord.gg/2JTYRq2rYh).
|
- #dream on the [Reason Discord](https://discord.gg/2JTYRq2rYh).
|
||||||
- #webdev on the [OCaml Discord](https://discord.gg/sx45hPkkWV).
|
- #webdev on the [OCaml Discord](https://discord.gg/sx45hPkkWV)
|
||||||
- The [OCaml Discuss forum](https://discuss.ocaml.org/).
|
- The [OCaml Discuss forum](https://discuss.ocaml.org/).
|
||||||
- The development stream on [Twitch](https://www.twitch.tv/antron_ML).
|
- The development stream on [Twitch](https://www.twitch.tv/antron_ML).
|
||||||
|
|
||||||
|
@ -1140,6 +1140,46 @@ let part_replacement = {|
|
|||||||
</pre>
|
</pre>
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
let upload_event_expected = {|<div class="spec type" id="type-upload_event">
|
||||||
|
<a href="#type-upload_event" class="anchor"></a><code><span><span class="keyword">type</span> upload_event</span><span> = </span><span>[ </span></code>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr id="type-upload_event.File" class="anchored">
|
||||||
|
<td class="def constructor">
|
||||||
|
<a href="#type-upload_event.File" class="anchor"></a><code><span>| </span></code><code><span>`File <span class="keyword">of</span> string * string</span></code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="type-upload_event.Field" class="anchored">
|
||||||
|
<td class="def constructor">
|
||||||
|
<a href="#type-upload_event.Field" class="anchor"></a><code><span>| </span></code><code><span>`Field <span class="keyword">of</span> string * string</span></code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="type-upload_event.Done" class="anchored">
|
||||||
|
<td class="def constructor">
|
||||||
|
<a href="#type-upload_event.Done" class="anchor"></a><code><span>| </span></code><code><span>`Done</span></code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="type-upload_event.Wrong_content_type" class="anchored">
|
||||||
|
<td class="def constructor">
|
||||||
|
<a href="#type-upload_event.Wrong_content_type" class="anchor"></a><code><span>| </span></code><code><span>`Wrong_content_type</span></code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<code><span> ]</span></code>
|
||||||
|
</div>
|
||||||
|
|}
|
||||||
|
|
||||||
|
let upload_event_replacement = {|
|
||||||
|
<pre><span class="keyword">type</span> upload_event = [
|
||||||
|
| `File <span class="of">of</span> <a href="https://ocaml.org/manual/latest/api/String.html">string</a> * <a href="https://ocaml.org/manual/latest/api/String.html">string</a>
|
||||||
|
| `Field <span class="of">of</span> <a href="https://ocaml.org/manual/latest/api/String.html">string</a> * <a href="https://ocaml.org/manual/latest/api/String.html">string</a>
|
||||||
|
| `Done
|
||||||
|
| `Wrong_content_type
|
||||||
|
]
|
||||||
|
</pre>
|
||||||
|
|}
|
||||||
|
|
||||||
let csrf_result_expected = {|<div class="spec type" id="type-csrf_result">
|
let csrf_result_expected = {|<div class="spec type" id="type-csrf_result">
|
||||||
<a href="#type-csrf_result" class="anchor"></a><code><span><span class="keyword">type</span> csrf_result</span><span> = </span><span>[ </span></code>
|
<a href="#type-csrf_result" class="anchor"></a><code><span><span class="keyword">type</span> csrf_result</span><span> = </span><span>[ </span></code>
|
||||||
<table>
|
<table>
|
||||||
@ -1657,6 +1697,18 @@ let new_field_replacement = {|
|
|||||||
</pre>
|
</pre>
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
let new_global_expected = {|<div class="spec value" id="val-new_global">
|
||||||
|
<a href="#val-new_global" class="anchor"></a><code><span><span class="keyword">val</span> new_global : <span>?name:string <span class="arrow">-></span></span> <span>?show_value:<span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> string)</span> <span class="arrow">-></span></span> <span><span>(<span>unit <span class="arrow">-></span></span> <span class="type-var">'a</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-global">global</a></span></span></code>
|
||||||
|
</div>
|
||||||
|
|}
|
||||||
|
|
||||||
|
let new_global_replacement = {|
|
||||||
|
<pre><span class="keyword">val</span> new_global :
|
||||||
|
?name:<a href="https://ocaml.org/manual/latest/api/String.html">string</a> ->
|
||||||
|
?show_value:('a -> <a href="https://ocaml.org/manual/latest/api/String.html">string</a>) ->
|
||||||
|
(<a href="https://ocaml.org/manual/latest/api/Unit.html">unit</a> -> 'a) -> 'a <a href="#type-global">global</a>
|
||||||
|
|}
|
||||||
|
|
||||||
let run_expected = {|<div class="spec value" id="val-run">
|
let run_expected = {|<div class="spec value" id="val-run">
|
||||||
<a href="#val-run" class="anchor"></a><code><span><span class="keyword">val</span> run : <span>?interface:string <span class="arrow">-></span></span> <span>?port:int <span class="arrow">-></span></span> <span>?socket_path:string <span class="arrow">-></span></span> <span>?stop:<span>unit <a href="#type-promise">promise</a></span> <span class="arrow">-></span></span>
|
<a href="#val-run" class="anchor"></a><code><span><span class="keyword">val</span> run : <span>?interface:string <span class="arrow">-></span></span> <span>?port:int <span class="arrow">-></span></span> <span>?socket_path:string <span class="arrow">-></span></span> <span>?stop:<span>unit <a href="#type-promise">promise</a></span> <span class="arrow">-></span></span>
|
||||||
<span>?error_handler:<a href="#type-error_handler">error_handler</a> <span class="arrow">-></span></span> <span>?tls:bool <span class="arrow">-></span></span> <span>?certificate_file:string <span class="arrow">-></span></span> <span>?key_file:string <span class="arrow">-></span></span>
|
<span>?error_handler:<a href="#type-error_handler">error_handler</a> <span class="arrow">-></span></span> <span>?tls:bool <span class="arrow">-></span></span> <span>?certificate_file:string <span class="arrow">-></span></span> <span>?key_file:string <span class="arrow">-></span></span>
|
||||||
|
@ -434,6 +434,7 @@ p + .odoc-spec {
|
|||||||
#val-origin_referrer_check + .spec-doc li + li,
|
#val-origin_referrer_check + .spec-doc li + li,
|
||||||
#val-form + .spec-doc li + li,
|
#val-form + .spec-doc li + li,
|
||||||
#type-part + .spec-doc li + li,
|
#type-part + .spec-doc li + li,
|
||||||
|
#type-upload_event + .spec-doc li + li,
|
||||||
#val-upload + .spec-doc li + li,
|
#val-upload + .spec-doc li + li,
|
||||||
#val-static + .spec-doc li + li,
|
#val-static + .spec-doc li + li,
|
||||||
#val-from_path + .spec-doc li + li {
|
#val-from_path + .spec-doc li + li {
|
||||||
|
@ -36,7 +36,7 @@ init_theme();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>1.0.0~alpha7</code></li>
|
<li><code>1.0.0~alpha6</code></li>
|
||||||
<li><code>opam install dream</code></li>
|
<li><code>opam install dream</code></li>
|
||||||
<li><a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream">GitHub</a></li>
|
<li><a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream">GitHub</a></li>
|
||||||
<li><a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/edit/master/src/dream.mli">Edit these docs</a></li>
|
<li><a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/edit/master/src/dream.mli">Edit these docs</a></li>
|
||||||
@ -123,7 +123,7 @@ init_theme();
|
|||||||
<li>
|
<li>
|
||||||
A <a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/tree/master/example#readme">
|
A <a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/tree/master/example#readme">
|
||||||
Tutorial</a> — get started at
|
Tutorial</a> — get started at
|
||||||
<a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/tree/master/example/1-hello#folders-and-files">
|
<a target="_blank" rel="noreferrer noopener" href="https://github.com/aantron/dream/tree/master/example/1-hello#files">
|
||||||
<code>1-hello</code></a>!
|
<code>1-hello</code></a>!
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -15,18 +15,31 @@ maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|||||||
depends: [
|
depends: [
|
||||||
"dream-pure"
|
"dream-pure"
|
||||||
"dune" {>= "2.7.0"} # --instrument-with.
|
"dune" {>= "2.7.0"} # --instrument-with.
|
||||||
"gluten"
|
|
||||||
"gluten-lwt-unix"
|
|
||||||
"h2" {< "0.13.0"}
|
|
||||||
"h2-lwt-unix"
|
|
||||||
"httpun" {< "0.2.0"}
|
|
||||||
"httpun-lwt-unix"
|
|
||||||
"httpun-ws"
|
|
||||||
"lwt"
|
"lwt"
|
||||||
"lwt_ppx" {>= "1.2.2"}
|
"lwt_ppx" {>= "1.2.2"}
|
||||||
"lwt_ssl"
|
"lwt_ssl"
|
||||||
"ocaml" {>= "4.08.0"}
|
"ocaml" {>= "4.08.0"}
|
||||||
"ssl" {>= "0.5.8"} # Ssl.get_negotiated_alpn_protocol.
|
"ssl" {>= "0.5.8"} # Ssl.get_negotiated_alpn_protocol.
|
||||||
|
|
||||||
|
# Currently vendored.
|
||||||
|
# "gluten"
|
||||||
|
# "gluten-lwt-unix"
|
||||||
|
# "httpaf"
|
||||||
|
# "httpaf-lwt-unix"
|
||||||
|
# "h2"
|
||||||
|
# "h2-lwt-unix"
|
||||||
|
# "hpack"
|
||||||
|
# "websocketaf"
|
||||||
|
|
||||||
|
# Dependencies of vendored packages.
|
||||||
|
"angstrom" {>= "0.14.0"}
|
||||||
|
"base64" {>= "3.0.0"}
|
||||||
|
"bigstringaf" {>= "0.5.0"} # h2.
|
||||||
|
"digestif" {>= "0.7.2"} # websocket/af, sha1, default implementation.
|
||||||
|
"faraday" {>= "0.6.1"}
|
||||||
|
"faraday-lwt-unix"
|
||||||
|
"lwt_ssl" {>= "1.2.0"} # Gluten.
|
||||||
|
"psq" # h2.
|
||||||
]
|
]
|
||||||
|
|
||||||
build: [
|
build: [
|
||||||
|
@ -29,7 +29,7 @@ Within this model, Dream adds:
|
|||||||
- Helpers for Web formats, such as Base64url, and a modern cipher.
|
- Helpers for Web formats, such as Base64url, and a modern cipher.
|
||||||
|
|
||||||
Because of the simple programming model, everything is optional and
|
Because of the simple programming model, everything is optional and
|
||||||
composable. It is trivially possible to strip Dream down to just a
|
composable. It is trivailly possible to strip Dream down to just a
|
||||||
bare driver of the various HTTP protocols.
|
bare driver of the various HTTP protocols.
|
||||||
|
|
||||||
Dream is presented as a single module, whose API is documented on one
|
Dream is presented as a single module, whose API is documented on one
|
||||||
|
@ -29,7 +29,7 @@ Within this model, Dream adds:
|
|||||||
- Helpers for Web formats, such as Base64url, and a modern cipher.
|
- Helpers for Web formats, such as Base64url, and a modern cipher.
|
||||||
|
|
||||||
Because of the simple programming model, everything is optional and
|
Because of the simple programming model, everything is optional and
|
||||||
composable. It is trivially possible to strip Dream down to just a
|
composable. It is trivailly possible to strip Dream down to just a
|
||||||
bare driver of the various HTTP protocols.
|
bare driver of the various HTTP protocols.
|
||||||
|
|
||||||
Dream is presented as a single module, whose API is documented on one
|
Dream is presented as a single module, whose API is documented on one
|
||||||
@ -55,7 +55,7 @@ depends: [
|
|||||||
("conf-libev" {os != "win32"} | "ocaml" {os = "win32"})
|
("conf-libev" {os != "win32"} | "ocaml" {os = "win32"})
|
||||||
"cstruct" {>= "6.0.0"}
|
"cstruct" {>= "6.0.0"}
|
||||||
"digestif" {>= "0.7"} # to_raw_string.
|
"digestif" {>= "0.7"} # to_raw_string.
|
||||||
"dream-httpaf" {>= "1.0.0~alpha4"}
|
"dream-httpaf" {>= "1.0.0~alpha3"}
|
||||||
"dream-pure" {>= "1.0.0~alpha2"}
|
"dream-pure" {>= "1.0.0~alpha2"}
|
||||||
"dune" {>= "2.7.0"} # --instrument-with.
|
"dune" {>= "2.7.0"} # --instrument-with.
|
||||||
"fmt" {>= "0.8.7"} # `Italic.
|
"fmt" {>= "0.8.7"} # `Italic.
|
||||||
@ -89,7 +89,7 @@ depends: [
|
|||||||
"html_of_jsx" {with-test}
|
"html_of_jsx" {with-test}
|
||||||
"js_of_ocaml" {with-test}
|
"js_of_ocaml" {with-test}
|
||||||
"js_of_ocaml-ppx" {with-test}
|
"js_of_ocaml-ppx" {with-test}
|
||||||
"ppx_expect" {with-test & >= "v0.15.0" & < "v0.17.0"} # Breaking changes.
|
"ppx_expect" {with-test & >= "v0.15.0"} # Formatting changes.
|
||||||
"ppx_yojson_conv" {with-test}
|
"ppx_yojson_conv" {with-test}
|
||||||
"reason" {with-test}
|
"reason" {with-test}
|
||||||
"tyxml" {with-test & >= "4.5.0"}
|
"tyxml" {with-test & >= "4.5.0"}
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -40,17 +40,17 @@ name of the `.ml` file, but with `.ml` changed to `.exe`.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- The next example, [**`2-middleware`**](../2-middleware#folders-and-files), adds a logger
|
- The next example, [**`2-middleware`**](../2-middleware#files), adds a logger
|
||||||
to the app.
|
to the app.
|
||||||
- [**`3-router`**](../3-router#folders-and-files) sends requests to different handlers,
|
- [**`3-router`**](../3-router#files) sends requests to different handlers,
|
||||||
depending on their path.
|
depending on their path.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-hello`**](../r-hello#folders-and-files) is a Reason syntax version of this example.
|
- [**`r-hello`**](../r-hello#files) is a Reason syntax version of this example.
|
||||||
- [**`w-watch`**](../w-watch#folders-and-files) sets up a development watcher.
|
- [**`w-watch`**](../w-watch#files) sets up a development watcher.
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
*Middleware* is just functions that take handlers and wrap them, producing
|
*Middleware* is just functions that take handlers and wrap them, producing
|
||||||
bigger handlers that do a little bit more. This example takes the handler from
|
bigger handlers that do a little bit more. This example takes the handler from
|
||||||
[**`1-hello`**](../1-hello#folders-and-files) and wraps it in one of the most useful
|
[**`1-hello`**](../1-hello#files) and wraps it in one of the most useful
|
||||||
middlewares, the [*logger*](https://aantron.github.io/dream/#val-logger):
|
middlewares, the [*logger*](https://aantron.github.io/dream/#val-logger):
|
||||||
|
|
||||||
```ocaml
|
```ocaml
|
||||||
@ -40,7 +40,7 @@ When you run this server and visit
|
|||||||
|
|
||||||
You can write your own messages to the log using
|
You can write your own messages to the log using
|
||||||
[`Dream.log`](https://aantron.github.io/dream/#val-log). See example
|
[`Dream.log`](https://aantron.github.io/dream/#val-log). See example
|
||||||
[**`a-log`**](../a-log#folders-and-files) for more logging options. Now that we have the
|
[**`a-log`**](../a-log#files) for more logging options. Now that we have the
|
||||||
logger, we will use it in all other examples, even though it's not really
|
logger, we will use it in all other examples, even though it's not really
|
||||||
necessary — it just makes it much easier to see what is going on.
|
necessary — it just makes it much easier to see what is going on.
|
||||||
|
|
||||||
@ -48,14 +48,14 @@ necessary — it just makes it much easier to see what is going on.
|
|||||||
|
|
||||||
There's not much else to middlewares — they are really just functions
|
There's not much else to middlewares — they are really just functions
|
||||||
from handlers to handlers, so you can create them anywhere. Example
|
from handlers to handlers, so you can create them anywhere. Example
|
||||||
[**`4-counter`**](../4-counter#folders-and-files) already shows a simple custom middleware.
|
[**`4-counter`**](../4-counter#files) already shows a simple custom middleware.
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
There are also more complicated middlewares defined in
|
There are also more complicated middlewares defined in
|
||||||
|
|
||||||
- [**`m-locals`**](../m-locals#folders-and-files),
|
- [**`m-locals`**](../m-locals/#files),
|
||||||
- [**`w-auto-reload`**](../w-auto-reload#folders-and-files), and
|
- [**`w-auto-reload`**](../w-auto-reload/#files), and
|
||||||
- [**`w-index-html`**](../w-index-html#folders-and-files).
|
- [**`w-index-html`**](../w-index-html/#files).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- TODO Fill out this list; probably a-promise belongs here. -->
|
<!-- TODO Fill out this list; probably a-promise belongs here. -->
|
||||||
@ -64,10 +64,10 @@ There are also more complicated middlewares defined in
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- The next example, [**`3-router`**](../3-router#folders-and-files), shows
|
- The next example, [**`3-router`**](../3-router#files), shows
|
||||||
[*routes*](https://aantron.github.io/dream/#routing), the other way to build
|
[*routes*](https://aantron.github.io/dream/#routing), the other way to build
|
||||||
up handlers in Dream.
|
up handlers in Dream.
|
||||||
- [**`4-counter`**](../4-counter#folders-and-files) builds the first custom middleware.
|
- [**`4-counter`**](../4-counter#files) builds the first custom middleware.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -42,20 +42,20 @@ The syntax `:word` in a route creates a path parameter, which can be read with
|
|||||||
When none of the routes match, the router returns a `404 Not Found` response.
|
When none of the routes match, the router returns a `404 Not Found` response.
|
||||||
Except for the status code, the `404 Not Found` response is *completely* empty,
|
Except for the status code, the `404 Not Found` response is *completely* empty,
|
||||||
so it might not display well in your browser. In example
|
so it might not display well in your browser. In example
|
||||||
[**`9-error`**](../9-error#folders-and-files), we will decorate all error responses with
|
[**`9-error`**](../9-error#files), we will decorate all error responses with
|
||||||
an error template in one central location.
|
an error template in one central location.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
The router can do more than match simple routes:
|
The router can do more than match simple routes:
|
||||||
|
|
||||||
- [**`f-static`**](../f-static#folders-and-files) forwards all requests with a certain
|
- [**`f-static`**](../f-static#files) forwards all requests with a certain
|
||||||
prefix to a static file handler.
|
prefix to a static file handler.
|
||||||
|
|
||||||
|
|
||||||
<!-- - [**`w-scope`**](../w-scope#folders-and-files) applies middlewares to groups of routes
|
<!-- - [**`w-scope`**](../w-scope/#files) applies middlewares to groups of routes
|
||||||
— but only when they match.
|
— but only when they match.
|
||||||
- [**`w-subsite`**](../w-subsite#folders-and-files) attaches a handler as a complete,
|
- [**`w-subsite`**](../w-subsite/#files) attaches a handler as a complete,
|
||||||
nested sub-site, which might have its own router. -->
|
nested sub-site, which might have its own router. -->
|
||||||
<!-- TODO -->
|
<!-- TODO -->
|
||||||
|
|
||||||
@ -63,9 +63,9 @@ The router can do more than match simple routes:
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`4-counter`**](../4-counter#folders-and-files) counts requests, and exposes a route for
|
- [**`4-counter`**](../4-counter#files) counts requests, and exposes a route for
|
||||||
getting the count.
|
getting the count.
|
||||||
- [**`5-promise`**](../5-promise#folders-and-files) introduces
|
- [**`5-promise`**](../5-promise#files) introduces
|
||||||
[Lwt](https://github.com/ocsigen/lwt), the promise library used by Dream.
|
[Lwt](https://github.com/ocsigen/lwt), the promise library used by Dream.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -37,16 +37,16 @@ which means they usually also
|
|||||||
This example's middleware only does something *before* calling the
|
This example's middleware only does something *before* calling the
|
||||||
`inner_handler`. To do something *after*, we will need to await the response
|
`inner_handler`. To do something *after*, we will need to await the response
|
||||||
promise with [Lwt](https://github.com/ocsigen/lwt#readme), the promise library
|
promise with [Lwt](https://github.com/ocsigen/lwt#readme), the promise library
|
||||||
used by Dream. The next example, [**`5-promise`**](../5-promise#folders-and-files), does
|
used by Dream. The next example, [**`5-promise`**](../5-promise#files), does
|
||||||
exactly that!
|
exactly that!
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`5-promise`**](../5-promise#folders-and-files) shows a middleware that awaits
|
- [**`5-promise`**](../5-promise#files) shows a middleware that awaits
|
||||||
responses using [Lwt](https://github.com/ocsigen/lwt).
|
responses using [Lwt](https://github.com/ocsigen/lwt).
|
||||||
- [**`6-echo`**](../6-echo#folders-and-files) responds to `POST` requests and reads their
|
- [**`6-echo`**](../6-echo#files) responds to `POST` requests and reads their
|
||||||
bodies.
|
bodies.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
[**`4-counter`**](../4-counter#folders-and-files) was limited to counting requests *before*
|
[**`4-counter`**](../4-counter#files) was limited to counting requests *before*
|
||||||
passing them on to the rest of the app. With the promise library
|
passing them on to the rest of the app. With the promise library
|
||||||
[Lwt](https://github.com/ocsigen/lwt), we can await responses, and do something
|
[Lwt](https://github.com/ocsigen/lwt), we can await responses, and do something
|
||||||
*after*. In this example, we separately count requests that were handled
|
*after*. In this example, we separately count requests that were handled
|
||||||
@ -91,8 +91,8 @@ We will stick to `let%lwt` in the examples and keep things tidy.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`6-echo`**](../6-echo#folders-and-files) uses Dream and Lwt to read a request body.
|
- [**`6-echo`**](../6-echo#files) uses Dream and Lwt to read a request body.
|
||||||
- [**`7-template`**](../7-template#folders-and-files) shows how to interleave HTML and
|
- [**`7-template`**](../7-template#files) shows how to interleave HTML and
|
||||||
OCaml.
|
OCaml.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -46,11 +46,11 @@ foo
|
|||||||
We usually want to do something more interesting with the request body than just
|
We usually want to do something more interesting with the request body than just
|
||||||
echo it, and there are several examples for that!
|
echo it, and there are several examples for that!
|
||||||
|
|
||||||
- [**`d-form`**](../d-form#folders-and-files) parses request bodies as forms.
|
- [**`d-form`**](../d-form#files) parses request bodies as forms.
|
||||||
- [**`e-json`**](../e-json#folders-and-files) parses bodies as JSON.
|
- [**`e-json`**](../e-json#files) parses bodies as JSON.
|
||||||
- [**`g-upload`**](../g-upload#folders-and-files) receives file upload forms.
|
- [**`g-upload`**](../g-upload#files) receives file upload forms.
|
||||||
- [**`i-graphql`**](../i-graphql#folders-and-files) receives GraphQL queries.
|
- [**`i-graphql`**](../i-graphql#files) receives GraphQL queries.
|
||||||
- [**`j-stream`**](../j-stream#folders-and-files) streams huge bodies.
|
- [**`j-stream`**](../j-stream#files) streams huge bodies.
|
||||||
|
|
||||||
We delay these examples a bit, so we can squeeze in a couple security topics
|
We delay these examples a bit, so we can squeeze in a couple security topics
|
||||||
first. These examples do take client input, after all! So, it's better to
|
first. These examples do take client input, after all! So, it's better to
|
||||||
@ -62,9 +62,9 @@ present them the right way.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`7-template`**](../7-template#folders-and-files) builds responses from templates and
|
- [**`7-template`**](../7-template#files) builds responses from templates and
|
||||||
guards against injection attacks (XSS).
|
guards against injection attacks (XSS).
|
||||||
- [**`8-debug`**](../8-debug#folders-and-files) renders error information in responses.
|
- [**`8-debug`**](../8-debug#files) renders error information in responses.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -125,31 +125,27 @@ and not supported by Dream.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`8-debug`**](../8-debug#folders-and-files) shows how to turn on debug responses, and
|
- [**`8-debug`**](../8-debug#files) shows how to turn on debug responses, and
|
||||||
get more info about errors.
|
get more info about errors.
|
||||||
- [**`9-error`**](../9-error#folders-and-files) sets up a central error template for all
|
- [**`9-error`**](../9-error#files) sets up a central error template for all
|
||||||
errors.
|
errors.
|
||||||
- [**`r-template`**](../r-template#folders-and-files) is a Reason syntax version of this
|
- [**`r-template`**](../r-template#files) is a Reason syntax version of this
|
||||||
example.
|
example.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-template-files`**](../w-template-files#folders-and-files) moves the template into a
|
- [**`w-template-files`**](../w-template-files#files) moves the template into a
|
||||||
separate `.eml.html` to avoid problems with editor support.
|
separate `.eml.html` to avoid problems with editor support.
|
||||||
- [**`w-template-logic`**](../w-template-logic#folders-and-files) shows how to put control
|
- [**`w-template-logic`**](../w-template-logic#files) shows how to put control
|
||||||
flow into templates.
|
flow into templates.
|
||||||
- [**`w-tyxml`**](../w-tyxml#folders-and-files) shows how to use
|
- [**`w-tyxml`**](../w-tyxml#files) shows how to use
|
||||||
[TyXML](https://github.com/ocsigen/tyxml), a different templater that uses
|
[TyXML](https://github.com/ocsigen/tyxml), a different templater that uses
|
||||||
OCaml's type system to prevent emitting many kinds of invalid HTML.
|
OCaml's type system to prevent emitting many kinds of invalid HTML.
|
||||||
- [**`r-tyxml`**](../r-tyxml#folders-and-files) if you are using Reason. You can use TyXML
|
- [**`r-tyxml`**](../r-tyxml#files) if you are using Reason. You can use TyXML
|
||||||
with JSX syntax server-side!
|
with JSX syntax server-side!
|
||||||
- [**`w-dream-html`**](../w-dream-html#folders-and-files) shows how to use
|
- [**`w-template-stream`**](../w-template-stream#files) streams templates to
|
||||||
[dream-html](https://github.com/yawaramin/dream-html), another alternative
|
|
||||||
library for generating HTML from OCaml, which is more closely integrated with
|
|
||||||
Dream.
|
|
||||||
- [**`w-template-stream`**](../w-template-stream#folders-and-files) streams templates to
|
|
||||||
responses, instead of building up complete response strings.
|
responses, instead of building up complete response strings.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -94,7 +94,7 @@ work with in development.
|
|||||||
|
|
||||||
You can have Dream show a custom error page with any information or graphics
|
You can have Dream show a custom error page with any information or graphics
|
||||||
that you like — we will do this in the [very next
|
that you like — we will do this in the [very next
|
||||||
example](../9-error#folders-and-files)!
|
example](../9-error#files)!
|
||||||
|
|
||||||
<!-- TODO Fix after stack trace is fixed. -->
|
<!-- TODO Fix after stack trace is fixed. -->
|
||||||
<!-- TODO Show the log -->
|
<!-- TODO Show the log -->
|
||||||
@ -104,9 +104,9 @@ example](../9-error#folders-and-files)!
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`9-error`**](../9-error#folders-and-files) handles all errors in one place, including
|
- [**`9-error`**](../9-error#files) handles all errors in one place, including
|
||||||
displaying the debugger output.
|
displaying the debugger output.
|
||||||
- [**`a-log`**](../a-log#folders-and-files) shows [log
|
- [**`a-log`**](../a-log#files) shows [log
|
||||||
levels](https://aantron.github.io/dream/#type-log_level) and
|
levels](https://aantron.github.io/dream/#type-log_level) and
|
||||||
[sub-logs](https://aantron.github.io/dream/#type-sub_log).
|
[sub-logs](https://aantron.github.io/dream/#type-sub_log).
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -63,7 +63,7 @@ including return a completely new response.
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
`debug_info` is a multiline string containing the same information as in the
|
`debug_info` is a multiline string containing the same information as in the
|
||||||
previous example, [**`8-debug`**](../8-debug#folders-and-files).
|
previous example, [**`8-debug`**](../8-debug#files).
|
||||||
|
|
||||||
<!-- TODO Images of the generated pages. -->
|
<!-- TODO Images of the generated pages. -->
|
||||||
|
|
||||||
@ -80,9 +80,9 @@ Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`a-log`**](../a-log#folders-and-files) shows how to write messages to Dream's
|
- [**`a-log`**](../a-log#files) shows how to write messages to Dream's
|
||||||
[log](https://aantron.github.io/dream/#logging).
|
[log](https://aantron.github.io/dream/#logging).
|
||||||
- [**`b-session`**](../b-session#folders-and-files) adds [session
|
- [**`b-session`**](../b-session#files) adds [session
|
||||||
management](https://aantron.github.io/dream/#sessions) for associating state
|
management](https://aantron.github.io/dream/#sessions) for associating state
|
||||||
with clients.
|
with clients.
|
||||||
|
|
||||||
|
@ -2,46 +2,46 @@
|
|||||||
|
|
||||||
Dream's first several examples make up a **tutorial**. Each example is a
|
Dream's first several examples make up a **tutorial**. Each example is a
|
||||||
complete project with a helpful README, and plenty of links to next steps and
|
complete project with a helpful README, and plenty of links to next steps and
|
||||||
documentation. You can begin at [**`1-hello`**](1-hello#folders-and-files), or look in the
|
documentation. You can begin at [**`1-hello`**](1-hello#files), or look in the
|
||||||
list below and jump to whatever interests you!
|
list below and jump to whatever interests you!
|
||||||
|
|
||||||
- [**`1-hello`**](1-hello#folders-and-files) — the simplest Dream server
|
- [**`1-hello`**](1-hello/#files) — the simplest Dream server
|
||||||
responds to every request with the same friendly message.
|
responds to every request with the same friendly message.
|
||||||
- [**`2-middleware`**](2-middleware#folders-and-files) — adds the first
|
- [**`2-middleware`**](2-middleware/#files) — adds the first
|
||||||
Dream middleware: the *logger*.
|
Dream middleware: the *logger*.
|
||||||
- [**`3-router`**](3-router#folders-and-files) — different handlers for
|
- [**`3-router`**](3-router/#files) — different handlers for
|
||||||
different paths.
|
different paths.
|
||||||
- [**`4-counter`**](4-counter#folders-and-files) — the first *custom*
|
- [**`4-counter`**](4-counter/#files) — the first *custom*
|
||||||
middleware!
|
middleware!
|
||||||
- [**`5-promise`**](5-promise#folders-and-files) — introduces Lwt, the
|
- [**`5-promise`**](5-promise/#files) — introduces Lwt, the
|
||||||
promise library used by Dream.
|
promise library used by Dream.
|
||||||
- [**`6-echo`**](6-echo#folders-and-files) — reads request bodies.
|
- [**`6-echo`**](6-echo/#files) — reads request bodies.
|
||||||
- [**`7-template`**](7-template#folders-and-files) — renders responses
|
- [**`7-template`**](7-template/#files) — renders responses
|
||||||
from inline HTML templates and guards against XSS.
|
from inline HTML templates and guards against XSS.
|
||||||
- [**`8-debug`**](8-debug#folders-and-files) — includes detailed
|
- [**`8-debug`**](8-debug/#files) — includes detailed
|
||||||
information about errors in responses.
|
information about errors in responses.
|
||||||
- [**`9-error`**](9-error#folders-and-files) — customize all error
|
- [**`9-error`**](9-error/#files) — customize all error
|
||||||
responses in one place.
|
responses in one place.
|
||||||
- [**`a-log`**](a-log#folders-and-files) — writing messages to Dream's
|
- [**`a-log`**](a-log/#files) — writing messages to Dream's
|
||||||
log.
|
log.
|
||||||
- [**`b-session`**](b-session#folders-and-files) — associates state with
|
- [**`b-session`**](b-session/#files) — associates state with
|
||||||
client sessions.
|
client sessions.
|
||||||
- [**`c-cookie`**](c-cookie#folders-and-files) — sets custom cookies.
|
- [**`c-cookie`**](c-cookie/#files) — sets custom cookies.
|
||||||
- [**`d-form`**](d-form#folders-and-files) — reads forms with CSRF
|
- [**`d-form`**](d-form#files) — reads forms with CSRF
|
||||||
prevention.
|
prevention.
|
||||||
- [**`e-json`**](e-json#folders-and-files) — sends and receives JSON
|
- [**`e-json`**](e-json#files) — sends and receives JSON
|
||||||
securely.
|
securely.
|
||||||
- [**`f-static`**](f-static#folders-and-files) — serves static files from
|
- [**`f-static`**](f-static#files) — serves static files from
|
||||||
a local directory.
|
a local directory.
|
||||||
- [**`g-upload`**](g-upload#folders-and-files) — receives file uploads.
|
- [**`g-upload`**](g-upload#files) — receives file uploads.
|
||||||
- [**`h-sql`**](h-sql#folders-and-files) — queries an SQL database.
|
- [**`h-sql`**](h-sql#files) — queries an SQL database.
|
||||||
- [**`i-graphql`**](i-graphql#folders-and-files) — serves a GraphQL
|
- [**`i-graphql`**](i-graphql#files) — serves a GraphQL
|
||||||
schema and GraphiQL.
|
schema and GraphiQL.
|
||||||
- [**`j-stream`**](j-stream#folders-and-files) — streams request and
|
- [**`j-stream`**](j-stream#files) — streams request and
|
||||||
response bodies.
|
response bodies.
|
||||||
- [**`k-websocket`**](k-websocket#folders-and-files) — opens a WebSocket
|
- [**`k-websocket`**](k-websocket#files) — opens a WebSocket
|
||||||
between client and server.
|
between client and server.
|
||||||
- [**`l-https`**](l-https#folders-and-files) — enables HTTPS and HTTP/2
|
- [**`l-https`**](l-https#files) — enables HTTPS and HTTP/2
|
||||||
upgrades.
|
upgrades.
|
||||||
|
|
||||||
That's it for the tutorial!
|
That's it for the tutorial!
|
||||||
@ -52,43 +52,43 @@ That's it for the tutorial!
|
|||||||
|
|
||||||
There are several examples showing Dream with Reason syntax.
|
There are several examples showing Dream with Reason syntax.
|
||||||
|
|
||||||
- [**`r-hello`**](r-hello#folders-and-files) — the simplest Dream server.
|
- [**`r-hello`**](r-hello#files) — the simplest Dream server.
|
||||||
- [**`r-template`**](r-template#folders-and-files) — renders HTML
|
- [**`r-template`**](r-template#files) — renders HTML
|
||||||
templates and protects against XSS.
|
templates and protects against XSS.
|
||||||
- [**`r-template-files`**](r-template-files#folders-and-files) — templates
|
- [**`r-template-files`**](r-template-files#files) — templates
|
||||||
in separate `.html` files for better editor support.
|
in separate `.html` files for better editor support.
|
||||||
- [**`r-template-logic`**](r-template-logic#folders-and-files) — control
|
- [**`r-template-logic`**](r-template-logic#files) — control
|
||||||
flow inside templates.
|
flow inside templates.
|
||||||
- [**`r-template-stream`**](r-template-stream#folders-and-files) — streams
|
- [**`r-template-stream`**](r-template-stream#files) — streams
|
||||||
templates as response bodies.
|
templates as response bodies.
|
||||||
- [**`r-tyxml`**](r-tyxml#folders-and-files) — type-checked server-side
|
- [**`r-tyxml`**](r-tyxml#files) — type-checked server-side
|
||||||
JSX templates.
|
JSX templates.
|
||||||
- [**`r-graphql`**](r-graphql#folders-and-files) — serves a GraphQL
|
- [**`r-graphql`**](r-graphql#files) — serves a GraphQL
|
||||||
schema.
|
schema.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
# Full-stack
|
# Full-stack
|
||||||
|
|
||||||
- [**`r-fullstack-melange`**](r-fullstack-melange#folders-and-files) —
|
- [**`r-fullstack-melange`**](r-fullstack-melange#files) —
|
||||||
server *and* client written in Reason!
|
server *and* client written in Reason!
|
||||||
- [**`w-fullstack-rescript`**](w-fullstack-rescript#folders-and-files) —
|
- [**`w-fullstack-rescript`**](w-fullstack-rescript#files) —
|
||||||
shares OCaml code between server and client using ReScript.
|
shares OCaml code between server and client using ReScript.
|
||||||
- [**`w-fullstack-jsoo`**](w-fullstack-jsoo#folders-and-files) — shares
|
- [**`w-fullstack-jsoo`**](w-fullstack-jsoo#files) — shares
|
||||||
OCaml code between server and client using js_of_ocaml.
|
OCaml code between server and client using js_of_ocaml.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
# Deploying
|
# Deploying
|
||||||
|
|
||||||
- [**`z-heroku`**](z-heroku#folders-and-files) — to
|
- [**`z-heroku`**](z-heroku#files) — to
|
||||||
[Heroku](https://www.heroku.com).
|
[Heroku](https://www.heroku.com).
|
||||||
- [**`z-fly`**](z-fly#folders-and-files) — to [Fly.io](https://fly.io/).
|
- [**`z-fly`**](z-fly#files) — to [Fly.io](https://fly.io/).
|
||||||
- [**`z-docker-esy`**](z-docker-esy#folders-and-files) — on a server,
|
- [**`z-docker-esy`**](z-docker-esy#files) — on a server,
|
||||||
using Docker, with package manager esy.
|
using Docker, with package manager esy.
|
||||||
- [**`z-docker-opam`**](z-docker-opam#folders-and-files) — on a server,
|
- [**`z-docker-opam`**](z-docker-opam#files) — on a server,
|
||||||
using Docker, with package manager opam.
|
using Docker, with package manager opam.
|
||||||
- [**`z-systemd`**](z-systemd#folders-and-files) — on a server, as a
|
- [**`z-systemd`**](z-systemd#files) — on a server, as a
|
||||||
systemd daemon.
|
systemd daemon.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -102,51 +102,49 @@ if something is missing!
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
- [**`w-template-files`**](w-template-files#folders-and-files) — templates
|
- [**`w-template-files`**](w-template-files#files) — templates
|
||||||
in separate `.html` files for better editor support.
|
in separate `.html` files for better editor support.
|
||||||
- [**`w-template-logic`**](w-template-logic#folders-and-files) — control
|
- [**`w-template-logic`**](w-template-logic#files) — control
|
||||||
flow inside templates.
|
flow inside templates.
|
||||||
- [**`w-graphql-subscription`**](w-graphql-subscription#folders-and-files)
|
- [**`w-graphql-subscription`**](w-graphql-subscription#files)
|
||||||
— GraphQL subscriptions.
|
— GraphQL subscriptions.
|
||||||
- [**`w-postgres`**](w-postgres#folders-and-files) — connects to a
|
- [**`w-postgres`**](w-postgres#files) — connects to a
|
||||||
PostgreSQL database.
|
PostgreSQL database.
|
||||||
- [**`w-flash`**](w-flash#folders-and-files) — using flash messages, which
|
- [**`w-flash`**](w-flash#files) — using flash messages, which
|
||||||
are displayed on the next request.
|
are displayed on the next request.
|
||||||
- [**`w-chat`**](w-chat#folders-and-files) — a chat room based on
|
- [**`w-chat`**](w-chat#files) — a chat room based on
|
||||||
WebSockets.
|
WebSockets.
|
||||||
- [**`w-content-security-policy`**](w-content-security-policy#folders-and-files)
|
- [**`w-content-security-policy`**](w-content-security-policy#files)
|
||||||
— sandboxes Web pages using `Content-Security-Policy`.
|
— sandboxes Web pages using `Content-Security-Policy`.
|
||||||
- [**`w-esy`**](w-esy#folders-and-files) — gives detail on packaging with
|
- [**`w-esy`**](w-esy#files) — gives detail on packaging with
|
||||||
[esy](https://esy.sh/), an npm-like package manager.
|
[esy](https://esy.sh/), an npm-like package manager.
|
||||||
- [**`w-one-binary`**](w-one-binary#folders-and-files) — bakes static
|
- [**`w-one-binary`**](w-one-binary#files) — bakes static
|
||||||
assets into a self-contained server binary.
|
assets into a self-contained server binary.
|
||||||
- [**`w-watch`**](w-watch#folders-and-files) — sets up a development
|
- [**`w-watch`**](w-watch#files) — sets up a development
|
||||||
watcher.
|
watcher.
|
||||||
- [**`w-live-reload`**](w-live-reload#folders-and-files) — a simple
|
- [**`w-live-reload`**](w-live-reload#files) — a simple
|
||||||
live-reloading setup.
|
live-reloading setup.
|
||||||
- [**`w-nginx`**](w-nginx#folders-and-files) — uses nginx as a
|
- [**`w-nginx`**](w-nginx#files) — uses nginx as a
|
||||||
reverse proxy.
|
reverse proxy.
|
||||||
- [**`w-tyxml`**](w-tyxml#folders-and-files) — uses TyXML for type-checked
|
- [**`w-tyxml`**](w-tyxml#files) — uses TyXML for type-checked
|
||||||
HTML templating.
|
HTML templating.
|
||||||
- [**`w-dream-html`**](../w-dream-html#folders-and-files) — uses
|
- [**`w-long-polling`**](w-long-polling#files) — old form of
|
||||||
dream-html for convenient HTML generation from OCaml.
|
|
||||||
- [**`w-long-polling`**](w-long-polling#folders-and-files) — old form of
|
|
||||||
asynchronous communication without WebSockets.
|
asynchronous communication without WebSockets.
|
||||||
- [**`w-query`**](w-query#folders-and-files) — reads URL query parameters.
|
- [**`w-query`**](w-query#files) — reads URL query parameters.
|
||||||
- [**`w-server-sent-events`**](w-server-sent-events#folders-and-files) —
|
- [**`w-server-sent-events`**](w-server-sent-events#files) —
|
||||||
[`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource),
|
[`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource),
|
||||||
an older alternative to WebSockets.
|
an older alternative to WebSockets.
|
||||||
- [**`w-template-stream`**](w-template-stream#folders-and-files) — sends
|
- [**`w-template-stream`**](w-template-stream#files) — sends
|
||||||
templates asynchronously, one chunk at a time.
|
templates asynchronously, one chunk at a time.
|
||||||
- [**`w-upload-stream`**](w-upload-stream#folders-and-files) — streams
|
- [**`w-upload-stream`**](w-upload-stream#files) — streams
|
||||||
uploaded files.
|
uploaded files.
|
||||||
- [**`w-stress-response`**](w-stress-response#folders-and-files) —
|
- [**`w-stress-response`**](w-stress-response#files) —
|
||||||
benchmarks streaming very large responses.
|
benchmarks streaming very large responses.
|
||||||
- [**`w-stress-websocket-send`**](w-stress-websocket-send#folders-and-files)
|
- [**`w-stress-websocket-send`**](w-stress-websocket-send#files)
|
||||||
— benchmarks sending WebSocket messages quickly.
|
— benchmarks sending WebSocket messages quickly.
|
||||||
- [**`w-multipart-dump`**](w-multipart-dump#folders-and-files) — echoes
|
- [**`w-multipart-dump`**](w-multipart-dump#files) — echoes
|
||||||
`multipart/form-data` bodies for debugging.
|
`multipart/form-data` bodies for debugging.
|
||||||
- [**`z-playground`**](z-playground#folders-and-files) — source code of
|
- [**`z-playground`**](z-playground#files) — source code of
|
||||||
the Dream playground.
|
the Dream playground.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -169,7 +167,7 @@ Ideas:
|
|||||||
Basics:
|
Basics:
|
||||||
|
|
||||||
- `w-content-negotiation`
|
- `w-content-negotiation`
|
||||||
- [**`w-query`**](w-query#folders-and-files) — done.
|
- [**`w-query`**](w-query#files) — done.
|
||||||
- `w-scope` — for
|
- `w-scope` — for
|
||||||
[`Dream.scope`](https://aantron.github.io/dream/#val-scope).
|
[`Dream.scope`](https://aantron.github.io/dream/#val-scope).
|
||||||
- `w-subsite` — for
|
- `w-subsite` — for
|
||||||
|
@ -76,9 +76,9 @@ let () =
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`b-session`**](../b-session#folders-and-files) returns Web development proper with
|
- [**`b-session`**](../b-session#files) returns Web development proper with
|
||||||
session management.
|
session management.
|
||||||
- [**`c-cookie`**](../c-cookie#folders-and-files) shows cookie handling in Dream.
|
- [**`c-cookie`**](../c-cookie#files) shows cookie handling in Dream.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -68,7 +68,7 @@ There are two other session back ends, which are persistent:
|
|||||||
using a different random encryption key each time it starts.
|
using a different random encryption key each time it starts.
|
||||||
- [`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions)
|
- [`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions)
|
||||||
stores sessions in a database. It is shown in example
|
stores sessions in a database. It is shown in example
|
||||||
[**`h-sql`**](../h-sql#folders-and-files).
|
[**`h-sql`**](../h-sql#files).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ new session will, again, be an empty pre-session.
|
|||||||
It is best to use HTTPS when using sessions, to prevent session cookies from
|
It is best to use HTTPS when using sessions, to prevent session cookies from
|
||||||
being easily observed by third parties. See
|
being easily observed by third parties. See
|
||||||
[`Dream.run`](https://aantron.github.io/dream/#val-run) argument `~https`, and
|
[`Dream.run`](https://aantron.github.io/dream/#val-run) argument `~https`, and
|
||||||
example [**`l-https`**](../l-https#folders-and-files). If you redirect from HTTP to HTTPS,
|
example [**`l-https`**](../l-https#files). If you redirect from HTTP to HTTPS,
|
||||||
do not issue sessions for HTTP requests. If you do, don't accept them later
|
do not issue sessions for HTTP requests. If you do, don't accept them later
|
||||||
from HTTPS requests.
|
from HTTPS requests.
|
||||||
|
|
||||||
@ -100,8 +100,8 @@ from HTTPS requests.
|
|||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- Sessions already use cookies internally, but in
|
- Sessions already use cookies internally, but in
|
||||||
[**`c-cookie`**](../c-cookie#folders-and-files) we set cookies for our own purposes!
|
[**`c-cookie`**](../c-cookie#files) we set cookies for our own purposes!
|
||||||
- [**`d-form`**](../d-form#folders-and-files) builds secure forms on top of sessions.
|
- [**`d-form`**](../d-form#files) builds secure forms on top of sessions.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -96,9 +96,9 @@ The easiest way to do that for general data is to use
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`d-form`**](../d-form#folders-and-files) builds secure forms on top of sessions, and
|
- [**`d-form`**](../d-form#files) builds secure forms on top of sessions, and
|
||||||
introduces automatic handling of CSRF tokens.
|
introduces automatic handling of CSRF tokens.
|
||||||
- [**`e-json`**](../e-json#folders-and-files) sends and receives JSON instead!
|
- [**`e-json`**](../e-json#files) sends and receives JSON instead!
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
With the session middleware from example [**`b-session`**](../b-session#folders-and-files),
|
With the session middleware from example [**`b-session`**](../b-session#files),
|
||||||
we can build a [secure form](https://aantron.github.io/dream/#forms):
|
we can build a [secure form](https://aantron.github.io/dream/#forms):
|
||||||
|
|
||||||
```ocaml
|
```ocaml
|
||||||
@ -100,14 +100,14 @@ important on login forms and other sensitive pages.
|
|||||||
|
|
||||||
However, this server is so simple that it doesn't store the data anywhere, and
|
However, this server is so simple that it doesn't store the data anywhere, and
|
||||||
the data is not sensitive, so we took a shortcut. See
|
the data is not sensitive, so we took a shortcut. See
|
||||||
[**`h-sql`**](../h-sql#folders-and-files) for an example with a proper redirection.
|
[**`h-sql`**](../h-sql#files) for an example with a proper redirection.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`e-json`**](../e-json#folders-and-files) receives and sends JSON.
|
- [**`e-json`**](../e-json#files) receives and sends JSON.
|
||||||
- [**`f-static`**](../f-static#folders-and-files) serves static files from a local
|
- [**`f-static`**](../f-static#files) serves static files from a local
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -49,7 +49,7 @@ To get this working, we have to add `ppx_yojson_conv` to our
|
|||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
and to
|
and to
|
||||||
[`json.opam`](https://github.com/aantron/dream/blob/master/example/e-json/e-json.opam):
|
[`json.opam`](https://github.com/aantron/dream/blob/master/example/e-json/json.opam):
|
||||||
|
|
||||||
<pre><code>depends: [
|
<pre><code>depends: [
|
||||||
"ocaml" {>= "4.08.0"}
|
"ocaml" {>= "4.08.0"}
|
||||||
@ -112,9 +112,9 @@ requests!
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`f-static`**](../f-static#folders-and-files) serves static files from the local
|
- [**`f-static`**](../f-static#files) serves static files from the local
|
||||||
file system.
|
file system.
|
||||||
- [**`g-upload`**](../g-upload#folders-and-files) receives files from an upload form.
|
- [**`g-upload`**](../g-upload#files) receives files from an upload form.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -6,10 +6,3 @@ depends: [
|
|||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
"ppx_yojson_conv"
|
"ppx_yojson_conv"
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -56,7 +56,7 @@ You can replace the file loading behavior of
|
|||||||
[crunch](https://github.com/mirage/ocaml-crunch) to compile a directory right
|
[crunch](https://github.com/mirage/ocaml-crunch) to compile a directory right
|
||||||
into your Web app binary, and then serve that directory from memory with
|
into your Web app binary, and then serve that directory from memory with
|
||||||
[`Dream.static`](https://aantron.github.io/dream/#val-static)! See example
|
[`Dream.static`](https://aantron.github.io/dream/#val-static)! See example
|
||||||
[**`w-one-binary`**](../w-one-binary#folders-and-files).
|
[**`w-one-binary`**](../w-one-binary#files).
|
||||||
|
|
||||||
You can also use `~loader` to set arbitrary headers on the response.
|
You can also use `~loader` to set arbitrary headers on the response.
|
||||||
|
|
||||||
@ -64,9 +64,9 @@ You can also use `~loader` to set arbitrary headers on the response.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`g-upload`**](../g-upload#folders-and-files) receives files instead of serving them.
|
- [**`g-upload`**](../g-upload#files) receives files instead of serving them.
|
||||||
- [**`h-sql`**](../h-sql#folders-and-files) runs SQL queries against a database.
|
- [**`h-sql`**](../h-sql#files) runs SQL queries against a database.
|
||||||
- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a
|
- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a
|
||||||
self-contained binary.
|
self-contained binary.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -74,7 +74,7 @@ However, this is only good for rare, small uploads, such as user avatars, or for
|
|||||||
prototyping.
|
prototyping.
|
||||||
|
|
||||||
For more heavy usage, see
|
For more heavy usage, see
|
||||||
[`Dream.upload`](https://aantron.github.io/dream/#val-upload) for
|
[`Dream.upload`](https://aantron.github.io/dream/#type-upload_event) for
|
||||||
streaming file uploads.
|
streaming file uploads.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -84,7 +84,7 @@ streaming file uploads.
|
|||||||
[`Dream.multipart`](https://aantron.github.io/dream/#val-multipart) behaves just
|
[`Dream.multipart`](https://aantron.github.io/dream/#val-multipart) behaves just
|
||||||
like [`Dream.form`](https://aantron.github.io/dream/#val-form) when it comes to
|
like [`Dream.form`](https://aantron.github.io/dream/#val-form) when it comes to
|
||||||
[CSRF protection](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html).
|
[CSRF protection](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html).
|
||||||
See example [**`d-form`**](../d-form#folders-and-files). We use
|
See example [**`d-form`**](../d-form#files). We use
|
||||||
[`Dream.csrf_tag`](https://aantron.github.io/dream/#val-csrf_tag) to generate
|
[`Dream.csrf_tag`](https://aantron.github.io/dream/#val-csrf_tag) to generate
|
||||||
the CSRF token in the template, and pass the `enctype="multipart/form-data"`
|
the CSRF token in the template, and pass the `enctype="multipart/form-data"`
|
||||||
attribute as needed for forms to upload files. The template output looks like
|
attribute as needed for forms to upload files. The template output looks like
|
||||||
@ -109,17 +109,17 @@ for a checklist of additional security precautions.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`h-sql`**](../h-sql#folders-and-files) runs SQL queries against a database.
|
- [**`h-sql`**](../h-sql#files) runs SQL queries against a database.
|
||||||
- [**`i-graphql`**](../i-graphql#folders-and-files) handles GraphQL queries and serves
|
- [**`i-graphql`**](../i-graphql#files) handles GraphQL queries and serves
|
||||||
GraphiQL.
|
GraphiQL.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-upload-stream`**](../w-upload-stream#folders-and-files) shows the streaming
|
- [**`w-upload-stream`**](../w-upload-stream#files) shows the streaming
|
||||||
interface for receiving file uploads.
|
interface for receiving file uploads.
|
||||||
- [**`w-multipart-dump`**](../w-multipart-dump#folders-and-files) shows the request body
|
- [**`w-multipart-dump`**](../w-multipart-dump#files) shows the request body
|
||||||
that is interpreted by
|
that is interpreted by
|
||||||
[`Dream.multipart`](https://aantron.github.io/dream/#val-multipart).
|
[`Dream.multipart`](https://aantron.github.io/dream/#val-multipart).
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -14,7 +14,7 @@ module T = Caqti_type
|
|||||||
let list_comments =
|
let list_comments =
|
||||||
let query =
|
let query =
|
||||||
let open Caqti_request.Infix in
|
let open Caqti_request.Infix in
|
||||||
(T.unit ->* T.(t2 int string))
|
(T.unit ->* T.(tup2 int string))
|
||||||
"SELECT id, text FROM comment" in
|
"SELECT id, text FROM comment" in
|
||||||
fun (module Db : DB) ->
|
fun (module Db : DB) ->
|
||||||
let%lwt comments_or_error = Db.collect_list query () in
|
let%lwt comments_or_error = Db.collect_list query () in
|
||||||
@ -82,7 +82,7 @@ comments!
|
|||||||
We take the opportunity to try out
|
We take the opportunity to try out
|
||||||
[`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions), which
|
[`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions), which
|
||||||
stores session data persistently in `db.sqlite`. See example
|
stores session data persistently in `db.sqlite`. See example
|
||||||
[**`b-session`**](../b-session#folders-and-files) for an introduction to session management.
|
[**`b-session`**](../b-session#files) for an introduction to session management.
|
||||||
Both the comments and the sessions survive server restarts.
|
Both the comments and the sessions survive server restarts.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -132,7 +132,7 @@ We also had to make an addition to our
|
|||||||
|
|
||||||
SQLite is good for small-to-medium sites and examples. For a larger site,
|
SQLite is good for small-to-medium sites and examples. For a larger site,
|
||||||
microservices, or other needs, you can switch, for example, to PostgreSQL. See
|
microservices, or other needs, you can switch, for example, to PostgreSQL. See
|
||||||
[**`w-postgres`**](../w-postgres#folders-and-files).
|
[**`w-postgres`**](../w-postgres#files).
|
||||||
|
|
||||||
A good program for examining databases locally is
|
A good program for examining databases locally is
|
||||||
[Beekeeper Studio](https://www.beekeeperstudio.io/). Dream might also integrate
|
[Beekeeper Studio](https://www.beekeeperstudio.io/). Dream might also integrate
|
||||||
@ -156,9 +156,9 @@ See
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`i-graphql`**](../i-graphql#folders-and-files) handles GraphQL queries and serves
|
- [**`i-graphql`**](../i-graphql#files) handles GraphQL queries and serves
|
||||||
GraphiQL.
|
GraphiQL.
|
||||||
- [**`j-stream`**](../j-stream#folders-and-files) streams response bodies to clients.
|
- [**`j-stream`**](../j-stream#files) streams response bodies to clients.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -6,10 +6,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -89,17 +89,17 @@ GraphiQL conditionally, only during development.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`j-stream`**](../j-stream#folders-and-files) streams response bodies to clients.
|
- [**`j-stream`**](../j-stream#files) streams response bodies to clients.
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) sends and receives messages over a
|
- [**`k-websocket`**](../k-websocket#files) sends and receives messages over a
|
||||||
WebSocket.
|
WebSocket.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-graphql`**](../r-graphql#folders-and-files) is a version of this example in Reason
|
- [**`r-graphql`**](../r-graphql#files) is a version of this example in Reason
|
||||||
syntax.
|
syntax.
|
||||||
- [**`w-graphql-subscription`**](../w-graphql-subscription#folders-and-files) for GraphQL
|
- [**`w-graphql-subscription`**](../w-graphql-subscription#files) for GraphQL
|
||||||
subscriptions.
|
subscriptions.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
In example [**`6-echo`**](../6-echo#folders-and-files), we echoed `POST` requests by reading
|
In example [**`6-echo`**](../6-echo#files), we echoed `POST` requests by reading
|
||||||
their whole bodies into memory, and then writing them. Here, we echo request
|
their whole bodies into memory, and then writing them. Here, we echo request
|
||||||
bodies chunk by chunk:
|
bodies chunk by chunk:
|
||||||
|
|
||||||
@ -60,9 +60,9 @@ See [*Streams*](https://aantron.github.io/dream/#streams) in the API docs.
|
|||||||
|
|
||||||
**Next steps:**
|
**Next steps:**
|
||||||
|
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) sends and receives messages over a
|
- [**`k-websocket`**](../k-websocket#files) sends and receives messages over a
|
||||||
WebSocket.
|
WebSocket.
|
||||||
- [**`l-https`**](../l-https#folders-and-files) enables HTTPS, which is very easy with
|
- [**`l-https`**](../l-https#files) enables HTTPS, which is very easy with
|
||||||
Dream.
|
Dream.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -78,14 +78,14 @@ See [*WebSockets*](https://aantron.github.io/dream/#websockets) in the API docs.
|
|||||||
|
|
||||||
**Last step:**
|
**Last step:**
|
||||||
|
|
||||||
- [**`l-https`**](../l-https#folders-and-files) enables HTTPS.
|
- [**`l-https`**](../l-https#files) enables HTTPS.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-chat`**](../w-chat#folders-and-files) is a simple WebSocket-based chat application.
|
- [**`w-chat`**](../w-chat#files) is a simple WebSocket-based chat application.
|
||||||
- [**`w-live-reload`**](../w-live-reload#folders-and-files) uses WebSockets to implement
|
- [**`w-live-reload`**](../w-live-reload#files) uses WebSockets to implement
|
||||||
live reloading.
|
live reloading.
|
||||||
- [**`w-graphql-subscription`**](../w-graphql-subscription) does not show a
|
- [**`w-graphql-subscription`**](../w-graphql-subscription) does not show a
|
||||||
WebSocket directly, but shows GraphQL subscriptions, which are implemented
|
WebSocket directly, but shows GraphQL subscriptions, which are implemented
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -42,7 +42,7 @@ cd $DIRECTORY
|
|||||||
|
|
||||||
echo
|
echo
|
||||||
echo -e "\e[0m✅ Fetching example files using git\e[0m"
|
echo -e "\e[0m✅ Fetching example files using git\e[0m"
|
||||||
echo -e "\e[0m Source: $REPO/tree/$REF/example/$EXAMPLE#folders-and-files\e[0m"
|
echo -e "\e[0m Source: $REPO/tree/$REF/example/$EXAMPLE#files\e[0m"
|
||||||
mkdir clone
|
mkdir clone
|
||||||
cd clone
|
cd clone
|
||||||
git init --quiet
|
git init --quiet
|
||||||
@ -81,7 +81,7 @@ echo " dune exec ./$EXE --watch"
|
|||||||
echo
|
echo
|
||||||
echo -e "\e[0m✅ See\e[0m"
|
echo -e "\e[0m✅ See\e[0m"
|
||||||
echo
|
echo
|
||||||
echo " - This example:" $REPO/tree/$REF/example/$EXAMPLE#folders-and-files
|
echo " - This example:" $REPO/tree/$REF/example/$EXAMPLE#files
|
||||||
echo " - Tutorial: " $REPO/tree/$REF/example#tutorial
|
echo " - Tutorial: " $REPO/tree/$REF/example#tutorial
|
||||||
echo
|
echo
|
||||||
echo 💲 dune exec ./$EXE
|
echo 💲 dune exec ./$EXE
|
||||||
|
@ -87,12 +87,12 @@ example in OCaml syntax.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-watch`**](../w-fswatch#folders-and-files) sets up a development watcher.
|
- [**`w-watch`**](../w-fswatch#files) sets up a development watcher.
|
||||||
- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a
|
- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a
|
||||||
self-contained binary.
|
self-contained binary.
|
||||||
- [**`7-template`**](../7-template#folders-and-files) discusses the templater, including
|
- [**`7-template`**](../7-template#files) discusses the templater, including
|
||||||
security. The example is in OCaml syntax.
|
security. The example is in OCaml syntax.
|
||||||
- [**`r-template`**](../r-template#folders-and-files) the code of the template example in
|
- [**`r-template`**](../r-template#files) the code of the template example in
|
||||||
Reason syntax.
|
Reason syntax.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -8,10 +8,3 @@ depends: [
|
|||||||
"melange-webapi"
|
"melange-webapi"
|
||||||
"reason" {>= "3.10.0"}
|
"reason" {>= "3.10.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -83,9 +83,9 @@ the schema:
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`i-graphql`**](../i-graphql#folders-and-files), the OCaml version of this example, for
|
- [**`i-graphql`**](../i-graphql#files), the OCaml version of this example, for
|
||||||
some more discussion.
|
some more discussion.
|
||||||
- [**`w-graphql-subscription`**](../w-graphql-subscription#folders-and-files) for GraphQL
|
- [**`w-graphql-subscription`**](../w-graphql-subscription#files) for GraphQL
|
||||||
subscriptions.
|
subscriptions.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -37,7 +37,7 @@ Note that we had to make an addition to
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-template`**](../r-template#folders-and-files) shows templates with Reason syntax.
|
- [**`r-template`**](../r-template#files) shows templates with Reason syntax.
|
||||||
- [**`2-middleware`**](../2-middleware) introduces the *logger*, the most
|
- [**`2-middleware`**](../2-middleware) introduces the *logger*, the most
|
||||||
commonly used Dream middleware. The example is in OCaml syntax.
|
commonly used Dream middleware. The example is in OCaml syntax.
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
This example splits the code of the basic template example,
|
This example splits the code of the basic template example,
|
||||||
[**`r-template`**](../r-template#folders-and-files), into two files. The first is the
|
[**`r-template`**](../r-template#files), into two files. The first is the
|
||||||
template, in
|
template, in
|
||||||
[`template.eml.html`](https://github.com/aantron/dream/blob/master/example/r-template-files/template.eml.html). We use the `.html` extension because it is
|
[`template.eml.html`](https://github.com/aantron/dream/blob/master/example/r-template-files/template.eml.html). We use the `.html` extension because it is
|
||||||
mostly HTML, and to prevent `refmt` from trying to format the file:
|
mostly HTML, and to prevent `refmt` from trying to format the file:
|
||||||
@ -57,8 +57,8 @@ file:
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-template`**](../r-template#folders-and-files) for the one-file version.
|
- [**`r-template`**](../r-template#files) for the one-file version.
|
||||||
- [**`7-template`**](../7-template#folders-and-files) for comments on [security
|
- [**`7-template`**](../7-template#files) for comments on [security
|
||||||
information](../7-template#security).
|
information](../7-template#security).
|
||||||
- [**`w-template-files`**](../w-template-files) for the OCaml version of this
|
- [**`w-template-files`**](../w-template-files) for the OCaml version of this
|
||||||
example.
|
example.
|
||||||
|
@ -74,8 +74,8 @@ let () =
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`7-template`**](../7-template#folders-and-files) for basic information about templates.
|
- [**`7-template`**](../7-template#files) for basic information about templates.
|
||||||
- [**`w-template-logic`**](../w-template-logic#folders-and-files) for the OCaml version
|
- [**`w-template-logic`**](../w-template-logic#files) for the OCaml version
|
||||||
of this example.
|
of this example.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -49,7 +49,7 @@ The important differences with regular usage of templates are:
|
|||||||
name `response`.
|
name `response`.
|
||||||
- We use the promise library [Lwt](https://github.com/ocsigen/lwt) inside the
|
- We use the promise library [Lwt](https://github.com/ocsigen/lwt) inside the
|
||||||
template for asynchronous control flow. See example
|
template for asynchronous control flow. See example
|
||||||
[**`5-promise`**](../5-promise#folders-and-files) for an introduction to Lwt.
|
[**`5-promise`**](../5-promise#files) for an introduction to Lwt.
|
||||||
|
|
||||||
The call to [`Dream.flush`](https://aantron.github.io/dream/#val-flush) isn't
|
The call to [`Dream.flush`](https://aantron.github.io/dream/#val-flush) isn't
|
||||||
necessary in most real-world cases — Dream's HTTP layer automatically
|
necessary in most real-world cases — Dream's HTTP layer automatically
|
||||||
@ -60,11 +60,11 @@ interactive, so we force writing of all output after generating each `<p>` tag.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-template`**](../r-template#folders-and-files) for the simpler way to do templates,
|
- [**`r-template`**](../r-template#files) for the simpler way to do templates,
|
||||||
building up entire bodies as strings.
|
building up entire bodies as strings.
|
||||||
- [**`7-template`**](../7-template#security) section *Security* for XSS
|
- [**`7-template`**](../7-template#security) section *Security* for XSS
|
||||||
prevention considerations.
|
prevention considerations.
|
||||||
- [**`w-template-stream`**](../w-template-stream#folders-and-files) is the OCaml version of
|
- [**`w-template-stream`**](../w-template-stream#files) is the OCaml version of
|
||||||
this example.
|
this example.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -59,11 +59,11 @@ same.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`r-template-files`**](../r-template-files#folders-and-files) puts the template into a
|
- [**`r-template-files`**](../r-template-files#files) puts the template into a
|
||||||
separate `.eml.html` file, which can help with editor problems.
|
separate `.eml.html` file, which can help with editor problems.
|
||||||
- [**`r-template-stream`**](../r-template-stream#folders-and-files) streams a template to a
|
- [**`r-template-stream`**](../r-template-stream#files) streams a template to a
|
||||||
response.
|
response.
|
||||||
- [**`9-error`**](../9-error#folders-and-files) sets up a central error template. The
|
- [**`9-error`**](../9-error#files) sets up a central error template. The
|
||||||
example is in OCaml syntax.
|
example is in OCaml syntax.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -76,7 +76,7 @@ Error: Unbound value html
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-tyxml`**](../w-tyxml#folders-and-files) for an introduction to TyXML.
|
- [**`w-tyxml`**](../w-tyxml#files) for an introduction to TyXML.
|
||||||
- [**`7-template`**](../7-template#security) section *Security* on output
|
- [**`7-template`**](../7-template#security) section *Security* on output
|
||||||
security. TyXML escapes strings by default, just as the built-in templater
|
security. TyXML escapes strings by default, just as the built-in templater
|
||||||
does.
|
does.
|
||||||
|
@ -45,7 +45,7 @@ scheme, rather than `ws://`, on the client.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**k-websocket**](../k-websocket#folders-and-files) for an introduction to WebSockets.
|
- [**k-websocket**](../k-websocket#files) for an introduction to WebSockets.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
# `w-dream-html`
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
[Dream-html](https://github.com/yawaramin/dream-html) can be used with Dream for
|
|
||||||
generating HTML. Dream-html is a library that offers functions for generating
|
|
||||||
HTML, SVG, and MathML, as well as out-of-the-box support for
|
|
||||||
[htmx](https://htmx.org/) attributes. It is closely integrated with Dream for
|
|
||||||
convenience.
|
|
||||||
|
|
||||||
```ocaml
|
|
||||||
let greet who =
|
|
||||||
let open Dream_html in
|
|
||||||
let open HTML in
|
|
||||||
html [lang "en"] [
|
|
||||||
head [] [
|
|
||||||
title [] "Greeting";
|
|
||||||
];
|
|
||||||
comment "Embedded in the HTML";
|
|
||||||
body [] [
|
|
||||||
h1 [] [txt "Good morning, %s!" who];
|
|
||||||
];
|
|
||||||
]
|
|
||||||
|
|
||||||
let () =
|
|
||||||
Dream.run
|
|
||||||
@@ Dream.logger
|
|
||||||
@@ Dream.router [
|
|
||||||
|
|
||||||
Dream.get "/"
|
|
||||||
(fun _ -> Dream_html.respond (greet "world"));
|
|
||||||
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
<pre><code><b>$ cd example/w-dream-html</b>
|
|
||||||
<b>$ opam install --deps-only --yes .</b>
|
|
||||||
<b>$ dune exec --root . ./main.exe</b></code></pre>
|
|
||||||
|
|
||||||
Try it in the [playground](https://dream.as/w-dream-html).
|
|
||||||
|
|
||||||
Some notes:
|
|
||||||
|
|
||||||
- All text nodes and attributes are HTML-escaped by default for security, with
|
|
||||||
exceptions noted in the documentation
|
|
||||||
- All text nodes and attributes accept format strings for conveniently embedding
|
|
||||||
variables in the HTML
|
|
||||||
- Functions like `Dream_html.respond`, `Dream_html.send`, `Dream_html.csrf_tag`
|
|
||||||
provide convenient integration with Dream
|
|
||||||
- The `<!DOCTYPE html>` prefix is automatically rendered before the `<html>` tag
|
|
||||||
- The `SVG` and `MathML` modules provide their corresponding markup. The `Hx`
|
|
||||||
module provides htmx attributes.
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
**See also:**
|
|
||||||
|
|
||||||
- [**`7-template`**](../7-template#security) section *Security* on output
|
|
||||||
security. Dream-html escapes strings by default, just as the built-in templater
|
|
||||||
does.
|
|
||||||
- [**`w-tyxml`**](../w-tyxml#folders-and-files) is a similar library that also generates
|
|
||||||
HTML, with different design tradeoffs.
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
[Up to the example index](../#examples)
|
|
@ -1,3 +0,0 @@
|
|||||||
(executable
|
|
||||||
(name html)
|
|
||||||
(libraries dream-html))
|
|
@ -1 +0,0 @@
|
|||||||
(lang dune 2.0)
|
|
@ -1,23 +0,0 @@
|
|||||||
let greet who =
|
|
||||||
let open Dream_html in
|
|
||||||
let open HTML in
|
|
||||||
html [lang "en"] [
|
|
||||||
head [] [
|
|
||||||
title [] "Greeting";
|
|
||||||
];
|
|
||||||
comment "Embedded in the HTML";
|
|
||||||
body [] [
|
|
||||||
h1 [] [txt "Good morning, %s!" who];
|
|
||||||
];
|
|
||||||
]
|
|
||||||
|
|
||||||
let () =
|
|
||||||
Dream.run
|
|
||||||
@@ Dream.logger
|
|
||||||
@@ Dream.router [
|
|
||||||
|
|
||||||
Dream.get "/"
|
|
||||||
(fun _ -> Dream_html.respond (greet "world"));
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
opam-version: "2.0"
|
|
||||||
|
|
||||||
depends: [
|
|
||||||
"ocaml" {>= "4.08.0"}
|
|
||||||
"dream-html" {>= "3.3.1"}
|
|
||||||
"dune" {>= "2.0.0"}
|
|
||||||
]
|
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
@ -55,7 +55,7 @@ You can then use the `esy` command without the `npx` prefix.
|
|||||||
|
|
||||||
If you need to run multiple build steps before `dune exec`, use
|
If you need to run multiple build steps before `dune exec`, use
|
||||||
[`esy.build`](https://esy.sh/docs/en/configuration.html#esybuild). Here is an
|
[`esy.build`](https://esy.sh/docs/en/configuration.html#esybuild). Here is an
|
||||||
example from [**`w-fullstack-jsoo`**](../w-fullstack-jsoo#folders-and-files):
|
example from [**`w-fullstack-jsoo`**](../w-fullstack-jsoo#files):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"esy": {
|
"esy": {
|
||||||
@ -124,12 +124,12 @@ See the examples linked below.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-fullstack-rescript`**](../w-fullstack-rescript#folders-and-files) for full-stack
|
- [**`w-fullstack-rescript`**](../w-fullstack-rescript#files) for full-stack
|
||||||
development with ReScript.
|
development with ReScript.
|
||||||
- [**`r-fullstack-melange`**](../r-fullstack-melange#folders-and-files) for full-stack
|
- [**`r-fullstack-melange`**](../r-fullstack-melange#files) for full-stack
|
||||||
development with Melange and Reason syntax.
|
development with Melange and Reason syntax.
|
||||||
- [**`w-fswatch`**](../w-fswatch#folders-and-files) for a development watcher.
|
- [**`w-fswatch`**](../w-fswatch#files) for a development watcher.
|
||||||
- [**`w-one-binary`**](../w-one-binary#folders-and-files) for bundling assets into a
|
- [**`w-one-binary`**](../w-one-binary#files) for bundling assets into a
|
||||||
self-contained binary.
|
self-contained binary.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -107,7 +107,7 @@ blows up their original size by 4/3.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`c-cookie`**](../c-cookie#folders-and-files) shows cookie handling, the mechanism that
|
- [**`c-cookie`**](../c-cookie#files) shows cookie handling, the mechanism that
|
||||||
flash messages are implemented over.
|
flash messages are implemented over.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -70,7 +70,7 @@ Then visit [http://localhost:8080](http://localhost:8080), and you will see...
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-one-binary`**](../w-one-binary#folders-and-files) for bundling assets into a
|
- [**`w-one-binary`**](../w-one-binary#files) for bundling assets into a
|
||||||
self-contained binary.
|
self-contained binary.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -7,10 +7,3 @@ depends: [
|
|||||||
"js_of_ocaml"
|
"js_of_ocaml"
|
||||||
"js_of_ocaml-ppx"
|
"js_of_ocaml-ppx"
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -85,12 +85,12 @@ client in `./static/client.js`. The example serves the bundled client using
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-esy`**](../w-esy#folders-and-files) details the server's [esy](https://esy.sh/)
|
- [**`w-esy`**](../w-esy#files) details the server's [esy](https://esy.sh/)
|
||||||
packaging.
|
packaging.
|
||||||
- [**`w-fswatch`**](../w-fswatch#folders-and-files) sets up a primitive development watcher.
|
- [**`w-fswatch`**](../w-fswatch#files) sets up a primitive development watcher.
|
||||||
- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a
|
- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a
|
||||||
self-contained binary.
|
self-contained binary.
|
||||||
- [**`f-static`**](../r-hello#folders-and-files) presents
|
- [**`f-static`**](../r-hello#files) presents
|
||||||
[`Dream.static`](https://aantron.github.io/dream/#val-static).
|
[`Dream.static`](https://aantron.github.io/dream/#val-static).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -79,8 +79,8 @@ similar.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`i-graphql`**](../i-graphql#folders-and-files) for a basic GraphQL example.
|
- [**`i-graphql`**](../i-graphql#files) for a basic GraphQL example.
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) for direct WebSocket usage.
|
- [**`k-websocket`**](../k-websocket#files) for direct WebSocket usage.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -50,7 +50,7 @@ Good morning, world! Random tag: jRak
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
This example plays very well with [**`w-watch`**](../w-watch#folders-and-files), which shows
|
This example plays very well with [**`w-watch`**](../w-watch#files), which shows
|
||||||
how to rebuild and restart a development server every time sources are modified
|
how to rebuild and restart a development server every time sources are modified
|
||||||
in the file system. Combining the two examples, it is possible to propagate
|
in the file system. Combining the two examples, it is possible to propagate
|
||||||
reloading all the way to the client, whenever any of the server's source code
|
reloading all the way to the client, whenever any of the server's source code
|
||||||
@ -60,8 +60,8 @@ changes.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) introduces WebSockets.
|
- [**`k-websocket`**](../k-websocket#files) introduces WebSockets.
|
||||||
- [**`w-watch`**](../w-watch#folders-and-files) rebuilds and restarts a server each
|
- [**`w-watch`**](../w-watch#files) rebuilds and restarts a server each
|
||||||
time its source code changes.
|
time its source code changes.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
*Long polling* is a technique, largely made obsolete by
|
*Long polling* is a technique, largely made obsolete by
|
||||||
[WebSockets](../k-websocket#folders-and-files), where a client sends a request, but the
|
[WebSockets](../k-websocket#files), where a client sends a request, but the
|
||||||
server does not respond until some data is available. This delayed response
|
server does not respond until some data is available. This delayed response
|
||||||
works as a sort of “push” from the client's point of view, because it comes at
|
works as a sort of “push” from the client's point of view, because it comes at
|
||||||
a time of the server's choosing.
|
a time of the server's choosing.
|
||||||
@ -46,7 +46,7 @@ polling.”
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) for a more modern way of achieving
|
- [**`k-websocket`**](../k-websocket#files) for a more modern way of achieving
|
||||||
asynchronous client-server communication.
|
asynchronous client-server communication.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -45,7 +45,7 @@ end
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
It's the basic example [**`2-middleware`**](../2-middleware#folders-and-files) adapted to
|
It's the basic example [**`2-middleware`**](../2-middleware#files) adapted to
|
||||||
Mirage. To build and run, do
|
Mirage. To build and run, do
|
||||||
|
|
||||||
<pre><code><b>$ cd example/w-mirage</b>
|
<pre><code><b>$ cd example/w-mirage</b>
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
# `w-mlx`
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
[mlx](https://github.com/ocaml-mlx/mlx), an OCaml syntax dialect which adds JSX
|
|
||||||
expressions, can be used with Dream for generating HTML.
|
|
||||||
|
|
||||||
```ocaml
|
|
||||||
let greet ~who () =
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>"Greeting"</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>"Good morning, " (JSX.string who) "!"</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
let () =
|
|
||||||
Dream.run
|
|
||||||
@@ Dream.logger
|
|
||||||
@@ Dream.router [
|
|
||||||
Dream.get "/" (fun _ ->
|
|
||||||
let html = JSX.render <greet who="world" /> in
|
|
||||||
Dream.html html)
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
<pre><code><b>$ cd example/w-mlx</b>
|
|
||||||
<b>$ opam install --deps-only --yes .</b>
|
|
||||||
<b>$ dune exec --root . ./mlx.exe</b></code></pre>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
[Up to the example index](../#examples)
|
|
@ -1,4 +0,0 @@
|
|||||||
(executable
|
|
||||||
(name mlx)
|
|
||||||
(libraries dream html_of_jsx)
|
|
||||||
(preprocess (pps html_of_jsx.ppx)))
|
|
@ -1,10 +0,0 @@
|
|||||||
(lang dune 3.16)
|
|
||||||
|
|
||||||
(dialect
|
|
||||||
(name mlx)
|
|
||||||
(implementation
|
|
||||||
(merlin_reader mlx)
|
|
||||||
(extension mlx)
|
|
||||||
(preprocess
|
|
||||||
(run mlx-pp %{input-file}))))
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
let greet ~who () =
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>"Greeting"</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>"Good morning, " (JSX.string who) "!"</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
let () =
|
|
||||||
Dream.run
|
|
||||||
@@ Dream.logger
|
|
||||||
@@ Dream.router [
|
|
||||||
Dream.get "/" (fun _ ->
|
|
||||||
let html = JSX.render <greet who="world" /> in
|
|
||||||
Dream.html html)
|
|
||||||
]
|
|
@ -1,16 +0,0 @@
|
|||||||
opam-version: "2.0"
|
|
||||||
|
|
||||||
depends: [
|
|
||||||
"ocaml" {>= "4.08.0"}
|
|
||||||
"dream"
|
|
||||||
"dune" {>= "3.16.0"}
|
|
||||||
"mlx"
|
|
||||||
"html_of_jsx"
|
|
||||||
]
|
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
@ -55,8 +55,8 @@ curl -F 'a=b' http://localhost:8080/
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`g-upload`**](../g-upload#folders-and-files) is the proper file upload example.
|
- [**`g-upload`**](../g-upload#files) is the proper file upload example.
|
||||||
- [**`6-echo`**](../6-echo#folders-and-files) is a proper echo example :)
|
- [**`6-echo`**](../6-echo#files) is a proper echo example :)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -150,11 +150,11 @@ docker-compose logs web -f
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`f-static`**](../f-static#folders-and-files) has Dream serve static files on its own,
|
- [**`f-static`**](../f-static#files) has Dream serve static files on its own,
|
||||||
without a reverse proxy.
|
without a reverse proxy.
|
||||||
- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) deploys to Digital Ocean with
|
- [**`z-docker-esy`**](../z-docker-esy#files) deploys to Digital Ocean with
|
||||||
Docker Compose and esy, including Docker installation instructions.
|
Docker Compose and esy, including Docker installation instructions.
|
||||||
- [**`z-docker-opam`**](../z-docker-opam#folders-and-files) deploys with Docker Compose and
|
- [**`z-docker-opam`**](../z-docker-opam#files) deploys with Docker Compose and
|
||||||
opam.
|
opam.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -111,10 +111,10 @@ To add more files, just add them to the `assets/` directory and re-run
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`w-esy`**](../w-esy#folders-and-files) for details on packaging with esy.
|
- [**`w-esy`**](../w-esy#files) for details on packaging with esy.
|
||||||
- [**`w-watch`**](../w-watch#folders-and-files) for a primitive watcher, which can be
|
- [**`w-watch`**](../w-watch#files) for a primitive watcher, which can be
|
||||||
extended to watch `assets/`.
|
extended to watch `assets/`.
|
||||||
- [**`f-static`**](../f-static#folders-and-files) shows the basics of
|
- [**`f-static`**](../f-static#files) shows the basics of
|
||||||
[`Dream.static`](https://aantron.github.io/dream/#val-static).
|
[`Dream.static`](https://aantron.github.io/dream/#val-static).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -6,10 +6,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -9,7 +9,7 @@ Web server with a PostgreSQL database.
|
|||||||
|
|
||||||
The
|
The
|
||||||
[code](https://github.com/aantron/dream/blob/master/example/w-postgres/postgres.eml.ml)
|
[code](https://github.com/aantron/dream/blob/master/example/w-postgres/postgres.eml.ml)
|
||||||
is almost identical to [**`h-sql`**](../h-sql#folders-and-files). The only differences are:
|
is almost identical to [**`h-sql`**](../h-sql#files). The only differences are:
|
||||||
|
|
||||||
- we now listen on `"0.0.0.0"`, since our client will definitely be outside the
|
- we now listen on `"0.0.0.0"`, since our client will definitely be outside the
|
||||||
Docker container, so not on `localhost`, and
|
Docker container, so not on `localhost`, and
|
||||||
@ -108,11 +108,11 @@ Tips:
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`h-sql`**](../h-sql#folders-and-files) is the SQLite, non-Docker version of this
|
- [**`h-sql`**](../h-sql#files) is the SQLite, non-Docker version of this
|
||||||
example.
|
example.
|
||||||
- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) deploys to Digital Ocean with
|
- [**`z-docker-esy`**](../z-docker-esy#files) deploys to Digital Ocean with
|
||||||
Docker Compose and esy, including Docker installation instructions.
|
Docker Compose and esy, including Docker installation instructions.
|
||||||
- [**`z-docker-opam`**](../z-docker-opam#folders-and-files) deploys with Docker Compose and
|
- [**`z-docker-opam`**](../z-docker-opam#files) deploys with Docker Compose and
|
||||||
opam.
|
opam.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -6,10 +6,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
@ -42,9 +42,9 @@ interface to server-sent events.
|
|||||||
|
|
||||||
**See also:**
|
**See also:**
|
||||||
|
|
||||||
- [**`k-websocket`**](../k-websocket#folders-and-files) for WebSockets, which largely
|
- [**`k-websocket`**](../k-websocket#files) for WebSockets, which largely
|
||||||
supersede server-sent events.
|
supersede server-sent events.
|
||||||
- [**`w-template-stream`**](../w-template-stream#folders-and-files) for another example of
|
- [**`w-template-stream`**](../w-template-stream#files) for another example of
|
||||||
“real-time” streaming with
|
“real-time” streaming with
|
||||||
[`Dream.flush`](https://aantron.github.io/dream/#val-flush).
|
[`Dream.flush`](https://aantron.github.io/dream/#val-flush).
|
||||||
|
|
||||||
|
@ -5,10 +5,3 @@ depends: [
|
|||||||
"dream"
|
"dream"
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
]
|
]
|
||||||
|
|
||||||
synopsis: "One of the Dream examples"
|
|
||||||
homepage: "https://github.com/aantron/dream"
|
|
||||||
bug-reports: "https://github.com/aantron/dream/issues"
|
|
||||||
author: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
license: "MIT"
|
|
||||||
maintainer: "Anton Bachin <antonbachin@yahoo.com>"
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user