Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rgrinberg/opium
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.17.0
Choose a base ref
...
head repository: rgrinberg/opium
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 11,139 additions and 1,937 deletions.
  1. +1 −0 .gitattributes
  2. +23 −0 .github/workflows/changelog.yml
  3. +41 −0 .github/workflows/ci.yml
  4. +14 −49 .gitignore
  5. +3 −0 .ocamlformat
  6. +0 −1 .ocp-indent
  7. +0 −34 .travis.yml
  8. +86 −0 CHANGES.md
  9. +21 −0 LICENSE
  10. +94 −13 Makefile
  11. +52 −32 README.cpp.md
  12. +120 −76 README.md
  13. +33 −0 benchmark/README.md
  14. BIN benchmark/result/histogram.png
  15. +111 −0 benchmark/result/httpaf.log
  16. +112 −0 benchmark/result/opium.log
  17. +39 −0 benchmark/run.sh
  18. +9 −0 benchmark/src/dune
  19. +71 −0 benchmark/src/httpaf.ml
  20. +32 −0 benchmark/src/opium.ml
  21. +9 −0 default.nix
  22. +8 −0 dune
  23. +99 −1 dune-project
  24. +12 −5 dune-workspace.dev
  25. +16 −0 example/README.md
  26. +6 −0 example/dune
  27. +9 −0 example/exit_hook/README.md
  28. +3 −0 example/exit_hook/dune
  29. +16 −0 example/exit_hook/main.ml
  30. +16 −0 example/file_upload/README.md
  31. +3 −0 example/file_upload/dune
  32. +262 −0 example/file_upload/main.ml
  33. +53 −0 example/file_upload/simple.ml
  34. +22 −0 example/graphql/README.md
  35. +3 −0 example/graphql/dune
  36. +81 −0 example/graphql/main.ml
  37. +11 −0 example/hello_world/README.md
  38. +3 −0 example/hello_world/dune
  39. +53 −0 example/hello_world/main.ml
  40. +18 −0 example/html_response/README.md
  41. +3 −0 example/html_response/dune
  42. +4 −0 example/html_response/main.ml
  43. +120 −0 example/html_response/view.ml
  44. +9 −0 example/json_request/README.md
  45. +3 −0 example/json_request/dune
  46. +9 −0 example/json_request/main.ml
  47. +14 −0 example/json_response/README.md
  48. +3 −0 example/json_response/dune
  49. +10 −0 example/json_response/main.ml
  50. +7 −0 example/rock_server/README.md
  51. +3 −0 example/rock_server/dune
  52. +70 −0 example/rock_server/main.ml
  53. +7 −0 example/simple_middleware/README.md
  54. +3 −0 example/simple_middleware/dune
  55. +29 −0 example/simple_middleware/main.ml
  56. +10 −0 example/static_serve/README.md
  57. BIN example/static_serve/asset/favicon.ico
  58. +2 −0 example/static_serve/asset/robots.txt
  59. +3 −0 example/static_serve/dune
  60. +8 −0 example/static_serve/main.ml
  61. +21 −0 example/user_auth/README.md
  62. +3 −0 example/user_auth/dune
  63. +55 −0 example/user_auth/main.ml
  64. +0 −45 examples/auth_middleware.ml
  65. +0 −15 examples/dune
  66. +0 −19 examples/exit_hook_example.ml
  67. +0 −29 examples/hello_world.ml
  68. +0 −8 examples/hello_world_basic.ml
  69. +0 −21 examples/hello_world_html.ml
  70. +0 −23 examples/middleware_ua.ml
  71. +0 −11 examples/read_json_body.ml
  72. +0 −81 examples/sample.ml
  73. +0 −22 examples/static_serve_override.ml
  74. +0 −18 examples/uppercase_middleware.ml
  75. +0 −8 lib_test/dune
  76. +0 −146 lib_test/routes.ml
  77. +24 −0 nix/default.nix
  78. +1,313 −0 nix/opam-selection.nix
  79. +4 −0 nix/opam2nix.nix
  80. +37 −0 opium-graphql.opam
  81. +76 −0 opium-graphql/asset/graphiql.html
  82. +2 −0 opium-graphql/doc/dune
  83. +112 −0 opium-graphql/doc/index.mld
  84. +11 −0 opium-graphql/src/dune
  85. +171 −0 opium-graphql/src/opium_graphql.ml
  86. +29 −0 opium-graphql/src/opium_graphql.mli
  87. +4 −0 opium-graphql/test/dune
  88. +157 −0 opium-graphql/test/request_test.ml
  89. +34 −0 opium-testing.opam
  90. +2 −0 opium-testing/doc/dune
  91. +79 −0 opium-testing/doc/index.mld
  92. +4 −0 opium-testing/src/dune
  93. +123 −0 opium-testing/src/opium_testing.ml
  94. +160 −0 opium-testing/src/opium_testing.mli
  95. +41 −30 opium.opam
  96. +0 −272 opium/app.ml
  97. +0 −104 opium/app.mli
  98. +0 −31 opium/debug.ml
  99. +0 −4 opium/debug.mli
  100. +2 −0 opium/doc/dune
  101. +73 −0 opium/doc/index.mld
  102. +0 −10 opium/dune
  103. +0 −39 opium/opium.ml
  104. +394 −0 opium/src/app.ml
  105. +78 −0 opium/src/app.mli
  106. +57 −0 opium/src/auth.ml
  107. +49 −0 opium/src/auth.mli
  108. +50 −0 opium/src/body.ml
  109. +67 −0 opium/src/body.mli
  110. +23 −0 opium/src/context.ml
  111. +108 −0 opium/src/context.mli
  112. +562 −0 opium/src/cookie.ml
  113. +203 −0 opium/src/cookie.mli
  114. +7 −0 opium/src/dune
  115. +45 −0 opium/src/handlers/handler_serve.ml
  116. +6 −0 opium/src/handlers/handler_serve.mli
  117. +15 −0 opium/src/headers.ml
  118. +161 −0 opium/src/headers.mli
  119. +53 −0 opium/src/import.ml
  120. +5 −0 opium/src/method.ml
  121. +82 −0 opium/src/method.mli
  122. +106 −0 opium/src/middlewares/middleware_allow_cors.ml
  123. +10 −0 opium/src/middlewares/middleware_allow_cors.mli
  124. +31 −0 opium/src/middlewares/middleware_basic_auth.ml
  125. +7 −0 opium/src/middlewares/middleware_basic_auth.mli
  126. +14 −0 opium/src/middlewares/middleware_content_length.ml
  127. +1 −0 opium/src/middlewares/middleware_content_length.mli
  128. +99 −0 opium/src/middlewares/middleware_debugger.ml
  129. +1 −0 opium/src/middlewares/middleware_debugger.mli
  130. +50 −0 opium/src/middlewares/middleware_etag.ml
  131. +1 −0 opium/src/middlewares/middleware_etag.mli
  132. +30 −0 opium/src/middlewares/middleware_head.ml
  133. +1 −0 opium/src/middlewares/middleware_head.mli
  134. +88 −0 opium/src/middlewares/middleware_logger.ml
  135. +2 −0 opium/src/middlewares/middleware_logger.mli
  136. +23 −0 opium/src/middlewares/middleware_method_override.ml
  137. +1 −0 opium/src/middlewares/middleware_method_override.mli
  138. +12 −0 opium/src/middlewares/middleware_method_required.ml
  139. +1 −0 opium/src/middlewares/middleware_method_required.mli
  140. +63 −0 opium/src/middlewares/middleware_router.ml
  141. +7 −0 opium/src/middlewares/middleware_router.mli
  142. +54 −0 opium/src/middlewares/middleware_static.ml
  143. +7 −0 opium/src/middlewares/middleware_static.mli
  144. +27 −0 opium/src/middlewares/middleware_static_unix.ml
  145. +7 −0 opium/src/middlewares/middleware_static_unix.mli
  146. +9 −0 opium/src/nifty.ml
  147. +32 −0 opium/src/opium.ml
  148. +245 −0 opium/src/opium.mli
  149. +232 −0 opium/src/request.ml
  150. +649 −0 opium/src/request.mli
  151. +241 −0 opium/src/response.ml
  152. +608 −0 opium/src/response.mli
  153. +116 −0 opium/src/route.ml
  154. +21 −0 opium/src/route.mli
  155. +162 −0 opium/src/status.ml
  156. +164 −0 opium/src/status.mli
  157. +13 −0 opium/src/version.ml
  158. +44 −0 opium/src/version.mli
  159. +0 −67 opium/static_serve.ml
  160. +0 −11 opium/static_serve.mli
  161. +32 −0 opium/test/cookie.ml
  162. +4 −0 opium/test/dune
  163. +130 −0 opium/test/middleware_allow_cors.ml
  164. +178 −0 opium/test/request.ml
  165. +206 −0 opium/test/response.ml
  166. +209 −0 opium/test/route.ml
  167. +0 −36 opium_kernel.opam
  168. +0 −83 opium_kernel/cookie.ml
  169. +0 −33 opium_kernel/cookie.mli
  170. +0 −10 opium_kernel/dune
  171. +0 −14 opium_kernel/hmap0.ml
  172. +0 −5 opium_kernel/hmap0.mli
  173. +0 −124 opium_kernel/misc.ml
  174. +0 −13 opium_kernel/opium_kernel.ml
  175. +0 −116 opium_kernel/rock.ml
  176. +0 −109 opium_kernel/rock.mli
  177. +0 −83 opium_kernel/route.ml
  178. +0 −65 opium_kernel/router.ml
  179. +0 −14 opium_kernel/router.mli
  180. +0 −7 opium_kernel/std.ml
  181. +37 −0 rock.opam
  182. +2 −0 rock/doc/dune
  183. +62 −0 rock/doc/index.mld
  184. +7 −0 rock/src/app.ml
  185. +7 −0 rock/src/app.mli
  186. +96 −0 rock/src/body.ml
  187. +64 −0 rock/src/body.mli
  188. +3 −0 rock/src/context.ml
  189. +108 −0 rock/src/context.mli
  190. +3 −0 rock/src/dune
  191. +5 −0 rock/src/filter.ml
  192. +13 −0 rock/src/filter.mli
  193. +1 −0 rock/src/handler.ml
  194. +3 −0 rock/src/handler.mli
  195. +7 −0 rock/src/middleware.ml
  196. +9 −0 rock/src/middleware.mli
  197. +42 −0 rock/src/request.ml
  198. +91 −0 rock/src/request.mli
  199. +20 −0 rock/src/response.ml
  200. +29 −0 rock/src/response.mli
  201. +10 −0 rock/src/rock.ml
  202. +14 −0 rock/src/rock.mli
  203. +139 −0 rock/src/server_connection.ml
  204. +32 −0 rock/src/server_connection.mli
  205. +1 −0 rock/src/service.ml
  206. +3 −0 rock/src/service.mli
  207. +9 −0 shell.nix
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nix/opam-selection.nix linguist-generated=true
23 changes: 23 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Changelog

on:
pull_request:
branches: [ master ]
types: [ opened, synchronize, reopened, labeled, unlabeled ]

jobs:
build:
name: Check changelog entry

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v1

- name: Check CHANGES.md changed
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no changelog') }}
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
! git diff --exit-code origin/$BASE_REF -- CHANGES.md
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: CI

on: [push, pull_request]

jobs:
build:
name: Build and test

runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest
- windows-latest
ocaml-compiler:
- 4.13.x
include:
- os: ubuntu-latest
ocaml-compiler: 4.08.x

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Use OCaml ${{ matrix.ocaml-version }}
uses: ocaml/setup-ocaml@v2
with:
ocaml-compiler: ${{ matrix.ocaml-compiler }}
dune-cache: ${{ matrix.os != 'macos-latest' }}
opam-depext-flags: --with-test

- run: opam install . --deps-only --with-test

- name: Run tests
run: make test

- name: Build examples
run: opam exec -- dune build @example
63 changes: 14 additions & 49 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,53 +1,18 @@
*.cmt
*.cmti
*.o
*.cmo
*.cma
*.cmxs
*.opt
*.run
*.cmi
*.cmx
*.cmxa
*.annot
*.depends
*.cmxi
*.mllib
*.mldylib
*.mlpack
*.odocl
*.odocdir
*.docl
*.docdir
*.cmt
*.a

# ocamlbuild working directory
_build/
examples/_build/

# ocamlbuild targets
*.byte
*.native
myocamlbuild.ml
setup.data
setup.log
setup.ml
META
_tags
TAGS
*.omc
*.omakedb
.omakedb.lock
_tests

examples/auth_middleware
examples/exit_hook_example
examples/hello_world
examples/hello_world_basic
examples/hello_world_html
examples/middleware_ua
examples/read_json_body
examples/sample
examples/static_serve_override
examples/uppercase_middleware
lib_test/routes
*.merlin
# Merlin configuring file for Vim and Emacs
.merlin

# Dune generated files
*.install
_opam

# Local OPAM switch
_opam/

# Nix-build geenrated artifact
result
3 changes: 3 additions & 0 deletions .ocamlformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
profile = janestreet
parse-docstrings = true
wrap-comments = true
1 change: 0 additions & 1 deletion .ocp-indent

This file was deleted.

34 changes: 0 additions & 34 deletions .travis.yml

This file was deleted.

86 changes: 86 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Unreleased

## Added

- Change type signature of static and static_unix middlewares to get ETag as promise.
- Make static_unix middleware derive ETag from file modification timestamp.
- `App.debug` and `App.verbose`
- Give access to client's sockaddr from within an Opium handler

## Fixed

- Fix Fullsplat behavior (routes with `**`)
- Undo splat reverse order. Now, the matches for `/*/*/*` with the url `/a/b/c` will return `["a"; "b"; "c"]`
- deprecated `Term` commands

## Changed

- Update various opium-testing apis to avoid raising warning 16
- replacing `mirage-crypto` with `digestif`, because `mirage-crypto` doesn't provide `md5` and `sha1` anymore

# 0.20.0

## Added

- New `Auth` module to work with `Authorization` header (#238)
- New `basic_auth` middleware to protect handlers with a `Basic` authentication method (#238)
- New `Response.of_file` API for conveniently creating a response of a file (#244)
- Add a package `opium-graphql` to easily create GraphQL server with Opium (#235)
- Add a function `App.run_multicore` that uses pre-forking and spawns multiple processes that will handle incoming requests (#239)

## Fixed

- Fix reading cookie values when multiple cookies are present in `Cookie` header (#246)

# 0.19.0

This release is a complete rewrite of the Opium's internal that switches from Cohttp to Httpaf.
As demonstrated in several benchmarks, Httpaf's latency is much lower than Cohttp's in stress tests, so it is expected that Opium will perform better in these high pressure situations with this change.

The underlying HTTP server implementation is now contained in the `rock` package, that provides a Service and Filter implementation, inspired by Finagle's. The architecture is similar to Ruby's Rack library (hence the name), so one can compose complex web applications by combining Rock applications.

The `rock` package offers a very slim API, with very few dependencies, so it should be an attractive option for other Web framework to build on, which would allow the re-usability of middlewares and handlers, independently of the framework used (e.g. one could use Sihl middlewares with Opium, and vice versa).

Apart from the architectural changes, this release comes with a lot of additionnal utilities and middlewares which should make Opium a better candidate for complex web applications, without having to re-write a lot of common Web server functionnalities.

The Request and Response modules now provide:

- JSON encoders/decoders with `Yojson`
- HTML encoders/decoders with `Tyxml`
- XML encoders/decoders with `Tyxml`
- SVG encoders/decoders with `Tyxml`
- multipart/form encoders/decoders with `multipart_form_data`
- urlencoded encoders/decoders with `Uri`

And the following middlewares are now built-in:

- `debugger` to display an HTML page with the errors in case of failures
- `logger` to log requests and responses, with a timer
- `allow_cors` to add CORS headers
- `static` to serve static content given a custom read function (e.g. read from S3)
- `static_unix` to to serve static content from the local filesystem
- `content_length` to add the `Content-Length` header to responses
- `method_override` to replace the HTTP method with the one found in the `_method` field of `application/x-www-form-urlencoded` encoded `POST` requests.
- `etag` to add `ETag` header to the responses and send an HTTP code `304` when the computed ETag matches the one specified in the request.
- `method_required` to filter the requests by method and respond with an HTTP code `405` if the method is not allowed.
- `head` to add supports for `HEAD` request for handlers that receive `GET` requests.

Lastly, this release also adds a package `opium-testing` that can be used to test Opium applications with `Alcotest`. It provides `Testable` modules for every Opium types, and implements helper functions to easily get an `Opium.Response` from an `Opium.Request`.

# 0.18.0

* Make examples easier to find and add documentation related to features used in them. (#125, @shonfeder)
* Allow overriding 404 handlers (#127, @anuragsoni)
* Support cohttp streaming response (#135, #137, #139, @anuragsoni)

# v0.17.1

* Change Deferred.t to Lwt.t in readme (#91, @rymdhund)
* Remove `cow` from deps (#92, @anuragsoni)

# v0.17.0

* Switch to dune (#88, @anuragsoni)
* Keep the "/" cookie default and expose all cookie directives (#82, @actionshrimp)
* Do not assume base 64 encoding of cookies (#74, @malthe)
* Add caching capabilities to middleware (#76, @mattjbray)
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Rudi Grinberg

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading