diff --git a/README.md b/README.md index 2b05ce9c..efd3b9d7 100644 --- a/README.md +++ b/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 into. -[https]: https://github.com/aantron/dream/tree/master/example/l-https#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#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#files -[middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#files +[https]: https://github.com/aantron/dream/tree/master/example/l-https#folders-and-files +[websocket]: https://github.com/aantron/dream/tree/master/example/k-websocket#folders-and-files +[graphql]: https://github.com/aantron/dream/tree/master/example/w-graphql-subscription#folders-and-files +[templates]: https://github.com/aantron/dream/tree/master/example/7-template#folders-and-files +[reason-templates]: https://github.com/aantron/dream/tree/master/example/r-template#folders-and-files +[middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files [handler]: https://aantron.github.io/dream/#type-handler -[routing]: https://github.com/aantron/dream/tree/master/example/3-router#files +[routing]: https://github.com/aantron/dream/tree/master/example/3-router#folders-and-files [cookies]: https://aantron.github.io/dream/#cookies [forms]: https://aantron.github.io/dream/#forms -[sessions]: https://github.com/aantron/dream/tree/master/example/b-session#files +[sessions]: https://github.com/aantron/dream/tree/master/example/b-session#folders-and-files [back-ends]: https://aantron.github.io/dream/#back-ends -[errors]: https://github.com/aantron/dream/tree/master/example/9-error#files +[errors]: https://github.com/aantron/dream/tree/master/example/9-error#folders-and-files [crypto]: https://aantron.github.io/dream/#cryptography -[logging]: https://github.com/aantron/dream/tree/master/example/2-middleware#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#files -[jsoo]: https://github.com/aantron/dream/tree/master/example/w-fullstack-jsoo#files +[logging]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files +[melange]: https://github.com/aantron/dream/tree/master/example/r-fullstack-melange#folders-and-files +[rescript]: https://github.com/aantron/dream/tree/master/example/w-fullstack-rescript#folders-and-files +[jsoo]: https://github.com/aantron/dream/tree/master/example/w-fullstack-jsoo#folders-and-files [types]: https://aantron.github.io/dream/#types [basic-read]: https://aantron.github.io/dream/#val-body [streaming]: https://aantron.github.io/dream/#streaming @@ -102,15 +102,15 @@ into. [alpn]: https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation [libs]: https://github.com/aantron/dream/tree/master/src [deploy]: https://github.com/aantron/dream/tree/master/example#deploying -[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#files +[jsx]: https://github.com/aantron/dream/tree/master/example/r-tyxml#folders-and-files +[one-binary]: https://github.com/aantron/dream/tree/master/example/w-one-binary#folders-and-files
## Quick start You can get -[one](https://github.com/aantron/dream/tree/master/example/2-middleware#files) +[one](https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-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)"
@@ -139,10 +139,10 @@ After that, go to any of the [examples][tutorial], such as dune exec ./middleware.exe ``` -[esy-example]: https://github.com/aantron/dream/tree/master/example/w-esy#files +[esy-example]: https://github.com/aantron/dream/tree/master/example/w-esy#folders-and-files [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 +[2-middleware]: https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files ## esy @@ -173,14 +173,14 @@ esy`, and started with `npx esy start`. [tutorial]: https://github.com/aantron/dream/tree/master/example#readme [examples]: https://github.com/aantron/dream/tree/master/example#examples -[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#files +[1-hello]: https://github.com/aantron/dream/tree/master/example/1-hello#folders-and-files +[r-hello]: https://github.com/aantron/dream/tree/master/example/r-hello#folders-and-files [reason-examples]: https://github.com/aantron/dream/tree/master/example#reason [deploying]: https://github.com/aantron/dream/tree/master/example#deploying [api-main]: https://aantron.github.io/dream/#types [fullstack]: https://github.com/aantron/dream/tree/master/example#full-stack -[watch]: https://github.com/aantron/dream/tree/master/example/w-watch#files -[reload]: https://github.com/aantron/dream/tree/master/example/w-live-reload#files +[watch]: https://github.com/aantron/dream/tree/master/example/w-watch#folders-and-files +[reload]: https://github.com/aantron/dream/tree/master/example/w-live-reload#folders-and-files
diff --git a/docs/web/templates/index.html b/docs/web/templates/index.html index cf0500c8..4ed2fc67 100644 --- a/docs/web/templates/index.html +++ b/docs/web/templates/index.html @@ -123,7 +123,7 @@
Tidy Web framework for OCaml and ReasonML
  • A Tutorial — get started at - + 1-hello!
  • diff --git a/example/1-hello/README.md b/example/1-hello/README.md index a4ec7e0e..78cbecd9 100644 --- a/example/1-hello/README.md +++ b/example/1-hello/README.md @@ -40,17 +40,17 @@ name of the `.ml` file, but with `.ml` changed to `.exe`. **Next steps:** -- The next example, [**`2-middleware`**](../2-middleware#files), adds a logger +- The next example, [**`2-middleware`**](../2-middleware#folders-and-files), adds a logger to the app. -- [**`3-router`**](../3-router#files) sends requests to different handlers, +- [**`3-router`**](../3-router#folders-and-files) sends requests to different handlers, depending on their path.
    **See also:** -- [**`r-hello`**](../r-hello#files) is a Reason syntax version of this example. -- [**`w-watch`**](../w-watch#files) sets up a development watcher. +- [**`r-hello`**](../r-hello#folders-and-files) is a Reason syntax version of this example. +- [**`w-watch`**](../w-watch#folders-and-files) sets up a development watcher.
    diff --git a/example/2-middleware/README.md b/example/2-middleware/README.md index c1798036..4768ce43 100644 --- a/example/2-middleware/README.md +++ b/example/2-middleware/README.md @@ -4,7 +4,7 @@ *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 -[**`1-hello`**](../1-hello#files) and wraps it in one of the most useful +[**`1-hello`**](../1-hello#folders-and-files) and wraps it in one of the most useful middlewares, the [*logger*](https://aantron.github.io/dream/#val-logger): ```ocaml @@ -40,7 +40,7 @@ When you run this server and visit You can write your own messages to the log using [`Dream.log`](https://aantron.github.io/dream/#val-log). See example -[**`a-log`**](../a-log#files) for more logging options. Now that we have the +[**`a-log`**](../a-log#folders-and-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 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 from handlers to handlers, so you can create them anywhere. Example -[**`4-counter`**](../4-counter#files) already shows a simple custom middleware. +[**`4-counter`**](../4-counter#folders-and-files) already shows a simple custom middleware. @@ -64,10 +64,10 @@ There are also more complicated middlewares defined in **Next steps:** -- The next example, [**`3-router`**](../3-router#files), shows +- The next example, [**`3-router`**](../3-router#folders-and-files), shows [*routes*](https://aantron.github.io/dream/#routing), the other way to build up handlers in Dream. -- [**`4-counter`**](../4-counter#files) builds the first custom middleware. +- [**`4-counter`**](../4-counter#folders-and-files) builds the first custom middleware.
    diff --git a/example/3-router/README.md b/example/3-router/README.md index 9ed8d909..348b913d 100644 --- a/example/3-router/README.md +++ b/example/3-router/README.md @@ -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. Except for the status code, the `404 Not Found` response is *completely* empty, so it might not display well in your browser. In example -[**`9-error`**](../9-error#files), we will decorate all error responses with +[**`9-error`**](../9-error#folders-and-files), we will decorate all error responses with an error template in one central location.
    The router can do more than match simple routes: -- [**`f-static`**](../f-static#files) forwards all requests with a certain +- [**`f-static`**](../f-static#folders-and-files) forwards all requests with a certain prefix to a static file handler. - @@ -63,9 +63,9 @@ The router can do more than match simple routes: **Next steps:** -- [**`4-counter`**](../4-counter#files) counts requests, and exposes a route for +- [**`4-counter`**](../4-counter#folders-and-files) counts requests, and exposes a route for getting the count. -- [**`5-promise`**](../5-promise#files) introduces +- [**`5-promise`**](../5-promise#folders-and-files) introduces [Lwt](https://github.com/ocsigen/lwt), the promise library used by Dream.
    diff --git a/example/4-counter/README.md b/example/4-counter/README.md index 0d05a4a8..8248bb56 100644 --- a/example/4-counter/README.md +++ b/example/4-counter/README.md @@ -37,16 +37,16 @@ which means they usually also This example's middleware only does something *before* calling the `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 -used by Dream. The next example, [**`5-promise`**](../5-promise#files), does +used by Dream. The next example, [**`5-promise`**](../5-promise#folders-and-files), does exactly that!
    **Next steps:** -- [**`5-promise`**](../5-promise#files) shows a middleware that awaits +- [**`5-promise`**](../5-promise#folders-and-files) shows a middleware that awaits responses using [Lwt](https://github.com/ocsigen/lwt). -- [**`6-echo`**](../6-echo#files) responds to `POST` requests and reads their +- [**`6-echo`**](../6-echo#folders-and-files) responds to `POST` requests and reads their bodies.
    diff --git a/example/5-promise/README.md b/example/5-promise/README.md index 5702d85d..22ebefd8 100644 --- a/example/5-promise/README.md +++ b/example/5-promise/README.md @@ -2,7 +2,7 @@
    -[**`4-counter`**](../4-counter#files) was limited to counting requests *before* +[**`4-counter`**](../4-counter#folders-and-files) was limited to counting requests *before* 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 *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:** -- [**`6-echo`**](../6-echo#files) uses Dream and Lwt to read a request body. -- [**`7-template`**](../7-template#files) shows how to interleave HTML and +- [**`6-echo`**](../6-echo#folders-and-files) uses Dream and Lwt to read a request body. +- [**`7-template`**](../7-template#folders-and-files) shows how to interleave HTML and OCaml.
    diff --git a/example/6-echo/README.md b/example/6-echo/README.md index 0aa1c2b7..0e846d01 100644 --- a/example/6-echo/README.md +++ b/example/6-echo/README.md @@ -46,11 +46,11 @@ foo We usually want to do something more interesting with the request body than just echo it, and there are several examples for that! -- [**`d-form`**](../d-form#files) parses request bodies as forms. -- [**`e-json`**](../e-json#files) parses bodies as JSON. -- [**`g-upload`**](../g-upload#files) receives file upload forms. -- [**`i-graphql`**](../i-graphql#files) receives GraphQL queries. -- [**`j-stream`**](../j-stream#files) streams huge bodies. +- [**`d-form`**](../d-form#folders-and-files) parses request bodies as forms. +- [**`e-json`**](../e-json#folders-and-files) parses bodies as JSON. +- [**`g-upload`**](../g-upload#folders-and-files) receives file upload forms. +- [**`i-graphql`**](../i-graphql#folders-and-files) receives GraphQL queries. +- [**`j-stream`**](../j-stream#folders-and-files) streams huge bodies. 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 @@ -62,9 +62,9 @@ present them the right way. **Next steps:** -- [**`7-template`**](../7-template#files) builds responses from templates and +- [**`7-template`**](../7-template#folders-and-files) builds responses from templates and guards against injection attacks (XSS). -- [**`8-debug`**](../8-debug#files) renders error information in responses. +- [**`8-debug`**](../8-debug#folders-and-files) renders error information in responses.
    diff --git a/example/7-template/README.md b/example/7-template/README.md index a4dc598a..a66df372 100644 --- a/example/7-template/README.md +++ b/example/7-template/README.md @@ -125,31 +125,31 @@ and not supported by Dream. **Next steps:** -- [**`8-debug`**](../8-debug#files) shows how to turn on debug responses, and +- [**`8-debug`**](../8-debug#folders-and-files) shows how to turn on debug responses, and get more info about errors. -- [**`9-error`**](../9-error#files) sets up a central error template for all +- [**`9-error`**](../9-error#folders-and-files) sets up a central error template for all errors. -- [**`r-template`**](../r-template#files) is a Reason syntax version of this +- [**`r-template`**](../r-template#folders-and-files) is a Reason syntax version of this example.
    **See also:** -- [**`w-template-files`**](../w-template-files#files) moves the template into a +- [**`w-template-files`**](../w-template-files#folders-and-files) moves the template into a separate `.eml.html` to avoid problems with editor support. -- [**`w-template-logic`**](../w-template-logic#files) shows how to put control +- [**`w-template-logic`**](../w-template-logic#folders-and-files) shows how to put control flow into templates. -- [**`w-tyxml`**](../w-tyxml#files) shows how to use +- [**`w-tyxml`**](../w-tyxml#folders-and-files) shows how to use [TyXML](https://github.com/ocsigen/tyxml), a different templater that uses OCaml's type system to prevent emitting many kinds of invalid HTML. -- [**`r-tyxml`**](../r-tyxml#files) if you are using Reason. You can use TyXML +- [**`r-tyxml`**](../r-tyxml#folders-and-files) if you are using Reason. You can use TyXML with JSX syntax server-side! -- [**`w-dream-html`**](../w-dream-html#files) shows how to use +- [**`w-dream-html`**](../w-dream-html#folders-and-files) shows how to use [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#files) streams templates to +- [**`w-template-stream`**](../w-template-stream#folders-and-files) streams templates to responses, instead of building up complete response strings.
    diff --git a/example/8-debug/README.md b/example/8-debug/README.md index 1f590829..3f0caa8d 100644 --- a/example/8-debug/README.md +++ b/example/8-debug/README.md @@ -94,7 +94,7 @@ work with in development. 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 -example](../9-error#files)! +example](../9-error#folders-and-files)! @@ -104,9 +104,9 @@ example](../9-error#files)! **Next steps:** -- [**`9-error`**](../9-error#files) handles all errors in one place, including +- [**`9-error`**](../9-error#folders-and-files) handles all errors in one place, including displaying the debugger output. -- [**`a-log`**](../a-log#files) shows [log +- [**`a-log`**](../a-log#folders-and-files) shows [log levels](https://aantron.github.io/dream/#type-log_level) and [sub-logs](https://aantron.github.io/dream/#type-sub_log). diff --git a/example/9-error/README.md b/example/9-error/README.md index efcd2e05..3028902e 100644 --- a/example/9-error/README.md +++ b/example/9-error/README.md @@ -63,7 +63,7 @@ including return a completely new response.
    `debug_info` is a multiline string containing the same information as in the -previous example, [**`8-debug`**](../8-debug#files). +previous example, [**`8-debug`**](../8-debug#folders-and-files). @@ -80,9 +80,9 @@ Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet **Next steps:** -- [**`a-log`**](../a-log#files) shows how to write messages to Dream's +- [**`a-log`**](../a-log#folders-and-files) shows how to write messages to Dream's [log](https://aantron.github.io/dream/#logging). -- [**`b-session`**](../b-session#files) adds [session +- [**`b-session`**](../b-session#folders-and-files) adds [session management](https://aantron.github.io/dream/#sessions) for associating state with clients. diff --git a/example/README.md b/example/README.md index 0da93f97..fddb0406 100644 --- a/example/README.md +++ b/example/README.md @@ -2,46 +2,46 @@ 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 -documentation. You can begin at [**`1-hello`**](1-hello#files), or look in the +documentation. You can begin at [**`1-hello`**](1-hello#folders-and-files), or look in the list below and jump to whatever interests you! -- [**`1-hello`**](1-hello/#files)  —  the simplest Dream server +- [**`1-hello`**](1-hello#folders-and-files)  —  the simplest Dream server responds to every request with the same friendly message. -- [**`2-middleware`**](2-middleware/#files)  —  adds the first +- [**`2-middleware`**](2-middleware#folders-and-files)  —  adds the first Dream middleware: the *logger*. -- [**`3-router`**](3-router/#files)  —  different handlers for +- [**`3-router`**](3-router#folders-and-files)  —  different handlers for different paths. -- [**`4-counter`**](4-counter/#files)  —  the first *custom* +- [**`4-counter`**](4-counter#folders-and-files)  —  the first *custom* middleware! -- [**`5-promise`**](5-promise/#files)  —  introduces Lwt, the +- [**`5-promise`**](5-promise#folders-and-files)  —  introduces Lwt, the promise library used by Dream. -- [**`6-echo`**](6-echo/#files)  —  reads request bodies. -- [**`7-template`**](7-template/#files)  —  renders responses +- [**`6-echo`**](6-echo#folders-and-files)  —  reads request bodies. +- [**`7-template`**](7-template#folders-and-files)  —  renders responses from inline HTML templates and guards against XSS. -- [**`8-debug`**](8-debug/#files)  —  includes detailed +- [**`8-debug`**](8-debug#folders-and-files)  —  includes detailed information about errors in responses. -- [**`9-error`**](9-error/#files)  —  customize all error +- [**`9-error`**](9-error#folders-and-files)  —  customize all error responses in one place. -- [**`a-log`**](a-log/#files)  —  writing messages to Dream's +- [**`a-log`**](a-log#folders-and-files)  —  writing messages to Dream's log. -- [**`b-session`**](b-session/#files)  —  associates state with +- [**`b-session`**](b-session#folders-and-files)  —  associates state with client sessions. -- [**`c-cookie`**](c-cookie/#files)  —  sets custom cookies. -- [**`d-form`**](d-form#files)  —  reads forms with CSRF +- [**`c-cookie`**](c-cookie#folders-and-files)  —  sets custom cookies. +- [**`d-form`**](d-form#folders-and-files)  —  reads forms with CSRF prevention. -- [**`e-json`**](e-json#files)  —  sends and receives JSON +- [**`e-json`**](e-json#folders-and-files)  —  sends and receives JSON securely. -- [**`f-static`**](f-static#files)  —  serves static files from +- [**`f-static`**](f-static#folders-and-files)  —  serves static files from a local directory. -- [**`g-upload`**](g-upload#files)  —  receives file uploads. -- [**`h-sql`**](h-sql#files)  —  queries an SQL database. -- [**`i-graphql`**](i-graphql#files)  —  serves a GraphQL +- [**`g-upload`**](g-upload#folders-and-files)  —  receives file uploads. +- [**`h-sql`**](h-sql#folders-and-files)  —  queries an SQL database. +- [**`i-graphql`**](i-graphql#folders-and-files)  —  serves a GraphQL schema and GraphiQL. -- [**`j-stream`**](j-stream#files)  —  streams request and +- [**`j-stream`**](j-stream#folders-and-files)  —  streams request and response bodies. -- [**`k-websocket`**](k-websocket#files)  —  opens a WebSocket +- [**`k-websocket`**](k-websocket#folders-and-files)  —  opens a WebSocket between client and server. -- [**`l-https`**](l-https#files)  —  enables HTTPS and HTTP/2 +- [**`l-https`**](l-https#folders-and-files)  —  enables HTTPS and HTTP/2 upgrades. 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. -- [**`r-hello`**](r-hello#files)  —  the simplest Dream server. -- [**`r-template`**](r-template#files)  —  renders HTML +- [**`r-hello`**](r-hello#folders-and-files)  —  the simplest Dream server. +- [**`r-template`**](r-template#folders-and-files)  —  renders HTML templates and protects against XSS. -- [**`r-template-files`**](r-template-files#files)  —  templates +- [**`r-template-files`**](r-template-files#folders-and-files)  —  templates in separate `.html` files for better editor support. -- [**`r-template-logic`**](r-template-logic#files)  —  control +- [**`r-template-logic`**](r-template-logic#folders-and-files)  —  control flow inside templates. -- [**`r-template-stream`**](r-template-stream#files)  —  streams +- [**`r-template-stream`**](r-template-stream#folders-and-files)  —  streams templates as response bodies. -- [**`r-tyxml`**](r-tyxml#files)  —  type-checked server-side +- [**`r-tyxml`**](r-tyxml#folders-and-files)  —  type-checked server-side JSX templates. -- [**`r-graphql`**](r-graphql#files)  —  serves a GraphQL +- [**`r-graphql`**](r-graphql#folders-and-files)  —  serves a GraphQL schema.
    # Full-stack -- [**`r-fullstack-melange`**](r-fullstack-melange#files)  —  +- [**`r-fullstack-melange`**](r-fullstack-melange#folders-and-files)  —  server *and* client written in Reason! -- [**`w-fullstack-rescript`**](w-fullstack-rescript#files)  —  +- [**`w-fullstack-rescript`**](w-fullstack-rescript#folders-and-files)  —  shares OCaml code between server and client using ReScript. -- [**`w-fullstack-jsoo`**](w-fullstack-jsoo#files)  —  shares +- [**`w-fullstack-jsoo`**](w-fullstack-jsoo#folders-and-files)  —  shares OCaml code between server and client using js_of_ocaml.
    # Deploying -- [**`z-heroku`**](z-heroku#files)  —  to +- [**`z-heroku`**](z-heroku#folders-and-files)  —  to [Heroku](https://www.heroku.com). -- [**`z-fly`**](z-fly#files)  —  to [Fly.io](https://fly.io/). -- [**`z-docker-esy`**](z-docker-esy#files)  —  on a server, +- [**`z-fly`**](z-fly#folders-and-files)  —  to [Fly.io](https://fly.io/). +- [**`z-docker-esy`**](z-docker-esy#folders-and-files)  —  on a server, using Docker, with package manager esy. -- [**`z-docker-opam`**](z-docker-opam#files)  —  on a server, +- [**`z-docker-opam`**](z-docker-opam#folders-and-files)  —  on a server, using Docker, with package manager opam. -- [**`z-systemd`**](z-systemd#files)  —  on a server, as a +- [**`z-systemd`**](z-systemd#folders-and-files)  —  on a server, as a systemd daemon.
    @@ -102,51 +102,51 @@ if something is missing!
    -- [**`w-template-files`**](w-template-files#files)  —  templates +- [**`w-template-files`**](w-template-files#folders-and-files)  —  templates in separate `.html` files for better editor support. -- [**`w-template-logic`**](w-template-logic#files)  —  control +- [**`w-template-logic`**](w-template-logic#folders-and-files)  —  control flow inside templates. -- [**`w-graphql-subscription`**](w-graphql-subscription#files) +- [**`w-graphql-subscription`**](w-graphql-subscription#folders-and-files)  —  GraphQL subscriptions. -- [**`w-postgres`**](w-postgres#files)  —  connects to a +- [**`w-postgres`**](w-postgres#folders-and-files)  —  connects to a PostgreSQL database. -- [**`w-flash`**](w-flash#files)  —  using flash messages, which +- [**`w-flash`**](w-flash#folders-and-files)  —  using flash messages, which are displayed on the next request. -- [**`w-chat`**](w-chat#files)  —  a chat room based on +- [**`w-chat`**](w-chat#folders-and-files)  —  a chat room based on WebSockets. -- [**`w-content-security-policy`**](w-content-security-policy#files) +- [**`w-content-security-policy`**](w-content-security-policy#folders-and-files)  —  sandboxes Web pages using `Content-Security-Policy`. -- [**`w-esy`**](w-esy#files)  —  gives detail on packaging with +- [**`w-esy`**](w-esy#folders-and-files)  —  gives detail on packaging with [esy](https://esy.sh/), an npm-like package manager. -- [**`w-one-binary`**](w-one-binary#files)  —  bakes static +- [**`w-one-binary`**](w-one-binary#folders-and-files)  —  bakes static assets into a self-contained server binary. -- [**`w-watch`**](w-watch#files)  —  sets up a development +- [**`w-watch`**](w-watch#folders-and-files)  —  sets up a development watcher. -- [**`w-live-reload`**](w-live-reload#files)  —  a simple +- [**`w-live-reload`**](w-live-reload#folders-and-files)  —  a simple live-reloading setup. -- [**`w-nginx`**](w-nginx#files)  —  uses nginx as a +- [**`w-nginx`**](w-nginx#folders-and-files)  —  uses nginx as a reverse proxy. -- [**`w-tyxml`**](w-tyxml#files)  —  uses TyXML for type-checked +- [**`w-tyxml`**](w-tyxml#folders-and-files)  —  uses TyXML for type-checked HTML templating. -- [**`w-dream-html`**](../w-dream-html#files)  —  uses +- [**`w-dream-html`**](../w-dream-html#folders-and-files)  —  uses dream-html for convenient HTML generation from OCaml. -- [**`w-long-polling`**](w-long-polling#files)  —  old form of +- [**`w-long-polling`**](w-long-polling#folders-and-files)  —  old form of asynchronous communication without WebSockets. -- [**`w-query`**](w-query#files)  —  reads URL query parameters. -- [**`w-server-sent-events`**](w-server-sent-events#files)  —  +- [**`w-query`**](w-query#folders-and-files)  —  reads URL query parameters. +- [**`w-server-sent-events`**](w-server-sent-events#folders-and-files)  —  [`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource), an older alternative to WebSockets. -- [**`w-template-stream`**](w-template-stream#files)  —  sends +- [**`w-template-stream`**](w-template-stream#folders-and-files)  —  sends templates asynchronously, one chunk at a time. -- [**`w-upload-stream`**](w-upload-stream#files)  —  streams +- [**`w-upload-stream`**](w-upload-stream#folders-and-files)  —  streams uploaded files. -- [**`w-stress-response`**](w-stress-response#files)  —  +- [**`w-stress-response`**](w-stress-response#folders-and-files)  —  benchmarks streaming very large responses. -- [**`w-stress-websocket-send`**](w-stress-websocket-send#files) +- [**`w-stress-websocket-send`**](w-stress-websocket-send#folders-and-files)  —  benchmarks sending WebSocket messages quickly. -- [**`w-multipart-dump`**](w-multipart-dump#files)  —  echoes +- [**`w-multipart-dump`**](w-multipart-dump#folders-and-files)  —  echoes `multipart/form-data` bodies for debugging. -- [**`z-playground`**](z-playground#files)  —  source code of +- [**`z-playground`**](z-playground#folders-and-files)  —  source code of the Dream playground.
    @@ -169,7 +169,7 @@ Ideas: Basics: - `w-content-negotiation` -- [**`w-query`**](w-query#files)  —  done. +- [**`w-query`**](w-query#folders-and-files)  —  done. - `w-scope`  —  for [`Dream.scope`](https://aantron.github.io/dream/#val-scope). - `w-subsite`  —  for diff --git a/example/a-log/README.md b/example/a-log/README.md index 4489644a..999a196d 100644 --- a/example/a-log/README.md +++ b/example/a-log/README.md @@ -76,9 +76,9 @@ let () = **Next steps:** -- [**`b-session`**](../b-session#files) returns Web development proper with +- [**`b-session`**](../b-session#folders-and-files) returns Web development proper with session management. -- [**`c-cookie`**](../c-cookie#files) shows cookie handling in Dream. +- [**`c-cookie`**](../c-cookie#folders-and-files) shows cookie handling in Dream.
    diff --git a/example/b-session/README.md b/example/b-session/README.md index 1e2c19ab..061c996a 100644 --- a/example/b-session/README.md +++ b/example/b-session/README.md @@ -68,7 +68,7 @@ There are two other session back ends, which are persistent: using a different random encryption key each time it starts. - [`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions) stores sessions in a database. It is shown in example - [**`h-sql`**](../h-sql#files). + [**`h-sql`**](../h-sql#folders-and-files).
    @@ -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 being easily observed by third parties. See [`Dream.run`](https://aantron.github.io/dream/#val-run) argument `~https`, and -example [**`l-https`**](../l-https#files). If you redirect from HTTP to HTTPS, +example [**`l-https`**](../l-https#folders-and-files). If you redirect from HTTP to HTTPS, do not issue sessions for HTTP requests. If you do, don't accept them later from HTTPS requests. @@ -100,8 +100,8 @@ from HTTPS requests. **Next steps:** - Sessions already use cookies internally, but in - [**`c-cookie`**](../c-cookie#files) we set cookies for our own purposes! -- [**`d-form`**](../d-form#files) builds secure forms on top of sessions. + [**`c-cookie`**](../c-cookie#folders-and-files) we set cookies for our own purposes! +- [**`d-form`**](../d-form#folders-and-files) builds secure forms on top of sessions.
    diff --git a/example/c-cookie/README.md b/example/c-cookie/README.md index a6da2090..53535d98 100644 --- a/example/c-cookie/README.md +++ b/example/c-cookie/README.md @@ -96,9 +96,9 @@ The easiest way to do that for general data is to use **Next steps:** -- [**`d-form`**](../d-form#files) builds secure forms on top of sessions, and +- [**`d-form`**](../d-form#folders-and-files) builds secure forms on top of sessions, and introduces automatic handling of CSRF tokens. -- [**`e-json`**](../e-json#files) sends and receives JSON instead! +- [**`e-json`**](../e-json#folders-and-files) sends and receives JSON instead!
    diff --git a/example/d-form/README.md b/example/d-form/README.md index e5564d89..c7df64b9 100644 --- a/example/d-form/README.md +++ b/example/d-form/README.md @@ -2,7 +2,7 @@
    -With the session middleware from example [**`b-session`**](../b-session#files), +With the session middleware from example [**`b-session`**](../b-session#folders-and-files), we can build a [secure form](https://aantron.github.io/dream/#forms): ```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 the data is not sensitive, so we took a shortcut. See -[**`h-sql`**](../h-sql#files) for an example with a proper redirection. +[**`h-sql`**](../h-sql#folders-and-files) for an example with a proper redirection.
    **Next steps:** -- [**`e-json`**](../e-json#files) receives and sends JSON. -- [**`f-static`**](../f-static#files) serves static files from a local +- [**`e-json`**](../e-json#folders-and-files) receives and sends JSON. +- [**`f-static`**](../f-static#folders-and-files) serves static files from a local directory.
    diff --git a/example/e-json/README.md b/example/e-json/README.md index f732f1f9..ba7bdf6e 100644 --- a/example/e-json/README.md +++ b/example/e-json/README.md @@ -112,9 +112,9 @@ requests! **Next steps:** -- [**`f-static`**](../f-static#files) serves static files from the local +- [**`f-static`**](../f-static#folders-and-files) serves static files from the local file system. -- [**`g-upload`**](../g-upload#files) receives files from an upload form. +- [**`g-upload`**](../g-upload#folders-and-files) receives files from an upload form.
    diff --git a/example/f-static/README.md b/example/f-static/README.md index bf43a6b4..f1de4c5d 100644 --- a/example/f-static/README.md +++ b/example/f-static/README.md @@ -56,7 +56,7 @@ You can replace the file loading behavior of [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 [`Dream.static`](https://aantron.github.io/dream/#val-static)! See example -[**`w-one-binary`**](../w-one-binary#files). +[**`w-one-binary`**](../w-one-binary#folders-and-files). 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:** -- [**`g-upload`**](../g-upload#files) receives files instead of serving them. -- [**`h-sql`**](../h-sql#files) runs SQL queries against a database. -- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a +- [**`g-upload`**](../g-upload#folders-and-files) receives files instead of serving them. +- [**`h-sql`**](../h-sql#folders-and-files) runs SQL queries against a database. +- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a self-contained binary.
    diff --git a/example/g-upload/README.md b/example/g-upload/README.md index 34e401fc..ede4ac7e 100644 --- a/example/g-upload/README.md +++ b/example/g-upload/README.md @@ -84,7 +84,7 @@ streaming file uploads. [`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 [CSRF protection](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html). -See example [**`d-form`**](../d-form#files). We use +See example [**`d-form`**](../d-form#folders-and-files). We use [`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"` 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:** -- [**`h-sql`**](../h-sql#files) runs SQL queries against a database. -- [**`i-graphql`**](../i-graphql#files) handles GraphQL queries and serves +- [**`h-sql`**](../h-sql#folders-and-files) runs SQL queries against a database. +- [**`i-graphql`**](../i-graphql#folders-and-files) handles GraphQL queries and serves GraphiQL.
    **See also:** -- [**`w-upload-stream`**](../w-upload-stream#files) shows the streaming +- [**`w-upload-stream`**](../w-upload-stream#folders-and-files) shows the streaming interface for receiving file uploads. -- [**`w-multipart-dump`**](../w-multipart-dump#files) shows the request body +- [**`w-multipart-dump`**](../w-multipart-dump#folders-and-files) shows the request body that is interpreted by [`Dream.multipart`](https://aantron.github.io/dream/#val-multipart). diff --git a/example/h-sql/README.md b/example/h-sql/README.md index 1739535c..aab16638 100644 --- a/example/h-sql/README.md +++ b/example/h-sql/README.md @@ -82,7 +82,7 @@ comments! We take the opportunity to try out [`Dream.sql_sessions`](https://aantron.github.io/dream/#val-sql_sessions), which stores session data persistently in `db.sqlite`. See example -[**`b-session`**](../b-session#files) for an introduction to session management. +[**`b-session`**](../b-session#folders-and-files) for an introduction to session management. Both the comments and the sessions survive server restarts.
    @@ -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, microservices, or other needs, you can switch, for example, to PostgreSQL. See -[**`w-postgres`**](../w-postgres#files). +[**`w-postgres`**](../w-postgres#folders-and-files). A good program for examining databases locally is [Beekeeper Studio](https://www.beekeeperstudio.io/). Dream might also integrate @@ -156,9 +156,9 @@ See **Next steps:** -- [**`i-graphql`**](../i-graphql#files) handles GraphQL queries and serves +- [**`i-graphql`**](../i-graphql#folders-and-files) handles GraphQL queries and serves GraphiQL. -- [**`j-stream`**](../j-stream#files) streams response bodies to clients. +- [**`j-stream`**](../j-stream#folders-and-files) streams response bodies to clients.
    diff --git a/example/i-graphql/README.md b/example/i-graphql/README.md index 6028578f..45c7bcdb 100644 --- a/example/i-graphql/README.md +++ b/example/i-graphql/README.md @@ -89,17 +89,17 @@ GraphiQL conditionally, only during development. **Next steps:** -- [**`j-stream`**](../j-stream#files) streams response bodies to clients. -- [**`k-websocket`**](../k-websocket#files) sends and receives messages over a +- [**`j-stream`**](../j-stream#folders-and-files) streams response bodies to clients. +- [**`k-websocket`**](../k-websocket#folders-and-files) sends and receives messages over a WebSocket.
    **See also:** -- [**`r-graphql`**](../r-graphql#files) is a version of this example in Reason +- [**`r-graphql`**](../r-graphql#folders-and-files) is a version of this example in Reason syntax. -- [**`w-graphql-subscription`**](../w-graphql-subscription#files) for GraphQL +- [**`w-graphql-subscription`**](../w-graphql-subscription#folders-and-files) for GraphQL subscriptions.
    diff --git a/example/j-stream/README.md b/example/j-stream/README.md index cb5afc02..c9078b4c 100644 --- a/example/j-stream/README.md +++ b/example/j-stream/README.md @@ -2,7 +2,7 @@
    -In example [**`6-echo`**](../6-echo#files), we echoed `POST` requests by reading +In example [**`6-echo`**](../6-echo#folders-and-files), we echoed `POST` requests by reading their whole bodies into memory, and then writing them. Here, we echo request bodies chunk by chunk: @@ -60,9 +60,9 @@ See [*Streams*](https://aantron.github.io/dream/#streams) in the API docs. **Next steps:** -- [**`k-websocket`**](../k-websocket#files) sends and receives messages over a +- [**`k-websocket`**](../k-websocket#folders-and-files) sends and receives messages over a WebSocket. -- [**`l-https`**](../l-https#files) enables HTTPS, which is very easy with +- [**`l-https`**](../l-https#folders-and-files) enables HTTPS, which is very easy with Dream.
    diff --git a/example/k-websocket/README.md b/example/k-websocket/README.md index be0e3b63..6d97b273 100644 --- a/example/k-websocket/README.md +++ b/example/k-websocket/README.md @@ -78,14 +78,14 @@ See [*WebSockets*](https://aantron.github.io/dream/#websockets) in the API docs. **Last step:** -- [**`l-https`**](../l-https#files) enables HTTPS. +- [**`l-https`**](../l-https#folders-and-files) enables HTTPS.
    **See also:** -- [**`w-chat`**](../w-chat#files) is a simple WebSocket-based chat application. -- [**`w-live-reload`**](../w-live-reload#files) uses WebSockets to implement +- [**`w-chat`**](../w-chat#folders-and-files) is a simple WebSocket-based chat application. +- [**`w-live-reload`**](../w-live-reload#folders-and-files) uses WebSockets to implement live reloading. - [**`w-graphql-subscription`**](../w-graphql-subscription) does not show a WebSocket directly, but shows GraphQL subscriptions, which are implemented diff --git a/example/quickstart.sh b/example/quickstart.sh index b6110f3f..d6b4c697 100755 --- a/example/quickstart.sh +++ b/example/quickstart.sh @@ -42,7 +42,7 @@ cd $DIRECTORY echo echo -e "\e[0m✅ Fetching example files using git\e[0m" -echo -e "\e[0m Source: $REPO/tree/$REF/example/$EXAMPLE#files\e[0m" +echo -e "\e[0m Source: $REPO/tree/$REF/example/$EXAMPLE#folders-and-files\e[0m" mkdir clone cd clone git init --quiet @@ -81,7 +81,7 @@ echo " dune exec ./$EXE --watch" echo echo -e "\e[0m✅ See\e[0m" echo -echo " - This example:" $REPO/tree/$REF/example/$EXAMPLE#files +echo " - This example:" $REPO/tree/$REF/example/$EXAMPLE#folders-and-files echo " - Tutorial: " $REPO/tree/$REF/example#tutorial echo echo 💲 dune exec ./$EXE diff --git a/example/r-fullstack-melange/README.md b/example/r-fullstack-melange/README.md index d23d07f8..c83039ff 100644 --- a/example/r-fullstack-melange/README.md +++ b/example/r-fullstack-melange/README.md @@ -87,12 +87,12 @@ example in OCaml syntax. **See also:** -- [**`w-watch`**](../w-fswatch#files) sets up a development watcher. -- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a +- [**`w-watch`**](../w-fswatch#folders-and-files) sets up a development watcher. +- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a self-contained binary. -- [**`7-template`**](../7-template#files) discusses the templater, including +- [**`7-template`**](../7-template#folders-and-files) discusses the templater, including security. The example is in OCaml syntax. -- [**`r-template`**](../r-template#files) the code of the template example in +- [**`r-template`**](../r-template#folders-and-files) the code of the template example in Reason syntax.
    diff --git a/example/r-graphql/README.md b/example/r-graphql/README.md index f9006759..e49fa557 100644 --- a/example/r-graphql/README.md +++ b/example/r-graphql/README.md @@ -83,9 +83,9 @@ the schema: **See also:** -- [**`i-graphql`**](../i-graphql#files), the OCaml version of this example, for +- [**`i-graphql`**](../i-graphql#folders-and-files), the OCaml version of this example, for some more discussion. -- [**`w-graphql-subscription`**](../w-graphql-subscription#files) for GraphQL +- [**`w-graphql-subscription`**](../w-graphql-subscription#folders-and-files) for GraphQL subscriptions.
    diff --git a/example/r-hello/README.md b/example/r-hello/README.md index a5d827fb..45f8e8e8 100644 --- a/example/r-hello/README.md +++ b/example/r-hello/README.md @@ -37,7 +37,7 @@ Note that we had to make an addition to **See also:** -- [**`r-template`**](../r-template#files) shows templates with Reason syntax. +- [**`r-template`**](../r-template#folders-and-files) shows templates with Reason syntax. - [**`2-middleware`**](../2-middleware) introduces the *logger*, the most commonly used Dream middleware. The example is in OCaml syntax. diff --git a/example/r-template-files/README.md b/example/r-template-files/README.md index e9afd245..d00116f4 100644 --- a/example/r-template-files/README.md +++ b/example/r-template-files/README.md @@ -3,7 +3,7 @@
    This example splits the code of the basic template example, -[**`r-template`**](../r-template#files), into two files. The first is the +[**`r-template`**](../r-template#folders-and-files), into two files. The first is the 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 mostly HTML, and to prevent `refmt` from trying to format the file: @@ -57,8 +57,8 @@ file: **See also:** -- [**`r-template`**](../r-template#files) for the one-file version. -- [**`7-template`**](../7-template#files) for comments on [security +- [**`r-template`**](../r-template#folders-and-files) for the one-file version. +- [**`7-template`**](../7-template#folders-and-files) for comments on [security information](../7-template#security). - [**`w-template-files`**](../w-template-files) for the OCaml version of this example. diff --git a/example/r-template-logic/README.md b/example/r-template-logic/README.md index 38119b17..16f66a2c 100644 --- a/example/r-template-logic/README.md +++ b/example/r-template-logic/README.md @@ -74,8 +74,8 @@ let () = **See also:** -- [**`7-template`**](../7-template#files) for basic information about templates. -- [**`w-template-logic`**](../w-template-logic#files) for the OCaml version +- [**`7-template`**](../7-template#folders-and-files) for basic information about templates. +- [**`w-template-logic`**](../w-template-logic#folders-and-files) for the OCaml version of this example.
    diff --git a/example/r-template-stream/README.md b/example/r-template-stream/README.md index f7607c26..cdff7f28 100644 --- a/example/r-template-stream/README.md +++ b/example/r-template-stream/README.md @@ -49,7 +49,7 @@ The important differences with regular usage of templates are: name `response`. - We use the promise library [Lwt](https://github.com/ocsigen/lwt) inside the template for asynchronous control flow. See example - [**`5-promise`**](../5-promise#files) for an introduction to Lwt. + [**`5-promise`**](../5-promise#folders-and-files) for an introduction to Lwt. 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 @@ -60,11 +60,11 @@ interactive, so we force writing of all output after generating each `

    ` tag. **See also:** -- [**`r-template`**](../r-template#files) for the simpler way to do templates, +- [**`r-template`**](../r-template#folders-and-files) for the simpler way to do templates, building up entire bodies as strings. - [**`7-template`**](../7-template#security) section *Security* for XSS prevention considerations. -- [**`w-template-stream`**](../w-template-stream#files) is the OCaml version of +- [**`w-template-stream`**](../w-template-stream#folders-and-files) is the OCaml version of this example.
    diff --git a/example/r-template/README.md b/example/r-template/README.md index 570332cd..03a879ec 100644 --- a/example/r-template/README.md +++ b/example/r-template/README.md @@ -59,11 +59,11 @@ same. **See also:** -- [**`r-template-files`**](../r-template-files#files) puts the template into a +- [**`r-template-files`**](../r-template-files#folders-and-files) puts the template into a separate `.eml.html` file, which can help with editor problems. -- [**`r-template-stream`**](../r-template-stream#files) streams a template to a +- [**`r-template-stream`**](../r-template-stream#folders-and-files) streams a template to a response. -- [**`9-error`**](../9-error#files) sets up a central error template. The +- [**`9-error`**](../9-error#folders-and-files) sets up a central error template. The example is in OCaml syntax.
    diff --git a/example/r-tyxml/README.md b/example/r-tyxml/README.md index 3a20ee45..430814cf 100644 --- a/example/r-tyxml/README.md +++ b/example/r-tyxml/README.md @@ -76,7 +76,7 @@ Error: Unbound value html **See also:** -- [**`w-tyxml`**](../w-tyxml#files) for an introduction to TyXML. +- [**`w-tyxml`**](../w-tyxml#folders-and-files) for an introduction to TyXML. - [**`7-template`**](../7-template#security) section *Security* on output security. TyXML escapes strings by default, just as the built-in templater does. diff --git a/example/w-chat/README.md b/example/w-chat/README.md index c24db67f..5d27db97 100644 --- a/example/w-chat/README.md +++ b/example/w-chat/README.md @@ -45,7 +45,7 @@ scheme, rather than `ws://`, on the client. **See also:** -- [**k-websocket**](../k-websocket#files) for an introduction to WebSockets. +- [**k-websocket**](../k-websocket#folders-and-files) for an introduction to WebSockets.
    diff --git a/example/w-dream-html/README.md b/example/w-dream-html/README.md index 0e8411d8..ade88392 100644 --- a/example/w-dream-html/README.md +++ b/example/w-dream-html/README.md @@ -59,7 +59,7 @@ Some notes: - [**`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#files) is a similar library that also generates +- [**`w-tyxml`**](../w-tyxml#folders-and-files) is a similar library that also generates HTML, with different design tradeoffs.
    diff --git a/example/w-esy/README.md b/example/w-esy/README.md index ceaefa5d..ce14f999 100644 --- a/example/w-esy/README.md +++ b/example/w-esy/README.md @@ -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 [`esy.build`](https://esy.sh/docs/en/configuration.html#esybuild). Here is an -example from [**`w-fullstack-jsoo`**](../w-fullstack-jsoo#files): +example from [**`w-fullstack-jsoo`**](../w-fullstack-jsoo#folders-and-files): ```json "esy": { @@ -124,12 +124,12 @@ See the examples linked below. **See also:** -- [**`w-fullstack-rescript`**](../w-fullstack-rescript#files) for full-stack +- [**`w-fullstack-rescript`**](../w-fullstack-rescript#folders-and-files) for full-stack development with ReScript. -- [**`r-fullstack-melange`**](../r-fullstack-melange#files) for full-stack +- [**`r-fullstack-melange`**](../r-fullstack-melange#folders-and-files) for full-stack development with Melange and Reason syntax. -- [**`w-fswatch`**](../w-fswatch#files) for a development watcher. -- [**`w-one-binary`**](../w-one-binary#files) for bundling assets into a +- [**`w-fswatch`**](../w-fswatch#folders-and-files) for a development watcher. +- [**`w-one-binary`**](../w-one-binary#folders-and-files) for bundling assets into a self-contained binary.
    diff --git a/example/w-flash/README.md b/example/w-flash/README.md index d5f10d0f..bef9b914 100644 --- a/example/w-flash/README.md +++ b/example/w-flash/README.md @@ -107,7 +107,7 @@ blows up their original size by 4/3. **See also:** -- [**`c-cookie`**](../c-cookie#files) shows cookie handling, the mechanism that +- [**`c-cookie`**](../c-cookie#folders-and-files) shows cookie handling, the mechanism that flash messages are implemented over.
    diff --git a/example/w-fullstack-jsoo/README.md b/example/w-fullstack-jsoo/README.md index bd7604c3..1e8d7929 100644 --- a/example/w-fullstack-jsoo/README.md +++ b/example/w-fullstack-jsoo/README.md @@ -70,7 +70,7 @@ Then visit [http://localhost:8080](http://localhost:8080), and you will see... **See also:** -- [**`w-one-binary`**](../w-one-binary#files) for bundling assets into a +- [**`w-one-binary`**](../w-one-binary#folders-and-files) for bundling assets into a self-contained binary.
    diff --git a/example/w-fullstack-rescript/README.md b/example/w-fullstack-rescript/README.md index a7dd9183..c25871e7 100644 --- a/example/w-fullstack-rescript/README.md +++ b/example/w-fullstack-rescript/README.md @@ -85,12 +85,12 @@ client in `./static/client.js`. The example serves the bundled client using **See also:** -- [**`w-esy`**](../w-esy#files) details the server's [esy](https://esy.sh/) +- [**`w-esy`**](../w-esy#folders-and-files) details the server's [esy](https://esy.sh/) packaging. -- [**`w-fswatch`**](../w-fswatch#files) sets up a primitive development watcher. -- [**`w-one-binary`**](../w-one-binary#files) bundles assets into a +- [**`w-fswatch`**](../w-fswatch#folders-and-files) sets up a primitive development watcher. +- [**`w-one-binary`**](../w-one-binary#folders-and-files) bundles assets into a self-contained binary. -- [**`f-static`**](../r-hello#files) presents +- [**`f-static`**](../r-hello#folders-and-files) presents [`Dream.static`](https://aantron.github.io/dream/#val-static).
    diff --git a/example/w-graphql-subscription/README.md b/example/w-graphql-subscription/README.md index 8a9c2525..9a76fbb2 100644 --- a/example/w-graphql-subscription/README.md +++ b/example/w-graphql-subscription/README.md @@ -79,8 +79,8 @@ similar. **See also:** -- [**`i-graphql`**](../i-graphql#files) for a basic GraphQL example. -- [**`k-websocket`**](../k-websocket#files) for direct WebSocket usage. +- [**`i-graphql`**](../i-graphql#folders-and-files) for a basic GraphQL example. +- [**`k-websocket`**](../k-websocket#folders-and-files) for direct WebSocket usage.
    diff --git a/example/w-live-reload/README.md b/example/w-live-reload/README.md index cbad3eb1..76c94b64 100644 --- a/example/w-live-reload/README.md +++ b/example/w-live-reload/README.md @@ -50,7 +50,7 @@ Good morning, world! Random tag: jRak
    -This example plays very well with [**`w-watch`**](../w-watch#files), which shows +This example plays very well with [**`w-watch`**](../w-watch#folders-and-files), which shows 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 reloading all the way to the client, whenever any of the server's source code @@ -60,8 +60,8 @@ changes. **See also:** -- [**`k-websocket`**](../k-websocket#files) introduces WebSockets. -- [**`w-watch`**](../w-watch#files) rebuilds and restarts a server each +- [**`k-websocket`**](../k-websocket#folders-and-files) introduces WebSockets. +- [**`w-watch`**](../w-watch#folders-and-files) rebuilds and restarts a server each time its source code changes.
    diff --git a/example/w-long-polling/README.md b/example/w-long-polling/README.md index 6120adf2..bbbce665 100644 --- a/example/w-long-polling/README.md +++ b/example/w-long-polling/README.md @@ -3,7 +3,7 @@
    *Long polling* is a technique, largely made obsolete by -[WebSockets](../k-websocket#files), where a client sends a request, but the +[WebSockets](../k-websocket#folders-and-files), where a client sends a request, but the 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 a time of the server's choosing. @@ -46,7 +46,7 @@ polling.” **See also:** -- [**`k-websocket`**](../k-websocket#files) for a more modern way of achieving +- [**`k-websocket`**](../k-websocket#folders-and-files) for a more modern way of achieving asynchronous client-server communication.
    diff --git a/example/w-mirage/README.md b/example/w-mirage/README.md index 39c5b864..7a776a6c 100644 --- a/example/w-mirage/README.md +++ b/example/w-mirage/README.md @@ -45,7 +45,7 @@ end
    -It's the basic example [**`2-middleware`**](../2-middleware#files) adapted to +It's the basic example [**`2-middleware`**](../2-middleware#folders-and-files) adapted to Mirage. To build and run, do

    $ cd example/w-mirage
    diff --git a/example/w-multipart-dump/README.md b/example/w-multipart-dump/README.md
    index ec7c4ce6..5c431461 100644
    --- a/example/w-multipart-dump/README.md
    +++ b/example/w-multipart-dump/README.md
    @@ -55,8 +55,8 @@ curl -F 'a=b' http://localhost:8080/
     
     **See also:**
     
    -- [**`g-upload`**](../g-upload#files) is the proper file upload example.
    -- [**`6-echo`**](../6-echo#files) is a proper echo example :)
    +- [**`g-upload`**](../g-upload#folders-and-files) is the proper file upload example.
    +- [**`6-echo`**](../6-echo#folders-and-files) is a proper echo example :)
     
     
    diff --git a/example/w-nginx/README.md b/example/w-nginx/README.md index 904b50d8..9472cc20 100644 --- a/example/w-nginx/README.md +++ b/example/w-nginx/README.md @@ -150,11 +150,11 @@ docker-compose logs web -f **See also:** -- [**`f-static`**](../f-static#files) has Dream serve static files on its own, +- [**`f-static`**](../f-static#folders-and-files) has Dream serve static files on its own, without a reverse proxy. -- [**`z-docker-esy`**](../z-docker-esy#files) deploys to Digital Ocean with +- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) deploys to Digital Ocean with Docker Compose and esy, including Docker installation instructions. -- [**`z-docker-opam`**](../z-docker-opam#files) deploys with Docker Compose and +- [**`z-docker-opam`**](../z-docker-opam#folders-and-files) deploys with Docker Compose and opam.
    diff --git a/example/w-one-binary/README.md b/example/w-one-binary/README.md index 89313d8d..e85492d6 100644 --- a/example/w-one-binary/README.md +++ b/example/w-one-binary/README.md @@ -111,10 +111,10 @@ To add more files, just add them to the `assets/` directory and re-run **See also:** -- [**`w-esy`**](../w-esy#files) for details on packaging with esy. -- [**`w-watch`**](../w-watch#files) for a primitive watcher, which can be +- [**`w-esy`**](../w-esy#folders-and-files) for details on packaging with esy. +- [**`w-watch`**](../w-watch#folders-and-files) for a primitive watcher, which can be extended to watch `assets/`. -- [**`f-static`**](../f-static#files) shows the basics of +- [**`f-static`**](../f-static#folders-and-files) shows the basics of [`Dream.static`](https://aantron.github.io/dream/#val-static).
    diff --git a/example/w-postgres/README.md b/example/w-postgres/README.md index 39b7f90a..f8598481 100644 --- a/example/w-postgres/README.md +++ b/example/w-postgres/README.md @@ -9,7 +9,7 @@ Web server with a PostgreSQL database. The [code](https://github.com/aantron/dream/blob/master/example/w-postgres/postgres.eml.ml) -is almost identical to [**`h-sql`**](../h-sql#files). The only differences are: +is almost identical to [**`h-sql`**](../h-sql#folders-and-files). The only differences are: - we now listen on `"0.0.0.0"`, since our client will definitely be outside the Docker container, so not on `localhost`, and @@ -108,11 +108,11 @@ Tips: **See also:** -- [**`h-sql`**](../h-sql#files) is the SQLite, non-Docker version of this +- [**`h-sql`**](../h-sql#folders-and-files) is the SQLite, non-Docker version of this example. -- [**`z-docker-esy`**](../z-docker-esy#files) deploys to Digital Ocean with +- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) deploys to Digital Ocean with Docker Compose and esy, including Docker installation instructions. -- [**`z-docker-opam`**](../z-docker-opam#files) deploys with Docker Compose and +- [**`z-docker-opam`**](../z-docker-opam#folders-and-files) deploys with Docker Compose and opam.
    diff --git a/example/w-server-sent-events/README.md b/example/w-server-sent-events/README.md index 7c1624c9..f1286647 100644 --- a/example/w-server-sent-events/README.md +++ b/example/w-server-sent-events/README.md @@ -42,9 +42,9 @@ interface to server-sent events. **See also:** -- [**`k-websocket`**](../k-websocket#files) for WebSockets, which largely +- [**`k-websocket`**](../k-websocket#folders-and-files) for WebSockets, which largely supersede server-sent events. -- [**`w-template-stream`**](../w-template-stream#files) for another example of +- [**`w-template-stream`**](../w-template-stream#folders-and-files) for another example of “real-time” streaming with [`Dream.flush`](https://aantron.github.io/dream/#val-flush). diff --git a/example/w-template-files/README.md b/example/w-template-files/README.md index 7dc0c5cb..0d1d2323 100644 --- a/example/w-template-files/README.md +++ b/example/w-template-files/README.md @@ -3,7 +3,7 @@
    This example splits the code of the basic template example, -[**`7-template`**](../7-template#files), into two files. The first is the +[**`7-template`**](../7-template#folders-and-files), into two files. The first is the template, in [`template.eml.html`](https://github.com/aantron/dream/blob/master/example/w-template-files/template.eml.html). We use the `.html` extension because it is mostly HTML, and to prevent @@ -46,7 +46,7 @@ let () = **See also:** -- [**`7-template`**](../7-template#files) for comments on the [`dune` +- [**`7-template`**](../7-template#folders-and-files) for comments on the [`dune` file](https://github.com/aantron/dream/blob/master/example/w-template-files/dune) and [security information](https://github.com/aantron/dream/tree/master/example/7-template#security). diff --git a/example/w-template-logic/README.md b/example/w-template-logic/README.md index bcc1d053..8ca45311 100644 --- a/example/w-template-logic/README.md +++ b/example/w-template-logic/README.md @@ -75,8 +75,8 @@ let () = **See also:** -- [**`7-template`**](../7-template#files) for more information about templates. -- [**`r-template-logic`**](../r-template-logic#files) for the Reason syntax +- [**`7-template`**](../7-template#folders-and-files) for more information about templates. +- [**`r-template-logic`**](../r-template-logic#folders-and-files) for the Reason syntax version of this example.
    diff --git a/example/w-template-stream/README.md b/example/w-template-stream/README.md index 95557cf1..609dbf75 100644 --- a/example/w-template-stream/README.md +++ b/example/w-template-stream/README.md @@ -44,7 +44,7 @@ here to prevent buffering of each paragraph. - [**`7-template`**](../7-template#security) section *Security* on security considerations with templates, and in general. -- [**`r-template-stream`**](../r-template-stream#files) is a Reason syntax +- [**`r-template-stream`**](../r-template-stream#folders-and-files) is a Reason syntax version of this example.
    diff --git a/example/w-tyxml/README.md b/example/w-tyxml/README.md index 4ddffc46..dc68e710 100644 --- a/example/w-tyxml/README.md +++ b/example/w-tyxml/README.md @@ -43,7 +43,7 @@ let () = When using Reason, TyXML supports JSX, through package [`tyxml-jsx`](https://ocsigen.org/tyxml/latest/manual/jsx). See -[**`r-tyxml`**](../r-tyxml#files) for a complete example, including Dune +[**`r-tyxml`**](../r-tyxml#folders-and-files) for a complete example, including Dune metadata. ```reason @@ -102,7 +102,7 @@ this, please [open an issue](https://github.com/aantron/dream/issues). - [**`7-template`**](../7-template#security) section *Security* on output security. TyXML escapes strings by default, just as the built-in templater does. -- [**`r-tyxml`**](../r-tyxml#files) is the Reason and JSX version of this +- [**`r-tyxml`**](../r-tyxml#folders-and-files) is the Reason and JSX version of this example.
    diff --git a/example/w-upload-stream/README.md b/example/w-upload-stream/README.md index 5287d042..8d57e3b4 100644 --- a/example/w-upload-stream/README.md +++ b/example/w-upload-stream/README.md @@ -2,7 +2,7 @@
    -This example is a variant of [**`g-upload`**](../g-upload#files) that +This example is a variant of [**`g-upload`**](../g-upload#folders-and-files) that [streams](https://aantron.github.io/dream/#streaming-uploads) uploaded files one chunk at a time, instead of loading them completely into memory. It counts the total size of each uploaded file: @@ -84,9 +84,9 @@ for a checklist of additional security precautions. **See also:** -- [**`g-upload`**](../g-upload#files) shows the simplified interface for +- [**`g-upload`**](../g-upload#folders-and-files) shows the simplified interface for receiving file uploads. -- [**`w-multipart-dump`**](../w-multipart-dump#files) shows the request body +- [**`w-multipart-dump`**](../w-multipart-dump#folders-and-files) shows the request body that is parsed by [`Dream.upload`](https://aantron.github.io/dream/#val-upload). diff --git a/example/w-watch/README.md b/example/w-watch/README.md index 3322c484..d96b01c9 100644 --- a/example/w-watch/README.md +++ b/example/w-watch/README.md @@ -15,9 +15,9 @@ Note that this requires Dune 3.7.0 or higher. **See also:** -- [**`w-live-reload`**](../w-live-reload#files) adds live reloading, so that +- [**`w-live-reload`**](../w-live-reload#folders-and-files) adds live reloading, so that browsers reload when the server is restarted. -- [**`w-esy`**](../w-esy#files) discusses [esy](https://esy.sh/) packaging. +- [**`w-esy`**](../w-esy#folders-and-files) discusses [esy](https://esy.sh/) packaging.
    diff --git a/example/z-docker-esy/README.md b/example/z-docker-esy/README.md index 508771a7..62602d0d 100644 --- a/example/z-docker-esy/README.md +++ b/example/z-docker-esy/README.md @@ -171,11 +171,11 @@ version of the deploy script. **See also:** -- [**`z-docker-opam`**](../z-docker-opam#files) is a variant of this example +- [**`z-docker-opam`**](../z-docker-opam#folders-and-files) is a variant of this example that uses opam instead of esy. -- [**`z-systemd`**](../z-systemd#files) packages the app as a systemd daemon, +- [**`z-systemd`**](../z-systemd#folders-and-files) packages the app as a systemd daemon, outside of a Docker container. -- [**`z-heroku`**](../z-heroku#files) deploys the app to +- [**`z-heroku`**](../z-heroku#folders-and-files) deploys the app to [Heroku](https://heroku.com).
    diff --git a/example/z-docker-opam/README.md b/example/z-docker-opam/README.md index 9c9e1130..0ff4b0b3 100644 --- a/example/z-docker-opam/README.md +++ b/example/z-docker-opam/README.md @@ -3,11 +3,11 @@
    This example runs a simple Web app inside a [Docker](https://www.docker.com/) -container. It is a variant of [**`z-docker-esy`**](../z-docker-esy#files), but +container. It is a variant of [**`z-docker-esy`**](../z-docker-esy#folders-and-files), but with [opam](https://opam.ocaml.org/) as the package manager. All the instructions are the same as in -[**`z-docker-esy`**](../z-docker-esy#files). The difference is in the +[**`z-docker-esy`**](../z-docker-esy#folders-and-files). The difference is in the [`Dockerfile`](https://github.com/aantron/dream/blob/master/example/z-docker-opam/Dockerfile), 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 diff --git a/example/z-heroku/README.md b/example/z-heroku/README.md index 45eecbce..68337297 100644 --- a/example/z-heroku/README.md +++ b/example/z-heroku/README.md @@ -11,7 +11,7 @@ is that it imposes some constraints on your app, such as no persistent local state. Many apps satisfy these constraints, however. The code is essentially example -[**`2-middleware`**](../2-middleware#files), but Heroku will pass the desired +[**`2-middleware`**](../2-middleware#folders-and-files), but Heroku will pass the desired port number in environment variable `PORT`, so we read it: ```ocaml @@ -180,9 +180,9 @@ by Aleksandra Sikora. **See also:** -- [**`z-docker-esy`**](../z-docker-esy#files) deploys to a dedicated server, +- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) deploys to a dedicated server, with the Web application managed by Docker Compose. -- [**`z-systemd`**](../z-systemd#files) deploys to a dedicated server, running +- [**`z-systemd`**](../z-systemd#folders-and-files) deploys to a dedicated server, running the Web application as a systemd daemon.
    diff --git a/example/z-playground/README.md b/example/z-playground/README.md index 1da04c33..d58d4c41 100644 --- a/example/z-playground/README.md +++ b/example/z-playground/README.md @@ -35,8 +35,8 @@ docker ps **See also:** -- [**`k-websocket`**](../k-websocket#files) introduces WebSockets. -- [**`z-systemd`**](../z-systemd#files) packages a tiny app for management by +- [**`k-websocket`**](../k-websocket#folders-and-files) introduces WebSockets. +- [**`z-systemd`**](../z-systemd#folders-and-files) packages a tiny app for management by systemd.
    diff --git a/example/z-playground/client/client.eml.html b/example/z-playground/client/client.eml.html index 602fd12b..a028e649 100644 --- a/example/z-playground/client/client.eml.html +++ b/example/z-playground/client/client.eml.html @@ -13,7 +13,7 @@ let example = Dream.html_escape example in let url = Printf.sprintf - "https://github.com/aantron/dream/tree/master/example/%s#files" + "https://github.com/aantron/dream/tree/master/example/%s#folders-and-files" example in " — " ^ example, Printf.sprintf diff --git a/example/z-systemd/README.md b/example/z-systemd/README.md index 75ef1613..56b91eef 100644 --- a/example/z-systemd/README.md +++ b/example/z-systemd/README.md @@ -183,10 +183,10 @@ very convenient way of passing it to the action. **See also:** -- [**`z-docker-esy`**](../z-docker-esy#files) packages the app using [Docker +- [**`z-docker-esy`**](../z-docker-esy#folders-and-files) packages the app using [Docker Compose](https://docs.docker.com/compose/), instead of running it directly with systemd. -- [**`z-heroku`**](../z-heroku#files) deploys the app to +- [**`z-heroku`**](../z-heroku#folders-and-files) deploys the app to [Heroku](https://heroku.com).
    diff --git a/src/mirage/mirage.mli b/src/mirage/mirage.mli index cbfc89df..06d73699 100644 --- a/src/mirage/mirage.mli +++ b/src/mirage/mirage.mli @@ -30,11 +30,11 @@ module Make 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} + {{:https://github.com/aantron/dream/tree/master/example/1-hello#folders-and-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 - {{:https://github.com/aantron/dream/tree/master/example/r-hello#files} + {{:https://github.com/aantron/dream/tree/master/example/r-hello#folders-and-files} [r-hello]}. {[ @@ -46,7 +46,7 @@ module Make and middleware = handler -> handler (** Middlewares are functions that take a {!handler}, and run some code before or after — producing a “bigger” handler. Example - {{:https://github.com/aantron/dream/tree/master/example/2-middleware#files} + {{:https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files} [2-middleware]} inserts the {!Dream.logger} middleware into a Web app: {[ @@ -57,9 +57,9 @@ module Make ]} Examples - {{:https://github.com/aantron/dream/tree/master/example/4-counter#files} + {{:https://github.com/aantron/dream/tree/master/example/4-counter#folders-and-files} [4-counter]} \[{{:http://dream.as/4-counter} playground}\] and - {{:https://github.com/aantron/dream/tree/master/example/5-promise#files} + {{:https://github.com/aantron/dream/tree/master/example/5-promise#folders-and-files} [5-promise]} show user-defined middlewares: {[ @@ -81,7 +81,7 @@ module Make 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} + {{:https://github.com/aantron/dream/tree/master/example/3-router#folders-and-files} [3-router]} \[{{:http://dream.as/3-router/echo/foo} playground}\]. Routes are created by helpers such as {!Dream.get} and {!Dream.scope}: @@ -131,7 +131,7 @@ module Make 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} + {{:https://github.com/aantron/dream/tree/master/example/5-promise#folders-and-files} [5-promise]} \[{{:http://dream.as/5-promise} playground}\]. Use [raise] to reject promises. If you are writing a library, you may prefer @@ -387,7 +387,7 @@ module Make (** First query parameter with the given name. See {{:https://tools.ietf.org/html/rfc3986#section-3.4} RFC 3986 §3.4} and example - {{:https://github.com/aantron/dream/tree/master/example/w-query#files} + {{:https://github.com/aantron/dream/tree/master/example/w-query#folders-and-files} [w-query]}. *) val queries : request -> string -> string list @@ -435,7 +435,7 @@ module Make As your Web app develops, consider adding [Content-Security-Policy] headers, as described in example - {{:https://github.com/aantron/dream/tree/master/example/w-content-security-policy#files} + {{:https://github.com/aantron/dream/tree/master/example/w-content-security-policy#folders-and-files} [w-content-security-policy]}. These headers are completely optional, but they can provide an extra layer of defense for a mature app. *) @@ -482,7 +482,7 @@ module Make (** Creates a fresh [101 Switching Protocols] response. Once this response is 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} + {{:https://github.com/aantron/dream/tree/master/example/k-websocket#folders-and-files} [k-websocket]} \[{{:http://dream.as/k-websocket} playground}\]. {[ @@ -573,7 +573,7 @@ module Make {!Dream.set_cookie} and {!Dream.cookie} are designed for round-tripping 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} + {{:https://github.com/aantron/dream/tree/master/example/c-cookie#folders-and-files} [c-cookie]} \[{{:http://dream.as/c-cookie} playground}\]. {[ @@ -619,7 +619,7 @@ module Make decrypt cookies from prior starts. See example - {{:https://github.com/aantron/dream/tree/master/example/c-cookie#files} + {{:https://github.com/aantron/dream/tree/master/example/c-cookie#folders-and-files} [c-cookie]}. Most of the optional arguments are for overriding inferred defaults. @@ -711,7 +711,7 @@ module Make string -> string option (** First cookie with the given name. See example - {{:https://github.com/aantron/dream/tree/master/example/c-cookie#files} + {{:https://github.com/aantron/dream/tree/master/example/c-cookie#folders-and-files} [c-cookie]}. {[ @@ -730,7 +730,7 @@ module Make val body : 'a message -> string promise (** Retrieves the entire body. See example - {{:https://github.com/aantron/dream/tree/master/example/6-echo#files} + {{:https://github.com/aantron/dream/tree/master/example/6-echo#folders-and-files} [6-echo]}. *) val set_body : 'a message -> string -> unit @@ -772,7 +772,7 @@ module Make response promise (** Creates a response with a {!type-stream} open for writing, and passes the stream to the callback when it is ready. See example - {{:https://github.com/aantron/dream/tree/master/example/j-stream#files} + {{:https://github.com/aantron/dream/tree/master/example/j-stream#folders-and-files} [j-stream]}. {[ @@ -786,7 +786,7 @@ module Make val read : stream -> string option promise (** Retrieves a body chunk. See example - {{:https://github.com/aantron/dream/tree/master/example/j-stream#files} + {{:https://github.com/aantron/dream/tree/master/example/j-stream#folders-and-files} [j-stream]}. *) (* TODO Document difference between receiving a request and receiving on a WebSocket. *) @@ -878,7 +878,7 @@ module Make for generating JSON parsers and serializers for OCaml data types. See example - {{:https://github.com/aantron/dream/tree/master/example/e-json#files} + {{:https://github.com/aantron/dream/tree/master/example/e-json#folders-and-files} [e-json]}. *) val origin_referrer_check : middleware @@ -928,7 +928,7 @@ module Make ]} See example - {{:https://github.com/aantron/dream/tree/master/example/d-form#files} + {{:https://github.com/aantron/dream/tree/master/example/d-form#folders-and-files} [d-form]} \[{{:http://dream.as/d-form} playground}\]. *) type 'a form_result = @@ -941,7 +941,7 @@ module Make | `Wrong_content_type ] (** Form CSRF checking results, in order from least to most severe. See {!Dream.val-form} and example - {{:https://github.com/aantron/dream/tree/master/example/d-form#files} + {{:https://github.com/aantron/dream/tree/master/example/d-form#folders-and-files} [d-form]}. The first three constructors, [`Ok], [`Expired], and [`Wrong_session] can @@ -1021,7 +1021,7 @@ module Make ]} See example - {{:https://github.com/aantron/dream/tree/master/example/g-upload#files} + {{:https://github.com/aantron/dream/tree/master/example/g-upload#folders-and-files} [g-upload]} \[{{:http://dream.as/g-upload} playground}\] and {{:https://datatracker.ietf.org/doc/html/rfc7578} RFC 7578}. @@ -1053,7 +1053,7 @@ module Make ]} See {!Dream.form_tag}, section {!section-templates}, and example - {{:https://github.com/aantron/dream/tree/master/example/g-upload#files} + {{:https://github.com/aantron/dream/tree/master/example/g-upload#folders-and-files} [g-upload]}. Note that, like {!Dream.form}, this function sorts form fields by field @@ -1153,19 +1153,19 @@ module Make v} See examples - {{:https://github.com/aantron/dream/tree/master/example/7-template#files} + {{:https://github.com/aantron/dream/tree/master/example/7-template#folders-and-files} [7-template]} \[{{:http://dream.as/7-template} playground}\] and - {{:https://github.com/aantron/dream/tree/master/example/r-template#files} + {{:https://github.com/aantron/dream/tree/master/example/r-template#folders-and-files} [r-template]} \[{{:http://dream.as/r-template} playground}\]. 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} + {{:https://github.com/aantron/dream/tree/master/example/w-tyxml#folders-and-files} [w-tyxml]} \[{{:http://dream.as/w-tyxml} playground}\]. 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} + {{:https://github.com/aantron/dream/tree/master/example/r-tyxml#folders-and-files} [r-tyxml]} \[{{:http://dream.as/r-tyxml} playground}\]. To use the built-in templates, add this to [dune]: @@ -1188,9 +1188,9 @@ module Make supported presently is [%% response] for streaming the template using {!Dream.write}, to a {!type-response} that is in scope. This is shown in examples - {{:https://github.com/aantron/dream/tree/master/example/w-template-stream#files} + {{:https://github.com/aantron/dream/tree/master/example/w-template-stream#folders-and-files} [w-template-stream]} and - {{:https://github.com/aantron/dream/tree/master/example/r-template-stream#files} + {{:https://github.com/aantron/dream/tree/master/example/r-template-stream#folders-and-files} [r-template-stream]}. A template ends... @@ -1282,7 +1282,7 @@ module Make (** Creates a router. If none of the routes match the request, the router returns {!Dream.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} + {{:https://github.com/aantron/dream/tree/master/example/3-router#folders-and-files} [3-router]} \[{{:http://dream.as/3-router} playground}\]. {[ @@ -1390,7 +1390,7 @@ module Make val static : loader:(string -> string -> handler) -> string -> handler (** Serves static files from a local directory. See example - {{:https://github.com/aantron/dream/tree/master/example/f-static#files} + {{:https://github.com/aantron/dream/tree/master/example/f-static#folders-and-files} [f-static]}. {[ @@ -1416,7 +1416,7 @@ module Make - [path] is what was substituted for [**]. The default loader is {!Dream.from_filesystem}. See example - {{:https://github.com/aantron/dream/tree/master/example/w-one-binary#files} + {{:https://github.com/aantron/dream/tree/master/example/w-one-binary#folders-and-files} [w-one-binary]} for a loader that serves files from memory instead. *) val mime_lookup : string -> (string * string) list @@ -1456,7 +1456,7 @@ module Make the next request that it is assigned to. See example - {{:https://github.com/aantron/dream/tree/master/example/b-session#files} + {{:https://github.com/aantron/dream/tree/master/example/b-session#folders-and-files} [b-session]} \[{{:http://dream.as/b-session} playground}\]. *) val session : string -> request -> string option @@ -1499,7 +1499,7 @@ module Make Flash messages are short strings which are stored in cookies during one 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} + {{:https://github.com/aantron/dream/tree/master/example/w-flash#folders-and-files} [w-flash]} \[{{:http://dream.as/w-flash} playground}\]. *) val flash_messages : middleware @@ -1527,7 +1527,7 @@ module Make 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} + {{:https://github.com/aantron/dream/tree/master/example/2-middleware#folders-and-files} [2-middleware]} \[{{:http://dream.as/2-middleware} playground}\]. *) val log : ('a, Format.formatter, unit, unit) format4 -> 'a @@ -1536,7 +1536,7 @@ module Make {{:https://v2.ocaml.org/api/Printf.html#VALfprintf} [Printf]} and {{: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} + {{:https://github.com/aantron/dream/tree/master/example/a-log#folders-and-files} [a-log]} \[{{:http://dream.as/a-log} playground}\]. {[ @@ -1561,7 +1561,7 @@ module Make (** Formats a message and writes it to the log at level [`Error]. The inner formatting function is called only if the {{!initialize_log} current log level} is [`Error] or higher. See example - {{:https://github.com/aantron/dream/tree/master/example/a-log#files} + {{:https://github.com/aantron/dream/tree/master/example/a-log#folders-and-files} [a-log]}. {[ @@ -1607,7 +1607,7 @@ module Make unless {!Dream.set_log_level} is used. See [README] of example - {{:https://github.com/aantron/dream/tree/master/example/a-log#files} + {{:https://github.com/aantron/dream/tree/master/example/a-log#folders-and-files} [a-log]}. *) val initialize_log : @@ -1771,7 +1771,7 @@ module Make 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} + {{:https://github.com/aantron/dream/tree/master/example/9-error#folders-and-files} [9-error]} \[{{:http://dream.as/9-error} playground}\]. {[