Skip to content

Commit fd3ed82

Browse files
committed
refactor: enhance header collection and parsing with increased C buffer and StringView adoption.
1 parent 3b80270 commit fd3ed82

6 files changed

Lines changed: 45 additions & 32 deletions

File tree

moon.mod.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oboard/mocket",
3-
"version": "0.5.7",
3+
"version": "0.5.8",
44
"deps": {
55
"illusory0x0/native": "0.2.1",
66
"moonbitlang/x": "0.4.34",
@@ -9,11 +9,8 @@
99
"readme": "README.md",
1010
"repository": "https://github.com/oboard/mocket",
1111
"license": "Apache-2.0",
12-
"keywords": [
13-
"http",
14-
"server"
15-
],
12+
"keywords": ["http", "server"],
1613
"description": "A web framework for MoonBit.",
1714
"source": "src",
1815
"preferred-target": "native"
19-
}
16+
}

src/body_reader.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub suberror BodyError {
77

88
///|
99
fn read_body(
10-
req_headers : Map[String, String],
10+
req_headers : Map[StringView, StringView],
1111
body_bytes : BytesView,
1212
) -> HttpBody raise BodyError {
1313
let content_type = req_headers.get("Content-Type")
@@ -54,7 +54,7 @@ priv struct ContentType {
5454
} derive(Show)
5555

5656
///|
57-
fn parse_content_type(s : String) -> ContentType? {
57+
fn parse_content_type(s : StringView) -> ContentType? {
5858
let parts = s.split(";").to_array()
5959
if parts.is_empty() {
6060
None

src/cookie.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ pub fn cookie_to_string(cookie : Array[CookieItem]) -> String {
5252
///|
5353

5454
///|
55-
pub fn parse_cookie(cookie : String) -> Map[String, CookieItem] {
55+
pub fn parse_cookie(cookie : StringView) -> Map[String, CookieItem] {
5656
let res = Map::new()
57-
let mut view = cookie[:]
57+
let mut view = cookie
5858
let mut last_cookie_name = ""
5959
while view.length() > 0 {
6060
// Skip whitespace using lexmatch

src/index.mbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn new(
8181
pub(all) struct HttpRequest {
8282
http_method : String
8383
url : String
84-
headers : Map[String, String]
84+
headers : Map[StringView, StringView]
8585
mut body : HttpBody
8686
}
8787

src/mocket.native.mbt

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,26 @@ fn handle_request_native(
162162
// res.end(to_cstr("{\"status\":\"ok\"}"))
163163

164164
let headers_str = from_cstr(req.headers())
165-
let req_headers = headers_str
166-
.split("\n")
167-
.map(fn(pair) {
168-
if pair.length() > 0 && pair.split(": ").to_array() is [key, value] {
169-
(key.to_string(), value.to_string())
170-
} else {
171-
("", "")
165+
let req_headers = Map::new()
166+
headers_str
167+
.split("\n")
168+
.each(fn(line) {
169+
let line = line.trim_space()
170+
if line == "" {
171+
return
172+
}
173+
try {
174+
if line.find(":") is Some(idx) {
175+
let key = line[0:idx].trim_space()
176+
let value = line[idx + 1:].trim_space()
177+
if key != "" {
178+
req_headers.set(key, value)
179+
}
172180
}
173-
})
174-
.filter(fn(pair) { pair.0.length() > 0 })
175-
.to_array()
176-
|> Map::from_array
181+
} catch {
182+
_ => ()
183+
}
184+
})
177185
let (params, handler) = match mocket.find_route(http_method, path) {
178186
Some((h, p)) => (p, h)
179187
_ => {

src/mocket.stub.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,25 @@ const char *req_headers(request_t *req)
258258
{
259259
if (req && req->hm)
260260
{
261-
static char headers_buf[1024];
261+
static char headers_buf[4096];
262262
headers_buf[0] = '\0';
263-
264-
// Extract some common headers
265-
struct mg_str *content_type = mg_http_get_header(req->hm, "Content-Type");
266-
if (content_type)
267-
{
268-
strncat(headers_buf, "Content-Type: ", sizeof(headers_buf) - strlen(headers_buf) - 1);
269-
strncat(headers_buf, content_type->buf,
270-
content_type->len < (sizeof(headers_buf) - strlen(headers_buf) - 1) ? content_type->len : (sizeof(headers_buf) - strlen(headers_buf) - 1));
271-
strncat(headers_buf, "\r\n", sizeof(headers_buf) - strlen(headers_buf) - 1);
263+
size_t buf_len = 0;
264+
size_t buf_cap = sizeof(headers_buf);
265+
266+
for (int i = 0; i < MG_MAX_HTTP_HEADERS; i++) {
267+
struct mg_http_header *h = &req->hm->headers[i];
268+
if (h->name.len == 0) break;
269+
270+
// Check if we have enough space: name.len + 2 (": ") + value.len + 2 ("\r\n") + 1 (null terminator)
271+
size_t needed = h->name.len + 2 + h->value.len + 2 + 1;
272+
if (buf_len + needed > buf_cap) break;
273+
274+
strncat(headers_buf, h->name.buf, h->name.len);
275+
strcat(headers_buf, ": ");
276+
strncat(headers_buf, h->value.buf, h->value.len);
277+
strcat(headers_buf, "\r\n");
278+
279+
buf_len += needed - 1; // -1 because null terminator is overwritten/handled by strcat
272280
}
273281

274282
return headers_buf;

0 commit comments

Comments
 (0)