From e71c7aed2faad2628f7b48c4d720e4e3668c5584 Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Tue, 28 May 2024 12:34:00 +0300 Subject: [PATCH] Remove references to playground and dream.as Maintaining dream.as has become a time sink and it is often down. This is likely due to an upstream issue in the HTTP stack, which might be replaced soon anyway. For now, it is best not to try to run the playground. Closes #123. Closes #222. --- .github/workflows/docker-esy.yml | 10 ++-- .github/workflows/docker-opam.yml | 10 ++-- .github/workflows/systemd.yml | 10 ++-- README.md | 13 ++--- docs/web/templates/index.html | 5 -- example/1-hello/README.md | 3 +- example/2-middleware/README.md | 3 +- example/3-router/README.md | 4 +- example/4-counter/README.md | 3 +- example/5-promise/README.md | 2 - example/6-echo/README.md | 2 - example/7-template/README.md | 6 +-- example/8-debug/README.md | 9 ++-- example/9-error/README.md | 2 - example/a-log/README.md | 3 +- example/b-session/README.md | 4 +- example/c-cookie/README.md | 7 ++- example/d-form/README.md | 2 - example/e-json/README.md | 2 - example/g-upload/README.md | 3 +- example/h-sql/README.md | 4 +- example/i-graphql/README.md | 4 +- example/j-stream/README.md | 2 - example/k-websocket/README.md | 4 +- example/r-graphql/README.md | 4 +- example/r-hello/README.md | 5 +- example/r-template-logic/README.md | 2 - example/r-template-stream/README.md | 3 +- example/r-template/README.md | 2 - example/r-tyxml/README.md | 5 +- example/w-chat/README.md | 5 +- example/w-content-security-policy/README.md | 7 ++- example/w-flash/README.md | 2 +- example/w-graphql-subscription/README.md | 3 +- example/w-long-polling/README.md | 2 - example/w-multipart-dump/README.md | 3 +- example/w-query/README.md | 5 +- example/w-server-sent-events/README.md | 5 +- example/w-template-logic/README.md | 2 - example/w-template-stream/README.md | 2 - example/w-tyxml/README.md | 2 - example/w-upload-stream/README.md | 2 - example/z-docker-esy/README.md | 9 +--- example/z-docker-opam/README.md | 5 -- example/z-systemd/README.md | 17 ++---- src/dream.mli | 57 ++++++++++----------- 46 files changed, 91 insertions(+), 175 deletions(-) diff --git a/.github/workflows/docker-esy.yml b/.github/workflows/docker-esy.yml index d62496ca..92febd04 100644 --- a/.github/workflows/docker-esy.yml +++ b/.github/workflows/docker-esy.yml @@ -1,9 +1,9 @@ name: docker-esy -on: - push: - paths: - - 'example/z-docker-esy/**' - - .github/workflows/docker-esy.yml +# on: +# push: +# paths: +# - 'example/z-docker-esy/**' +# - .github/workflows/docker-esy.yml jobs: deploy: diff --git a/.github/workflows/docker-opam.yml b/.github/workflows/docker-opam.yml index 7b290044..71605804 100644 --- a/.github/workflows/docker-opam.yml +++ b/.github/workflows/docker-opam.yml @@ -1,9 +1,9 @@ name: docker-opam -on: - push: - paths: - - 'example/z-docker-opam/**' - - .github/workflows/docker-opam.yml +# on: +# push: +# paths: +# - 'example/z-docker-opam/**' +# - .github/workflows/docker-opam.yml jobs: deploy: diff --git a/.github/workflows/systemd.yml b/.github/workflows/systemd.yml index 6c8c1e99..2821c388 100644 --- a/.github/workflows/systemd.yml +++ b/.github/workflows/systemd.yml @@ -1,9 +1,9 @@ name: systemd -on: - push: - paths: - - 'example/z-systemd/**' - - .github/workflows/systemd.yml +# on: +# push: +# paths: +# - 'example/z-systemd/**' +# - .github/workflows/systemd.yml jobs: deploy: diff --git a/README.md b/README.md index 6b223ef5..2b05ce9c 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ Easy-to-use, feature-complete Web framework without boilerplate.

Quick Start | - Playground | Tutorial | Reference @@ -110,16 +109,12 @@ into. ## Quick start -Visit one of the first tutorials in the [online -playground][2-middleware-playground], and read its -[docs](https://github.com/aantron/dream/tree/master/example/2-middleware#files). -You can get and build it locally with: +You can get +[one](https://github.com/aantron/dream/tree/master/example/2-middleware#files) +of the first [tutorials][tutorial] and build it locally with:

bash -c "$(curl -fsSL https://raw.githubusercontent.com/aantron/dream/master/example/quickstart.sh)"
-Most of the other [examples][tutorial] are also loaded in the playground. See -the links on its [home page][playground]. - ### opam Create a project directory with an optional local switch: @@ -148,8 +143,6 @@ dune exec ./middleware.exe [quickstart.sh]: https://github.com/aantron/dream/blob/master/example/quickstart.sh [esy]: https://esy.sh/ [2-middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#files -[playground]: http://dream.as -[2-middleware-playground]: http://dream.as/2-middleware ## esy diff --git a/docs/web/templates/index.html b/docs/web/templates/index.html index 61784f2d..835c9807 100644 --- a/docs/web/templates/index.html +++ b/docs/web/templates/index.html @@ -130,11 +130,6 @@
Tidy Web framework for OCaml and ReasonML
Many Examples, covering all kinds of scenarios. -
  • - An online - Playground, where you can try Dream without installing - anything! -
  • diff --git a/example/1-hello/README.md b/example/1-hello/README.md index 23beadbf..a4ec7e0e 100644 --- a/example/1-hello/README.md +++ b/example/1-hello/README.md @@ -24,8 +24,7 @@ browser. Your terminal probably makes the link clickable. If you go to [http://localhost:8080](http://localhost:8080), you will, of -course, see `Good morning, world!`. You can also try it in the [Dream -Playground](http://dream.as/1-hello). +course, see `Good morning, world!`.
    diff --git a/example/2-middleware/README.md b/example/2-middleware/README.md index f542724d..c1798036 100644 --- a/example/2-middleware/README.md +++ b/example/2-middleware/README.md @@ -33,8 +33,7 @@ let () =
    When you run this server and visit -[http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/2-middleware)], you get much more interesting +[http://localhost:8080](http://localhost:8080), you get much more interesting (and colorful!) output: ![Dream log example](https://raw.githubusercontent.com/aantron/dream/master/docs/asset/log-sanitized.png) diff --git a/example/3-router/README.md b/example/3-router/README.md index 79b17483..9ed8d909 100644 --- a/example/3-router/README.md +++ b/example/3-router/README.md @@ -32,9 +32,7 @@ let () =
    This is also our first dynamic site! A request to `/echo/foo` gets the response -`foo`, and a request to `/echo/bar` gets `bar`! Try it in the -[playground](http://dream.as/3-router/echo/foo) — once the server loads, -edit the URL in the right pane to visit `/echo/bar`. +`foo`, and a request to `/echo/bar` gets `bar`! The syntax `:word` in a route creates a path parameter, which can be read with [`Dream.param`](https://aantron.github.io/dream/#val-param). diff --git a/example/4-counter/README.md b/example/4-counter/README.md index 160e2af2..0d05a4a8 100644 --- a/example/4-counter/README.md +++ b/example/4-counter/README.md @@ -4,8 +4,7 @@ This example shows how easy it is to define a custom middleware, `count_requests`. It exposes the request count at -[http://localhost:8080/](http://localhost:8080/) -[[playground](http://dream.as/4-counter)], in a sort of dashboard: +[http://localhost:8080/](http://localhost:8080/), in a sort of dashboard: ```ocaml let count = ref 0 diff --git a/example/5-promise/README.md b/example/5-promise/README.md index c5c92def..5702d85d 100644 --- a/example/5-promise/README.md +++ b/example/5-promise/README.md @@ -44,8 +44,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./promise.exe -Try it in the [playground](http://dream.as/5-promise). -
    As you can see, the diff --git a/example/6-echo/README.md b/example/6-echo/README.md index 020bb348..0aa1c2b7 100644 --- a/example/6-echo/README.md +++ b/example/6-echo/README.md @@ -24,8 +24,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./echo.exe -...or run it in the [playground](http://dream.as/6-echo). -
    You can test it with curl: diff --git a/example/7-template/README.md b/example/7-template/README.md index 8074baea..a7a13a38 100644 --- a/example/7-template/README.md +++ b/example/7-template/README.md @@ -84,15 +84,11 @@ already escaped, or if it is safe for some other reason. But be careful! To show the danger, let's launch a **script injection (XSS) attack** against this tiny Web app! First, go to [`template.eml.ml`](https://github.com/aantron/dream/blob/master/example/7-template/template.eml.ml#L4), -change the substitution to `<%s! param %>`, and restart the app. You can also -make the edit in the [playground](http://dream.as/7-template/foo). Then, -visit +change the substitution to `<%s! param %>`, and restart the app. Then, visit this highly questionable URL: [http://localhost:8080/%3Cscript%3Ealert(%22Impossible!%22)%3C%2Fscript%3E](http://localhost:8080/%3Cscript%3Ealert(%22Impossible!%22)%3C%2Fscript%3E) -If you are using the playground, change the host and port accordingly. - This URL will cause our Web app to display an alert box, which we, as the developers, did not intend! diff --git a/example/8-debug/README.md b/example/8-debug/README.md index c0a7c7f5..1f590829 100644 --- a/example/8-debug/README.md +++ b/example/8-debug/README.md @@ -30,11 +30,10 @@ let () = The rest of the app just adds two routes for triggering two kinds of failures that the debugger will detail. Visit -[http://localhost:8080/bad](http://localhost:8080/bad) -[[playground](http://dream.as/8-debug/bad)] to trigger a `400 Bad Request` -response, and [http://localhost:8080/fail](http://localhost:8080/fail) -[[playground](http://dream.as/8-debug/fail)] to trigger an exception. The -debugger will show reports like this: +[http://localhost:8080/bad](http://localhost:8080/bad) to trigger a +`400 Bad Request` response, and +[http://localhost:8080/fail](http://localhost:8080/fail) to trigger an +exception. The debugger will show reports like this: ``` Failure("The Web app failed!") diff --git a/example/9-error/README.md b/example/9-error/README.md index c578b44b..efcd2e05 100644 --- a/example/9-error/README.md +++ b/example/9-error/README.md @@ -36,8 +36,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./error.exe -Try it in the [playground](http://dream.as/9-error). -
    We kept the error template simple for the sake of the example, but this is diff --git a/example/a-log/README.md b/example/a-log/README.md index 9c68e5ef..4489644a 100644 --- a/example/a-log/README.md +++ b/example/a-log/README.md @@ -30,8 +30,7 @@ let () =
    -If you visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/a-log)] and then +If you visit [http://localhost:8080](http://localhost:8080) and then [http://localhost:8080/fail](http://localhost:8080/fail), you will find these messages in the log, between the others: diff --git a/example/b-session/README.md b/example/b-session/README.md index b41abcfe..1e2c19ab 100644 --- a/example/b-session/README.md +++ b/example/b-session/README.md @@ -28,8 +28,8 @@ let () =
    -The first time you access the app [[playground](http://dream.as/b-session)], it -“logs you in” by saving you user name in a session. The session manager, +The first time you access the app, it “logs you in” by saving you user name in +a session. The session manager, [`Dream.memory_sessions`](https://aantron.github.io/dream/#val-memory_sessions), a middleware, adds a `dream.session` cookie to the response, containing the session key. The next time you access the app, the session is looked up again diff --git a/example/c-cookie/README.md b/example/c-cookie/README.md index 4ab14d33..a6da2090 100644 --- a/example/c-cookie/README.md +++ b/example/c-cookie/README.md @@ -29,10 +29,9 @@ let () =
    -The first time you access this app [[playground](http://dream.as/c-cookie)], it -sets up a language preference, `ut-OP`. This string is sent to the client in a -`ui.language` cookie. On the next request, the client sends it back. The app -retrieves and displays it. +The first time you access this app, it sets up a language preference, `ut-OP`. +This string is sent to the client in a `ui.language` cookie. On the next +request, the client sends it back. The app retrieves and displays it.
    diff --git a/example/d-form/README.md b/example/d-form/README.md index d3a8ca65..e5564d89 100644 --- a/example/d-form/README.md +++ b/example/d-form/README.md @@ -49,8 +49,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./form.exe -Try it in the [playground](http://dream.as/d-form). -
    The template adds a CSRF token to the form using diff --git a/example/e-json/README.md b/example/e-json/README.md index c928a703..b770b21d 100644 --- a/example/e-json/README.md +++ b/example/e-json/README.md @@ -65,8 +65,6 @@ The build commands, as always, are: $ opam install --deps-only --yes . $ dune exec --root . ./json.exe -You can try this example in the [playground](http://dream.as/e-json). -
    This example expects JSON of the form `{"message": "some-message"}`. Let's test diff --git a/example/g-upload/README.md b/example/g-upload/README.md index e2cf8b5a..0f7c4735 100644 --- a/example/g-upload/README.md +++ b/example/g-upload/README.md @@ -56,8 +56,7 @@ let () =
    -The page shown after uploading looks like this -[[playground](http://dream.as/g-upload)]: +The page shown after uploading looks like this: ``` foo.png, 663959 bytes diff --git a/example/h-sql/README.md b/example/h-sql/README.md index 0fda8e87..1739535c 100644 --- a/example/h-sql/README.md +++ b/example/h-sql/README.md @@ -72,8 +72,8 @@ let () =
    -Try visiting [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/h-sql)] and leaving some comments! +Try visiting [http://localhost:8080](http://localhost:8080) and leaving some +comments! ![Comments](https://raw.githubusercontent.com/aantron/dream/master/docs/asset/sql.png) diff --git a/example/i-graphql/README.md b/example/i-graphql/README.md index a6e746ac..6028578f 100644 --- a/example/i-graphql/README.md +++ b/example/i-graphql/README.md @@ -63,8 +63,8 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/i-graphql)], and you can interact with the schema: +Visit [http://localhost:8080](http://localhost:8080), and you can interact with +the schema: ![GraphiQL](https://raw.githubusercontent.com/aantron/dream/master/docs/asset/graphiql.png) diff --git a/example/j-stream/README.md b/example/j-stream/README.md index 21c62a03..cb5afc02 100644 --- a/example/j-stream/README.md +++ b/example/j-stream/README.md @@ -36,8 +36,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./stream.exe -Try running it in the [playground](http://dream.as/j-stream). -
    You can test it by running diff --git a/example/k-websocket/README.md b/example/k-websocket/README.md index 1c9e4da8..be0e3b63 100644 --- a/example/k-websocket/README.md +++ b/example/k-websocket/README.md @@ -54,8 +54,8 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/k-websocket)] to get the whole exchange started! +Visit [http://localhost:8080](http://localhost:8080) to get the whole exchange +started! ![WebSocket alert](https://raw.githubusercontent.com/aantron/dream/master/docs/asset/websocket.png) diff --git a/example/r-graphql/README.md b/example/r-graphql/README.md index 9f8e41b9..f9006759 100644 --- a/example/r-graphql/README.md +++ b/example/r-graphql/README.md @@ -74,8 +74,8 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/r-graphql)], and you can interact with the schema: +Visit [http://localhost:8080](http://localhost:8080), and you can interact with +the schema: ![GraphiQL](https://raw.githubusercontent.com/aantron/dream/master/docs/asset/graphiql.png) diff --git a/example/r-hello/README.md b/example/r-hello/README.md index be449bc3..a5d827fb 100644 --- a/example/r-hello/README.md +++ b/example/r-hello/README.md @@ -19,9 +19,8 @@ let () =
    -After starting it, visit [http://localhost:8080](http://localhost:8080), or use -the [playground](http://dream.as/r-hello), and it will respond with its friendly -greeting! +After starting it, visit [http://localhost:8080](http://localhost:8080), and it +will respond with its friendly greeting!
    diff --git a/example/r-template-logic/README.md b/example/r-template-logic/README.md index 12797069..38119b17 100644 --- a/example/r-template-logic/README.md +++ b/example/r-template-logic/README.md @@ -70,8 +70,6 @@ let () = $ npm install esy && npx esy $ npx esy start -Try it in the [playground](http://dream.as/r-template-logic). -
    **See also:** diff --git a/example/r-template-stream/README.md b/example/r-template-stream/README.md index 7fa8fd19..f7607c26 100644 --- a/example/r-template-stream/README.md +++ b/example/r-template-stream/README.md @@ -35,8 +35,7 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/r-template-stream)] to see it in action. +Visit [http://localhost:8080](http://localhost:8080) to see it in action. The important differences with regular usage of templates are: diff --git a/example/r-template/README.md b/example/r-template/README.md index 19208090..570332cd 100644 --- a/example/r-template/README.md +++ b/example/r-template/README.md @@ -30,8 +30,6 @@ let () = $ npm install esy && npx esy $ npx esy start -Try it in the [playground](http://dream.as/r-template). -
    To use the templater, we need to add a stanza to our diff --git a/example/r-tyxml/README.md b/example/r-tyxml/README.md index 26a6d273..3a20ee45 100644 --- a/example/r-tyxml/README.md +++ b/example/r-tyxml/README.md @@ -2,9 +2,8 @@
    -[TyXML](https://github.com/ocsigen/tyxml) can be used -[[playground](http://dream.as/r-tyxml)] together with Reason's built-in JSX -syntax for generating HTML on the server: +[TyXML](https://github.com/ocsigen/tyxml) can be used together with Reason's +built-in JSX syntax for generating HTML on the server: ```reason open Tyxml diff --git a/example/w-chat/README.md b/example/w-chat/README.md index 9e61ce56..c24db67f 100644 --- a/example/w-chat/README.md +++ b/example/w-chat/README.md @@ -34,10 +34,7 @@ The rest of the code hooks up the client's message form to the WebSocket.
    Open [http://localhost:8080](http://localhost:8080) in two tabs to get the -whole exchange started! You can also try it in the -[playground](http://dream.as/w-chat). To connect a second tab, copy out the -address from the playground's location bar, and paste it into a new tab in your -browser. +whole exchange started!
    diff --git a/example/w-content-security-policy/README.md b/example/w-content-security-policy/README.md index 740abcb6..e87e33e0 100644 --- a/example/w-content-security-policy/README.md +++ b/example/w-content-security-policy/README.md @@ -49,10 +49,9 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/w-content-security-policy)], and your browser -should refuse to show `/nested` inside the frame on the home page. In addition, -the server log will show something like +Visit [http://localhost:8080](http://localhost:8080), and your browser should +refuse to show `/nested` inside the frame on the home page. In addition, the +server log will show something like ``` 09.06.21 09:54:35.971 ERROR REQ 3 { diff --git a/example/w-flash/README.md b/example/w-flash/README.md index 78fe40bf..d5f10d0f 100644 --- a/example/w-flash/README.md +++ b/example/w-flash/README.md @@ -94,7 +94,7 @@ request, like this:
    After starting the server, visit [http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/w-flash)] to start this little interaction! +to start this little interaction!
    diff --git a/example/w-graphql-subscription/README.md b/example/w-graphql-subscription/README.md index c423f611..8a9c2525 100644 --- a/example/w-graphql-subscription/README.md +++ b/example/w-graphql-subscription/README.md @@ -56,8 +56,7 @@ let () =
    -Visit [http://localhost:8080](http://localhost:8080) or the -[playground](http://dream.as/w-graphql-subscription), and run +Visit [http://localhost:8080](http://localhost:8080), and run ```graphql subscription { diff --git a/example/w-long-polling/README.md b/example/w-long-polling/README.md index c4e8a2d8..6120adf2 100644 --- a/example/w-long-polling/README.md +++ b/example/w-long-polling/README.md @@ -42,8 +42,6 @@ the client immediately. If a client sends the next request before any more messages are generated, the server waits to respond — hence, “long polling.” -Try it in the [playground](http://dream.as/w-long-polling). -
    **See also:** diff --git a/example/w-multipart-dump/README.md b/example/w-multipart-dump/README.md index 8dbe6dc1..ec7c4ce6 100644 --- a/example/w-multipart-dump/README.md +++ b/example/w-multipart-dump/README.md @@ -3,8 +3,7 @@
    This app serves a file upload form at -[http://localhost:8080](http://localhost:8080) -[[playground](http://dream.as/w-multipart-dump)]. When the form is submitted, it +[http://localhost:8080](http://localhost:8080). When the form is submitted, it echoes the POST request's body back to the client. It is useful for inspecting the `multipart/form-data` bodies generated by browsers and other clients. Typical output looks like this: diff --git a/example/w-query/README.md b/example/w-query/README.md index b2a303e5..4d6ddb46 100644 --- a/example/w-query/README.md +++ b/example/w-query/README.md @@ -22,9 +22,8 @@ let () =
    Visit [http://localhost:8080?echo=foo](http://localhost:8080?echo=foo) -[[playground](http://dream.as/w-query?echo=foo)] and you will see `foo` -printed! Since we are inserting untrusted client-sent data into an HTML -response, we have to escape it with +and you will see `foo` printed! Since we are inserting untrusted client-sent +data into an HTML response, we have to escape it with [`Dream.html_escape`](https://aantron.github.io/dream/#val-html_escape). See *Security* in example [**`7-template`**](../7-template#security) for a discussion. Perhaps you can even launch an XSS attack against an unsafe version diff --git a/example/w-server-sent-events/README.md b/example/w-server-sent-events/README.md index 6d0a1dd7..7c1624c9 100644 --- a/example/w-server-sent-events/README.md +++ b/example/w-server-sent-events/README.md @@ -27,9 +27,8 @@ let rec message_loop () =
    When a client connects to the example's server-sent events endpoint at -[http://localhost:8080/push](http://localhost:8080/push) -[[playground](http://dream.as/w-server-sent-events)], the server first sends any -messages that have already accumulated, and then gradually +[http://localhost:8080/push](http://localhost:8080/push), the server first +sends any messages that have already accumulated, and then gradually [streams](https://aantron.github.io/dream/#streaming) more messages as they are created. diff --git a/example/w-template-logic/README.md b/example/w-template-logic/README.md index d7210401..bcc1d053 100644 --- a/example/w-template-logic/README.md +++ b/example/w-template-logic/README.md @@ -71,8 +71,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./template.exe -Try it in the [playground](http://dream.as/w-template-logic). -
    **See also:** diff --git a/example/w-template-stream/README.md b/example/w-template-stream/README.md index a1db0694..95557cf1 100644 --- a/example/w-template-stream/README.md +++ b/example/w-template-stream/README.md @@ -32,8 +32,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./template_stream.exe -Try it in the [playground](http://dream.as/w-template-stream). -
    Most uses of streaming don't need diff --git a/example/w-tyxml/README.md b/example/w-tyxml/README.md index b1816381..4ddffc46 100644 --- a/example/w-tyxml/README.md +++ b/example/w-tyxml/README.md @@ -37,8 +37,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./tyxml.exe -Try it in the [playground](http://dream.as/w-tyxml). -
    ## JSX diff --git a/example/w-upload-stream/README.md b/example/w-upload-stream/README.md index 12173755..5287d042 100644 --- a/example/w-upload-stream/README.md +++ b/example/w-upload-stream/README.md @@ -63,8 +63,6 @@ let () = $ opam install --deps-only --yes . $ dune exec --root . ./upload_stream.exe -Try it in the [playground](http://dream.as/w-upload-stream). -
    ## Security diff --git a/example/z-docker-esy/README.md b/example/z-docker-esy/README.md index 44a2aac6..508771a7 100644 --- a/example/z-docker-esy/README.md +++ b/example/z-docker-esy/README.md @@ -32,9 +32,6 @@ services: driver: ${LOGGING_DRIVER:-json-file} ``` -The example app is running live at -[http://docker-esy.dream.as](http://docker-esy.dream.as). - The setup can be run locally or on any server provider. We will use a [Digital Ocean](https://digitalocean.com) "droplet" (virtual machine). The server binary is built by Docker. @@ -151,10 +148,8 @@ $ ssh build@my-droplet "journalctl -f" ## Automation -The Dream repo has a -[GitHub action](https://github.com/aantron/dream/blob/master/.github/workflows/docker-esy.yml) -that deploys this example to [docker-esy.dream.as](http://docker-esy.dream.as) -on every push. It runs the [two commands](#deploy) above. +The app can be deployed on every push by running the [two commands](#deploy) +above in GitHub Actions. The action needs SSH access to the droplet. See [*Automation*](../z-systemd#automation) in diff --git a/example/z-docker-opam/README.md b/example/z-docker-opam/README.md index 7912702e..9c9e1130 100644 --- a/example/z-docker-opam/README.md +++ b/example/z-docker-opam/README.md @@ -13,11 +13,6 @@ which, in this example, derives an image from one of the [opam base images](https://hub.docker.com/r/ocaml/opam), and installs dependencies using opam. The initial build requires at least 2 GB of memory. -The example is live at -[http://docker-opam.dream.as](http://docker-opam.dream.as), and is deployed -there automatically, on push, by a -[GitHub action](https://github.com/aantron/dream/blob/master/.github/workflows/docker-opam.yml). -
    [Up to the example index](../#deploying) diff --git a/example/z-systemd/README.md b/example/z-systemd/README.md index e1d428c2..75ef1613 100644 --- a/example/z-systemd/README.md +++ b/example/z-systemd/README.md @@ -36,10 +36,6 @@ let () = ] ``` -It is live at [http://systemd.dream.as](http://systemd.dream.as). As a second -example, the [playground](http://dream.as) is deployed as a [systemd -service](https://github.com/aantron/dream/blob/master/example/z-playground/server/playground.service). - The service can be hosted on any server provider. We will use [Digital Ocean](https://www.digitalocean.com) in this example. We will run the build remotely, taking advantage of the remote filesystem as a build cache. If you @@ -48,8 +44,7 @@ binaries to the server. This will simplify the server setup slightly, as it won't need an OCaml/Reason build system. To complete the setup, we [add a CD script](#automation) at the end. It deploys -the example to [systemd.dream.as](http://systemd.dream.as) each time the code is -pushed! +the example each time the code is pushed!
    @@ -161,13 +156,9 @@ $ ssh build@my-droplet "journalctl -f" ## Automation -The Dream repo deploys this example to -[systemd.dream.as](http://systemd.dream.as) from a [GitHub -action](https://github.com/aantron/dream/blob/master/.github/workflows/systemd.yml), -which mainly just runs the [deploy steps](#deploy) above. - -The action needs SSH access to the droplet. Generate an SSH key pair without a -passphrase, and upload the public key: +The app can be deployed by a GitHub Action. The action needs SSH access to the +droplet. Generate an SSH key pair without a passphrase, and upload the public +key: ``` $ ssh-keygen -t rsa -b 4096 -f github-actions diff --git a/src/dream.mli b/src/dream.mli index 93d481c0..d92444ef 100644 --- a/src/dream.mli +++ b/src/dream.mli @@ -22,9 +22,9 @@ and response = server message and handler = request -> response promise (** Handlers are asynchronous functions from requests to responses. Example {{:https://github.com/aantron/dream/tree/master/example/1-hello#files} - [1-hello]} \[{{:http://dream.as/1-hello} playground}\] shows the simplest - handler, an anonymous function which we pass to {!Dream.run}. This creates a - complete Web server! You can also see the Reason version in example + [1-hello]} shows the simplest handler, an anonymous function which we pass + to {!Dream.run}. This creates a complete Web server! You can also see the + Reason version in example {{:https://github.com/aantron/dream/tree/master/example/r-hello#files} [r-hello]}. @@ -49,7 +49,7 @@ and middleware = handler -> handler Examples {{:https://github.com/aantron/dream/tree/master/example/4-counter#files} - [4-counter]} \[{{:http://dream.as/4-counter} playground}\] and + [4-counter]} and {{:https://github.com/aantron/dream/tree/master/example/5-promise#files} [5-promise]} show user-defined middlewares: @@ -73,8 +73,8 @@ and route (** Routes tell {!Dream.router} which handler to select for each request. See {!section-routing} and example {{:https://github.com/aantron/dream/tree/master/example/3-router#files} - [3-router]} \[{{:http://dream.as/3-router/echo/foo} playground}\]. Routes - are created by helpers such as {!Dream.get} and {!Dream.scope}: + [3-router]}. Routes are created by helpers such as {!Dream.get} and + {!Dream.scope}: {[ Dream.router [ @@ -123,7 +123,7 @@ and 'a promise = 'a Lwt.t (** Dream uses {{:https://github.com/ocsigen/lwt} Lwt} for promises and asynchronous I/O. See example {{:https://github.com/aantron/dream/tree/master/example/5-promise#files} - [5-promise]} \[{{:http://dream.as/5-promise} playground}\]. + [5-promise]}. Use [raise] to reject promises. If you are writing a library, you may prefer using @@ -525,7 +525,7 @@ val set_header : 'a message -> string -> string -> unit secure cookies. The most secure settings applicable to the current server are inferred automatically. See example {{:https://github.com/aantron/dream/tree/master/example/c-cookie#files} - [c-cookie]} \[{{:http://dream.as/c-cookie} playground}\]. + [c-cookie]}. {[ Dream.set_cookie response request "my.cookie" "foo" @@ -847,7 +847,7 @@ val websocket : returned to Dream's HTTP layer, the callback is passed a new {!type-websocket}, and the application can begin using it. See example {{:https://github.com/aantron/dream/tree/master/example/k-websocket#files} - [k-websocket]} \[{{:http://dream.as/k-websocket} playground}\]. + [k-websocket]}. {[ let my_handler = fun request -> @@ -960,7 +960,7 @@ val origin_referrer_check : middleware See example {{:https://github.com/aantron/dream/tree/master/example/d-form#files} - [d-form]} \[{{:http://dream.as/d-form} playground}\]. *) + [d-form]}. *) type 'a form_result = [ | `Ok of 'a @@ -1059,8 +1059,7 @@ type multipart_form = See example {{:https://github.com/aantron/dream/tree/master/example/g-upload#files} - [g-upload]} \[{{:http://dream.as/g-upload} playground}\] and - {{:https://datatracker.ietf.org/doc/html/rfc7578} RFC 7578}. + [g-upload]} and {{:https://datatracker.ietf.org/doc/html/rfc7578} RFC 7578}. Note that clients such as curl can send files with no filename ([None]), though most browsers seem to insert at least an empty filename ([Some ""]). @@ -1193,19 +1192,18 @@ let render message = See examples {{:https://github.com/aantron/dream/tree/master/example/7-template#files} - [7-template]} \[{{:http://dream.as/7-template} playground}\] and + [7-template]} and {{:https://github.com/aantron/dream/tree/master/example/r-template#files} - [r-template]} \[{{:http://dream.as/r-template} playground}\]. + [r-template]}. There is also a typed alternative, provided by an external library, {{:https://github.com/ocsigen/tyxml} TyXML}. It is shown in example {{:https://github.com/aantron/dream/tree/master/example/w-tyxml#files} - [w-tyxml]} \[{{:http://dream.as/w-tyxml} playground}\]. If you are using - Reason syntax, TyXML can be used with + [w-tyxml]}. If you are using Reason syntax, TyXML can be used with {{:https://ocsigen.org/tyxml/latest/manual/jsx} server-side JSX}. See example {{:https://github.com/aantron/dream/tree/master/example/r-tyxml#files} - [r-tyxml]} \[{{:http://dream.as/r-tyxml} playground}\]. + [r-tyxml]}. To use the built-in templates, add this to [dune]: @@ -1361,7 +1359,7 @@ val router : route list -> handler responds with [404 Not Found]. Route components starting with [:] are parameters, which can be retrieved with {!Dream.param}. See example {{:https://github.com/aantron/dream/tree/master/example/3-router#files} - [3-router]} \[{{:http://dream.as/3-router} playground}\]. + [3-router]}. {[ let () = @@ -1564,7 +1562,7 @@ val mime_lookup : string -> (string * string) list See example {{:https://github.com/aantron/dream/tree/master/example/b-session#files} - [b-session]} \[{{:http://dream.as/b-session} playground}\]. *) + [b-session]}. *) val session_field : request -> string -> string option (** Value from the request's session. *) @@ -1625,7 +1623,7 @@ val session_expires_at : request -> float request, to be made available for the next request. The typical use case is to provide form feedback across a redirect. See example {{:https://github.com/aantron/dream/tree/master/example/w-flash#files} - [w-flash]} \[{{:http://dream.as/w-flash} playground}\]. *) + [w-flash]}. *) val flash : middleware (** Implements storing flash messages in cookies. *) @@ -1644,12 +1642,11 @@ val add_flash_message : request -> string -> string -> unit ocaml-graphql-server}. See examples: - {{:https://github.com/aantron/dream/tree/master/example/i-graphql#files} - [i-graphql]} \[{{:http://dream.as/i-graphql} playground}\] + [i-graphql]} - {{:https://github.com/aantron/dream/tree/master/example/r-graphql#files} - [r-graphql]} \[{{:http://dream.as/r-graphql} playground}\] + [r-graphql]} - {{:https://github.com/aantron/dream/tree/master/example/w-graphql-subscription#files} - [w-graphql-subscription]} \[{{:http://dream.as/w-graphql-subscription} - playground}\]. + [w-graphql-subscription]}. If you are also {{:https://github.com/aantron/dream/tree/master/example#full-stack} writing @@ -1721,7 +1718,7 @@ val graphiql : ?default_query:string -> string -> handler {{:https://github.com/paurkedal/ocaml-caqti/#readme} Caqti}, an SQL interface with several back ends. See example {{:https://github.com/aantron/dream/tree/master/example/h-sql#files} - [h-sql]} \[{{:http://dream.as/h-sql} playground}\]. + [h-sql]}. Dream installs the core {{:https://opam.ocaml.org/packages/caqti/} [caqti]} package, but you should also install at least one of: @@ -1783,7 +1780,7 @@ val sql : request -> (Caqti_lwt.connection -> 'a promise) -> 'a promise val logger : middleware (** Logs and times requests. Time spent logging is included. See example {{:https://github.com/aantron/dream/tree/master/example/2-middleware#files} - [2-middleware]} \[{{:http://dream.as/2-middleware} playground}\]. *) + [2-middleware]}. *) val log : ('a, Format.formatter, unit, unit) format4 -> 'a (** Formats a message and logs it. Disregard the obfuscated type: the first @@ -1792,7 +1789,7 @@ val log : ('a, Format.formatter, unit, unit) format4 -> 'a {{:https://v2.ocaml.org/api/Format.html#VALfprintf} [Format]}. The rest of the arguments are determined by the format string. See example {{:https://github.com/aantron/dream/tree/master/example/a-log#files} - [a-log]} \[{{:http://dream.as/a-log} playground}\]. + [a-log]}. {[ Dream.log "Counter is now: %i" counter; @@ -2042,7 +2039,7 @@ val error_template : (error -> string -> response -> response promise) -> error_handler (** Builds an {!error_handler} from a template. See example {{:https://github.com/aantron/dream/tree/master/example/9-error#files} - [9-error]} \[{{:http://dream.as/9-error} playground}\]. + [9-error]}. {[ let my_error_handler = @@ -2126,11 +2123,11 @@ val run : - [~error_handler] handles all errors, both from the application, and low-level errors. See {!section-errors} and example {{:https://github.com/aantron/dream/tree/master/example/9-error#files} - [9-error]} \[{{:http://dream.as/9-error} playground}\]. + [9-error]}. {!Dream.debug_error_handler} is a default error handler that can be passed here to help debug Web apps. See example {{:https://github.com/aantron/dream/tree/master/example/8-debug#files} - [8-debug]} \[{{:http://dream.as/8-debug} playground}\]. + [8-debug]}. - [~tls:true] enables TLS. You should also specify [~certificate_file] and [~key_file]. However, for development, Dream includes an insecure compiled-in