Skip to content

Commit 790ae03

Browse files
committed
wip switching to byteview
1 parent 6639e29 commit 790ae03

File tree

3 files changed

+57
-48
lines changed

3 files changed

+57
-48
lines changed

lightbug_http/header.mojo

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from collections import Dict, Optional
2-
from lightbug_http.io.bytes import Bytes, ByteReader, ByteWriter, is_newline, is_space, ByteView
2+
from lightbug_http.io.bytes import Bytes, ByteReader, ByteWriter, is_newline, is_space, ByteView, bytes_equal_ignore_case, bytes_to_lower_string
33
from lightbug_http.strings import BytesConstant
44
from lightbug_http._logger import logger
55
from lightbug_http.strings import rChar, nChar, lineBreak, to_string
@@ -37,42 +37,11 @@ fn write_header[T: Writer](mut writer: T, key: String, value: String):
3737
writer.write(key + ": ", value, lineBreak)
3838

3939

40-
fn bytes_equal_ignore_case(a: ByteView, b: String) -> Bool:
41-
"""Compare ByteView with String case-insensitively without creating intermediate strings."""
42-
if len(a) != len(b):
43-
return False
44-
45-
for i in range(len(a)):
46-
var byte_a = a[i]
47-
var byte_b = ord(b[i])
48-
49-
# Convert to lowercase for comparison
50-
if byte_a >= ord('A') and byte_a <= ord('Z'):
51-
byte_a = byte_a + 32 # Convert to lowercase
52-
if byte_b >= ord('A') and byte_b <= ord('Z'):
53-
byte_b = byte_b + 32 # Convert to lowercase
54-
55-
if byte_a != byte_b:
56-
return False
57-
return True
58-
59-
60-
fn bytes_to_lower_string(b: ByteView) -> String:
61-
"""Convert ByteView to lowercase String."""
62-
var result = Bytes()
63-
for i in range(len(b)):
64-
var byte_val = b[i]
65-
if byte_val >= ord('A') and byte_val <= ord('Z'):
66-
byte_val = byte_val + 32 # Convert to lowercase
67-
result.append(byte_val)
68-
return to_string(result^)
69-
70-
7140
@value
7241
struct Headers[origin: Origin](Writable, Stringable):
7342
"""Represents the header key/values in an http request/response.
7443
75-
Header keys are normalized to lowercase and stored as strings for efficient lookup,
44+
Header keys are normalized to lowercase and stored as strings,
7645
while values are stored as bytes to comply with RFC requirements.
7746
"""
7847

lightbug_http/http/request.mojo

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from memory import Span
2-
from lightbug_http.io.bytes import Bytes, bytes, ByteReader, ByteWriter
2+
from lightbug_http.io.bytes import Bytes, bytes, ByteReader, ByteWriter, ByteView
33
from lightbug_http.header import Headers, HeaderKey, Header, write_header
44
from lightbug_http.cookie import RequestCookieJar
55
from lightbug_http.uri import URI
@@ -30,29 +30,30 @@ struct RequestMethod:
3030
alias options = RequestMethod("OPTIONS")
3131

3232

33-
@value
34-
struct HTTPRequest(Writable, Stringable):
35-
var headers: Headers
33+
struct HTTPRequest[origin: Origin](Writable, Stringable):
34+
var headers: Headers[origin]
3635
var cookies: RequestCookieJar
3736
var uri: URI
3837
var body_raw: Bytes
3938

40-
var method: String
41-
var protocol: String
39+
var method: ByteView[origin]
40+
var protocol: ByteView[origin]
4241

4342
var server_is_tls: Bool
4443
var timeout: Duration
4544

4645
@staticmethod
47-
fn from_bytes(addr: String, max_body_size: Int, b: Span[Byte]) raises -> HTTPRequest:
46+
fn from_bytes(addr: String, max_body_size: Int, b: Span[Byte]) raises -> HTTPRequest[origin]:
4847
var reader = ByteReader(b)
49-
var headers = Headers()
50-
var method: String
51-
var protocol: String
52-
var uri: String
48+
var headers = Headers[origin]()
49+
var method: ByteView[origin]
50+
var protocol: ByteView[origin]
51+
var uri: ByteView[origin]
5352
try:
5453
var rest = headers.parse_raw(reader)
55-
method, uri, protocol = rest[0], rest[1], rest[2]
54+
var method = rest[0]
55+
var uri = rest[1]
56+
var protocol = rest[2]
5657
except e:
5758
raise Error("HTTPRequest.from_bytes: Failed to parse request headers: " + String(e))
5859

@@ -67,7 +68,7 @@ struct HTTPRequest(Writable, Stringable):
6768
raise Error("HTTPRequest.from_bytes: Request body too large.")
6869

6970
var request = HTTPRequest(
70-
URI.parse(addr + uri), headers=headers, method=method, protocol=protocol, cookies=cookies
71+
URI.parse(addr + String(uri)), headers=headers, method=String(method), protocol=String(protocol), cookies=cookies
7172
)
7273

7374
if content_length > 0:
@@ -82,7 +83,7 @@ struct HTTPRequest(Writable, Stringable):
8283
fn __init__(
8384
out self,
8485
uri: URI,
85-
headers: Headers = Headers(),
86+
headers: Headers[origin] = Headers[origin](),
8687
cookies: RequestCookieJar = RequestCookieJar(),
8788
method: String = "GET",
8889
protocol: String = strHttp11,
@@ -92,7 +93,7 @@ struct HTTPRequest(Writable, Stringable):
9293
):
9394
self.headers = headers
9495
self.cookies = cookies
95-
self.method = method
96+
self.method = ByteView(method.as_bytes())
9697
self.protocol = protocol
9798
self.uri = uri
9899
self.body_raw = body
@@ -108,6 +109,14 @@ struct HTTPRequest(Writable, Stringable):
108109
else:
109110
self.headers[HeaderKey.HOST] = uri.host
110111

112+
fn __copyinit__(out self, existing: HTTPRequest[origin]):
113+
self.headers = existing.headers
114+
self.cookies = existing.cookies
115+
self.uri = existing.uri
116+
self.body_raw = existing.body_raw
117+
self.method = existing.method
118+
self.protocol = existing.protocol
119+
111120
fn get_body(self) -> StringSlice[__origin_of(self.body_raw)]:
112121
return StringSlice(unsafe_from_utf8=Span(self.body_raw))
113122

lightbug_http/io/bytes.mojo

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,37 @@ fn is_space(b: Byte) -> Bool:
2626
return b == BytesConstant.whitespace
2727

2828

29+
fn bytes_equal_ignore_case(a: ByteView, b: String) -> Bool:
30+
"""Compare ByteView with String case-insensitively without creating intermediate strings."""
31+
if len(a) != len(b):
32+
return False
33+
34+
for i in range(len(a)):
35+
var byte_a = a[i]
36+
var byte_b = ord(b[i])
37+
38+
# Convert to lowercase for comparison
39+
if byte_a >= ord('A') and byte_a <= ord('Z'):
40+
byte_a = byte_a + 32 # Convert to lowercase
41+
if byte_b >= ord('A') and byte_b <= ord('Z'):
42+
byte_b = byte_b + 32 # Convert to lowercase
43+
44+
if byte_a != byte_b:
45+
return False
46+
return True
47+
48+
49+
fn bytes_to_lower_string(b: ByteView) -> String:
50+
"""Convert ByteView to lowercase String."""
51+
var result = Bytes()
52+
for i in range(len(b)):
53+
var byte_val = b[i]
54+
if byte_val >= ord('A') and byte_val <= ord('Z'):
55+
byte_val = byte_val + 32 # Convert to lowercase
56+
result.append(byte_val)
57+
return to_string(result^)
58+
59+
2960
struct ByteWriter(Writer):
3061
var _inner: Bytes
3162

0 commit comments

Comments
 (0)