Skip to content

Commit 4cb35ba

Browse files
committed
First commit
0 parents  commit 4cb35ba

22 files changed

+722
-0
lines changed

.github/workflows/test.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: erlef/setup-beam@v1
16+
with:
17+
otp-version: "26.0.2"
18+
gleam-version: "1.1.0"
19+
rebar3-version: "3"
20+
# elixir-version: "1.15.4"
21+
- run: gleam deps download
22+
- run: gleam test
23+
- run: gleam format --check src test

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump

.prettierrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "printWidth": 80, "proseWrap": "always" }

README.md

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# cors
2+
3+
## Middlewares
4+
5+
```gleam
6+
import gleam/http
7+
import mist
8+
import simple_cors as cors
9+
import wisp.{type Request, type Response}
10+
11+
fn cors() {
12+
cors.new()
13+
|> cors.allow_origin("http://localhost:3000")
14+
|> cors.allow_origin("http://localhost:4000")
15+
|> cors.allow_method(http.Get)
16+
|> cors.allow_method(http.Post)
17+
}
18+
19+
fn handler(req: Request) -> Response {
20+
use req <- cors.wisp_handle(req, cors())
21+
wisp.ok()
22+
}
23+
24+
fn main() {
25+
handler
26+
|> wisp.mist_handler(secret_key)
27+
|> mist.new()
28+
|> mist.port(3000)
29+
|> mist.start_http()
30+
}
31+
```
32+
33+
## What is CORS?
34+
35+
Browsers apply a simple rules for every HTTP request: when the request
36+
originates from a different origin than the target server URL — and if it's not
37+
a simple request — the browser needs to authorize the cross-origin call.
38+
39+
> From the HTTP point of view, a simple request respects the following
40+
> conditions:
41+
>
42+
> - Allowed methods are `GET`, `HEAD` or `POST`
43+
> - Allowed headers are `Accept`, `Accept-Language`, `Content-Language` and
44+
> `Content-Type`
45+
> - `Content-Type` should be:
46+
> - `application/x-www-form-urlencoded`
47+
> - `multipart/form-data`
48+
> - `text/plain`
49+
> - No event listener has been added on `XMLHttpRequestUpload`.
50+
> `XMLHttpRequestUpload.upload` is preferred.
51+
> - No `ReadableStream` is used in the request.
52+
53+
To authorize the call, the browser will issue a first request, called a
54+
"preflight" request. This request takes the form of an `OPTIONS` request, which
55+
should be answered positively by the server (meaning the response status code
56+
should be 2XX) and should contains the appropriate CORS headers
57+
(`Access-Control` headers).
58+
59+
In case the preflight request is not successful, the server will simply cancel
60+
the HTTP request. But if the preflight request is successful, then the browser
61+
will then launch the real request, and the server will be able to handle it.
62+
63+
## What are the headers?
64+
65+
We distinguish different types of headers: the headers concerning the request
66+
issuer (the caller) and the headers responded by the server.
67+
68+
### Response headers
69+
70+
Response headers are not automatically set by the server, and you should handle
71+
them according on what you want to do. This package tries to abstract it to
72+
simplify your development and let you focus on your application. We count 6 CORS
73+
response headers:
74+
75+
- `Access-Control-Allow-Origin`, indicates which origins are allowed to access
76+
the server. It can be a joker (`"*"`) or a unique domain
77+
(`https://gleam.run`). It cannot contains multiple domains, but can response
78+
to multiple different domains with the `VARY` header. You should not have to
79+
take care of this, because the library provides it for you.
80+
- `Access-Control-Expose-Headers`, provides a whitelist of allowed headers for
81+
the browsers. Only the headers in the whitelist will be able to be used in the
82+
response object in the JS code. It means if the response contains headers you
83+
want to cache to the client, you can use this header.
84+
- `Access-Control-Max-Age`, allows to put the preflight response in cache, for a
85+
specified amount of time. This avoids to rerun the `OPTIONS` request multiple
86+
times.
87+
- `Access-Control-Allow-Credentials`, allows the request to includes credentials
88+
authorizations. This can expose you to CSRF attack. Never activate this option
89+
unless you carefully know what you're doing.
90+
- `Access-Control-Allow-Methods`, provides a whitelist of subsequent authorized
91+
methods in the future requests.
92+
- `Access-Control-Allow-Headers`, indicates which headers are accepted by the
93+
server, and thus, which headers the browser will be able to send in subsequent
94+
requests.
95+
96+
### Request headers
97+
98+
Request headers are headers automatically set by the browser, when issuing a
99+
request with `XMLHttpRequest` or `fetch`. You should not bother about it, but
100+
they're still referenced it, in case you encounter them.We count 3 CORS request
101+
headers:
102+
103+
- `Origin` contains the origin of the request. The browser will _always_ fill
104+
this header automatically.
105+
- `Access-Control-Request-Method` contains the desired methods to use when
106+
talking with the server.
107+
- `Access-Control-Request-Header` contains the desired headers that the request
108+
want to have.
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: erlef/setup-beam@v1
16+
with:
17+
otp-version: "26.0.2"
18+
gleam-version: "1.1.0"
19+
rebar3-version: "3"
20+
# elixir-version: "1.15.4"
21+
- run: gleam deps download
22+
- run: gleam test
23+
- run: gleam format --check src test

e2e/mist_test/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump

e2e/mist_test/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# mist_test
2+
3+
[![Package Version](https://img.shields.io/hexpm/v/mist_test)](https://hex.pm/packages/mist_test)
4+
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/mist_test/)
5+
6+
```sh
7+
gleam add mist_test
8+
```
9+
```gleam
10+
import mist_test
11+
12+
pub fn main() {
13+
// TODO: An example of the project in use
14+
}
15+
```
16+
17+
Further documentation can be found at <https://hexdocs.pm/mist_test>.
18+
19+
## Development
20+
21+
```sh
22+
gleam run # Run the project
23+
gleam test # Run the tests
24+
gleam shell # Run an Erlang shell
25+
```

e2e/mist_test/gleam.toml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name = "mist_test"
2+
version = "1.0.0"
3+
4+
# Fill out these fields if you intend to generate HTML documentation or publish
5+
# your project to the Hex package manager.
6+
#
7+
# description = ""
8+
# licences = ["Apache-2.0"]
9+
# repository = { type = "github", user = "username", repo = "project" }
10+
# links = [{ title = "Website", href = "https://gleam.run" }]
11+
#
12+
# For a full reference of all the available options, you can have a look at
13+
# https://gleam.run/writing-gleam/gleam-toml/.
14+
15+
[dependencies]
16+
gleam_http = ">= 3.6.0 and < 4.0.0"
17+
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
18+
mist = ">= 1.0.0 and < 2.0.0"
19+
simple_cors = {path = "../.."}
20+
gleam_erlang = ">= 0.25.0 and < 1.0.0"
21+
22+
[dev-dependencies]
23+
gleeunit = ">= 1.0.0 and < 2.0.0"

e2e/mist_test/manifest.toml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
{ name = "birl", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "976CFF85D34D50F7775896615A71745FBE0C325E50399787088F941B539A0497" },
6+
{ name = "exception", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "F5580D584F16A20B7FCDCABF9E9BE9A2C1F6AC4F9176FA6DD0B63E3B20D450AA" },
7+
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
8+
{ name = "gleam_crypto", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "ADD058DEDE8F0341F1ADE3AAC492A224F15700829D9A3A3F9ADF370F875C51B7" },
9+
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
10+
{ name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" },
11+
{ name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" },
12+
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
13+
{ name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" },
14+
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
15+
{ name = "glisten", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "glisten", source = "hex", outer_checksum = "CF3A9383E9BA4A8CBAF2F7B799716290D02F2AC34E7A77556B49376B662B9314" },
16+
{ name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" },
17+
{ name = "logging", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "82C112ED9B6C30C1772A6FE2613B94B13F62EA35F5869A2630D13948D297BD39" },
18+
{ name = "marceau", version = "1.1.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "1AAD727A30BE0F95562C3403BB9B27C823797AD90037714255EEBF617B1CDA81" },
19+
{ name = "mist", version = "1.0.0", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "hpack_erl", "logging"], otp_app = "mist", source = "hex", outer_checksum = "7765E53DCC9ACCACF217B8E0CA3DE7E848C783BFAE5118B75011E81C2C80385C" },
20+
{ name = "ranger", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "1566C272B1D141B3BBA38B25CB761EF56E312E79EC0E2DFD4D3C19FB0CC1F98C" },
21+
{ name = "simple_cors", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib", "mist", "wisp"], source = "local", path = "../.." },
22+
{ name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" },
23+
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
24+
{ name = "wisp", version = "0.14.0", build_tools = ["gleam"], requirements = ["exception", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_json", "gleam_stdlib", "logging", "marceau", "mist", "simplifile"], otp_app = "wisp", source = "hex", outer_checksum = "9F5453AF1F9275E6F8707BC815D6A6A9DF41551921B16FBDBA52883773BAE684" },
25+
]
26+
27+
[requirements]
28+
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0" }
29+
gleam_http = { version = ">= 3.6.0 and < 4.0.0" }
30+
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
31+
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
32+
mist = { version = ">= 1.0.0 and < 2.0.0" }
33+
simple_cors = { path = "../.." }

e2e/mist_test/src/mist_test.gleam

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import gleam/bytes_builder
2+
import gleam/erlang/process
3+
import gleam/http
4+
import gleam/http/request.{type Request}
5+
import gleam/http/response.{type Response}
6+
import mist.{type Connection, type ResponseData}
7+
import simple_cors as cors
8+
9+
fn cors() {
10+
cors.new()
11+
|> cors.allow_origin("http://localhost:3000")
12+
|> cors.allow_method(http.Get)
13+
|> cors.allow_method(http.Post)
14+
}
15+
16+
fn main_handler(req: Request(Connection)) -> Response(ResponseData) {
17+
use _req <- cors.mist_handle(req, cors())
18+
let empty = mist.Bytes(bytes_builder.new())
19+
response.new(200)
20+
|> response.set_body(empty)
21+
}
22+
23+
pub fn main() {
24+
let assert Ok(_) =
25+
main_handler
26+
|> mist.new()
27+
|> mist.port(8080)
28+
|> mist.start_http()
29+
process.sleep(5000)
30+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import gleeunit
2+
import gleeunit/should
3+
4+
pub fn main() {
5+
gleeunit.main()
6+
}
7+
8+
// gleeunit test functions end in `_test`
9+
pub fn hello_world_test() {
10+
1
11+
|> should.equal(1)
12+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: erlef/setup-beam@v1
16+
with:
17+
otp-version: "26.0.2"
18+
gleam-version: "1.1.0"
19+
rebar3-version: "3"
20+
# elixir-version: "1.15.4"
21+
- run: gleam deps download
22+
- run: gleam test
23+
- run: gleam format --check src test

e2e/wisp_test/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump

e2e/wisp_test/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# wisp_test
2+
3+
[![Package Version](https://img.shields.io/hexpm/v/wisp_test)](https://hex.pm/packages/wisp_test)
4+
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/wisp_test/)
5+
6+
```sh
7+
gleam add wisp_test
8+
```
9+
```gleam
10+
import wisp_test
11+
12+
pub fn main() {
13+
// TODO: An example of the project in use
14+
}
15+
```
16+
17+
Further documentation can be found at <https://hexdocs.pm/wisp_test>.
18+
19+
## Development
20+
21+
```sh
22+
gleam run # Run the project
23+
gleam test # Run the tests
24+
gleam shell # Run an Erlang shell
25+
```

e2e/wisp_test/gleam.toml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name = "wisp_test"
2+
version = "1.0.0"
3+
4+
# Fill out these fields if you intend to generate HTML documentation or publish
5+
# your project to the Hex package manager.
6+
#
7+
# description = ""
8+
# licences = ["Apache-2.0"]
9+
# repository = { type = "github", user = "username", repo = "project" }
10+
# links = [{ title = "Website", href = "https://gleam.run" }]
11+
#
12+
# For a full reference of all the available options, you can have a look at
13+
# https://gleam.run/writing-gleam/gleam-toml/.
14+
15+
[dependencies]
16+
gleam_http = ">= 3.6.0 and < 4.0.0"
17+
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
18+
mist = ">= 1.0.0 and < 2.0.0"
19+
simple_cors = {path = "../.."}
20+
wisp = ">= 0.14.0 and < 1.0.0"
21+
gleam_erlang = ">= 0.25.0 and < 1.0.0"
22+
23+
[dev-dependencies]
24+
gleeunit = ">= 1.0.0 and < 2.0.0"

0 commit comments

Comments
 (0)