Skip to content

Commit 9f0fee0

Browse files
committed
Merge pull request #5 from oboard:reflactor/http-body
Reflactor/http-body
2 parents 2fdc3f6 + cf89a88 commit 9f0fee0

36 files changed

Lines changed: 1520 additions & 537 deletions

moon.mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oboard/mocket",
3-
"version": "0.5.8",
3+
"version": "0.6.0",
44
"deps": {
55
"illusory0x0/native": "0.2.1",
66
"moonbitlang/x": "0.4.34",
Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,3 @@
1-
///|
2-
pub suberror BodyError {
3-
InvalidJsonCharset
4-
InvalidJson
5-
InvalidText
6-
}
7-
8-
///|
9-
fn read_body(
10-
req_headers : Map[StringView, StringView],
11-
body_bytes : BytesView,
12-
) -> HttpBody raise BodyError {
13-
let content_type = req_headers.get("Content-Type")
14-
if content_type is Some(content_type) {
15-
let content_type = parse_content_type(content_type)
16-
if content_type is Some(content_type) {
17-
return match content_type {
18-
{ subtype: "json", .. } => {
19-
let json = @encoding/utf8.decode(body_bytes) catch {
20-
_ => raise BodyError::InvalidJsonCharset
21-
}
22-
Json(@json.parse(json) catch { _ => raise BodyError::InvalidJson })
23-
}
24-
{ media_type: "text", .. } =>
25-
Text(
26-
@encoding/utf8.decode(body_bytes) catch {
27-
_ => raise BodyError::InvalidText
28-
},
29-
)
30-
{ subtype: "x-www-form-urlencoded", .. } =>
31-
Form(parse_form_data(body_bytes))
32-
{ subtype: "form-data" | "multipart", params, .. } => {
33-
let boundary = match params.get("boundary") {
34-
Some(b) => Some(b)
35-
None => params.get("BOUNDARY")
36-
}
37-
match boundary {
38-
Some(b) => Multipart(parse_multipart(body_bytes, b.to_string()))
39-
None => Bytes(body_bytes)
40-
}
41-
}
42-
_ => Bytes(body_bytes)
43-
}
44-
}
45-
}
46-
Bytes(body_bytes)
47-
}
48-
491
///|
502
priv struct ContentType {
513
media_type : StringView

src/cors/cors.mbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn handle_cors(
6666
max_age~,
6767
)
6868
// 对于预检请求,直接返回空响应,不调用next()
69-
@mocket.Empty
69+
@mocket.HttpResponse::new(OK).to_responder()
7070
} else {
7171
append_cors_headers(
7272
event,

src/cors/pkg.generated.mbti

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn append_cors_headers(@mocket.MocketEvent, origin? : String, methods? : String,
1010

1111
fn append_cors_preflight_headers(@mocket.MocketEvent, origin? : String, methods? : String, allow_headers? : String, credentials? : Bool, max_age? : Int) -> Unit
1212

13-
fn handle_cors(origin? : String, methods? : String, allow_headers? : String, expose_headers? : String, credentials? : Bool, max_age? : Int) -> async (@mocket.MocketEvent, async () -> @mocket.HttpBody noraise) -> @mocket.HttpBody noraise
13+
fn handle_cors(origin? : String, methods? : String, allow_headers? : String, expose_headers? : String, credentials? : Bool, max_age? : Int) -> async (@mocket.MocketEvent, async () -> &@mocket.Responder noraise) -> &@mocket.Responder noraise
1414

1515
fn is_preflight_request(@mocket.MocketEvent) -> Bool
1616

src/examples/cookie/main.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ fn main {
44
app.get("/", e => {
55
e.res.set_cookie("session_id", "12345", max_age=3600)
66
if e.req.get_cookie("session_id") is Some(session_id) {
7-
Text(session_id.value)
7+
session_id.value
88
} else {
9-
Text("No session_id")
9+
"No session_id"
1010
}
1111
})
1212

src/examples/responder/main.mbt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
///|
2+
using @mocket {type HttpResponse}
3+
4+
///|
5+
struct Person {
6+
name : String
7+
age : Int
8+
} derive(ToJson, FromJson)
9+
10+
///|
11+
impl @mocket.BodyReader for Person with from_request(req) -> Person raise {
12+
@json.from_json(req.body())
13+
}
14+
15+
///|
16+
fn main {
17+
let app = @mocket.new()
18+
19+
// Text Response
20+
app
21+
..get("/", _event => "⚡️ Tadaa!")
22+
23+
// Object Response
24+
..get("/json", _event => { name: "oboard", age: 21 }.to_json())
25+
26+
// JSON Request
27+
// curl --location 'localhost:4000/json' \
28+
// --header 'Content-Type: application/json' \
29+
// --data '{
30+
// "name": "oboard",
31+
// "age": 21
32+
// }'
33+
..post("/json", event => try {
34+
let person : Person = event.req.body()
35+
HttpResponse::new(OK).body(
36+
"Hello, \{person.name}. You are \{person.age} years old.",
37+
)
38+
} catch {
39+
_ => HttpResponse::new(BadRequest).body("Invalid JSON")
40+
})
41+
42+
// Echo Server
43+
..post("/echo", e => e.req)
44+
45+
// 404 Page
46+
..get("/404", _ => HttpResponse::new(NotFound).body(
47+
@mocket.html(
48+
(
49+
#|<html>
50+
#|<body>
51+
#| <h1>404</h1>
52+
#|</body>
53+
#|</html>
54+
),
55+
),
56+
))
57+
58+
// Print Server URL
59+
for path in app.mappings.keys() {
60+
println("\{path.0} http://localhost:4000\{path.1}")
61+
}
62+
63+
// Serve
64+
app.serve(port=4000)
65+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"is-main": true,
3+
"import": ["oboard/mocket"]
4+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Generated using `moon info`, DON'T EDIT IT
2+
package "oboard/mocket/examples/responder"
3+
4+
import(
5+
"moonbitlang/core/json"
6+
)
7+
8+
// Values
9+
10+
// Errors
11+
12+
// Types and methods
13+
type Person
14+
impl ToJson for Person
15+
impl @json.FromJson for Person
16+
17+
// Type aliases
18+
19+
// Traits
20+

src/examples/route/main.mbt

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
///|
22
fn main {
3-
let app = @mocket.new(logger=@mocket.new_production_logger())
3+
let app = @mocket.new()
44

55
// Register global middleware
66
app
7-
..use_middleware((event, next) => {
8-
println("📝 Request: \{event.req.http_method} \{event.req.url}")
9-
next()
10-
})
7+
..use_middleware(logger_middleware)
118
..use_middleware(@cors.handle_cors())
129

1310
// Text Response
14-
..get("/", _event => Text("⚡️ Tadaa!"))
11+
..get("/", _event => "⚡️ Tadaa!")
1512

1613
// Hello World
17-
..on("GET", "/hello", _ => Text("Hello world!"))
14+
..on("GET", "/hello", _ => "Hello world!")
1815
..group("/api", group => {
1916
// 添加组级中间件
2017
group.use_middleware((event, next) => {
@@ -23,61 +20,54 @@ fn main {
2320
)
2421
next()
2522
})
26-
group.get("/hello", _ => Text("Hello world!"))
27-
group.get("/json", _ => Json({
28-
"name": "John Doe",
29-
"age": 30,
30-
"city": "New York",
31-
}))
23+
group.get("/hello", _ => "Hello world!")
24+
group.get("/json", _ => (
25+
{ "name": "John Doe", "age": 30, "city": "New York" } : Json))
3226
})
3327

3428
// JSON Response
35-
..get("/json", _event => Json({
36-
"name": "John Doe",
37-
"age": 30,
38-
"city": "New York",
39-
}))
29+
..get("/json", _event => (
30+
{ "name": "John Doe", "age": 30, "city": "New York" } : Json))
4031

4132
// Async Response
4233
..get("/async_data", async fn(_event) noraise {
43-
Json({ "name": "John Doe", "age": 30, "city": "New York" })
34+
({ "name": "John Doe", "age": 30, "city": "New York" } : Json)
4435
})
4536

4637
// Dynamic Routes
4738
// /hello2/World = Hello, World!
4839
..get("/hello/:name", event => {
4940
let name = event.params.get("name").unwrap_or("World")
50-
Text("Hello, \{name}!")
41+
"Hello, \{name}!"
5142
})
5243
// /hello2/World = Hello, World!
5344
..get("/hello2/*", event => {
5445
let name = event.params.get("_").unwrap_or("World")
55-
Text("Hello, \{name}!")
46+
"Hello, \{name}!"
5647
})
5748

5849
// Wildcard Routes
5950
// /hello3/World/World = Hello, World/World!
6051
..get("/hello3/**", event => {
6152
let name = event.params.get("_").unwrap_or("World")
62-
Text("Hello, \{name}!")
53+
"Hello, \{name}!"
6354
})
6455

6556
// Echo Server
66-
..post("/echo", e => e.req.body)
57+
..post("/echo", e => e.req)
6758

6859
// 404 Page
69-
..get("/404", e => {
70-
e.res.status_code = 404
71-
HTML(
60+
..get("/404", _ => @mocket.HttpResponse::new(NotFound).body(
61+
@mocket.html(
7262
(
7363
#|<html>
7464
#|<body>
7565
#| <h1>404</h1>
7666
#|</body>
7767
#|</html>
7868
),
79-
)
80-
})
69+
),
70+
))
8171

8272
// Print Server URL
8373
for path in app.mappings.keys() {
@@ -87,3 +77,15 @@ fn main {
8777
// Serve
8878
app.serve(port=4000)
8979
}
80+
81+
///|
82+
pub async fn logger_middleware(
83+
event : @mocket.MocketEvent,
84+
next : async () -> &@mocket.Responder noraise,
85+
) -> &@mocket.Responder noraise {
86+
let start_time = @env.now()
87+
let res = next()
88+
let duration = @env.now() - start_time
89+
println("\{event.req.http_method} \{event.req.url} - \{duration}ms")
90+
res
91+
}

src/examples/route/pkg.generated.mbti

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
// Generated using `moon info`, DON'T EDIT IT
22
package "oboard/mocket/examples/route"
33

4+
import(
5+
"oboard/mocket"
6+
)
7+
48
// Values
9+
async fn logger_middleware(@mocket.MocketEvent, async () -> &@mocket.Responder noraise) -> &@mocket.Responder noraise
510

611
// Errors
712

0 commit comments

Comments
 (0)