Skip to content

Commit

Permalink
Merge pull request #241 from thatstoasty/fix-body-reader
Browse files Browse the repository at this point in the history
Fix reader not skipping over all CRLF
  • Loading branch information
saviorand authored Feb 2, 2025
2 parents 0d320e7 + dfcf13d commit 0cbb77b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 24 deletions.
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,25 +97,22 @@ Once you have a Mojo project set up locally,
For example, to make a `Printer` service that prints some details about the request to console:

```mojo
from lightbug_http import *
from lightbug_http.http import HTTPRequest, HTTPResponse, OK
from lightbug_http.strings import to_string
from lightbug_http.header import HeaderKey
@value
struct Printer(HTTPService):
fn func(mut self, req: HTTPRequest) raises -> HTTPResponse:
var uri = req.uri
print("Request URI: ", to_string(uri.request_uri))
var header = req.headers
print("Request protocol: ", req.protocol)
print("Request method: ", req.method)
print(
"Request Content-Type: ", to_string(header[HeaderKey.CONTENT_TYPE])
)
var body = req.body_raw
print("Request Body: ", to_string(body))
return OK(body)
print("Request URI:", req.uri.request_uri)
print("Request protocol:", req.protocol)
print("Request method:", req.method)
if HeaderKey.CONTENT_TYPE in req.headers:
print("Request Content-Type:", req.headers[HeaderKey.CONTENT_TYPE])
if req.body_raw:
print("Request Body:", to_string(req.body_raw))
return OK(req.body_raw)
```

6. Start a server listening on a port with your service like so.
Expand Down
11 changes: 7 additions & 4 deletions lightbug_http/http/request.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ struct HTTPRequest(Writable, Stringable):
var request = HTTPRequest(
URI.parse(addr + uri), headers=headers, method=method, protocol=protocol, cookies=cookies
)
try:
request.read_body(reader, content_length, max_body_size)
except e:
raise Error("HTTPRequest.from_bytes: Failed to read request body: " + str(e))

if content_length > 0:
try:
reader.skip_carriage_return()
request.read_body(reader, content_length, max_body_size)
except e:
raise Error("HTTPRequest.from_bytes: Failed to read request body: " + str(e))

return request

Expand Down
5 changes: 3 additions & 2 deletions lightbug_http/server.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,15 @@ struct Server(Movable):
var response: HTTPResponse
try:
response = handler.func(request)
except:
except e:
logger.error("Unexpected error in the handler:", e)

if not conn.is_closed():
# Try to send back an internal server error, but always attempt to teardown the connection.
try:
# TODO: Move InternalError response to an alias when Mojo can support Dict operations at compile time. (@thatstoasty)
_ = conn.write(encode(InternalError()))
except e:
logger.error(e)
raise Error("Failed to send InternalError response")
finally:
conn.teardown()
Expand Down
6 changes: 4 additions & 2 deletions lightbug_http/service.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ struct Printer(HTTPService):
print("Request URI:", req.uri.request_uri)
print("Request protocol:", req.protocol)
print("Request method:", req.method)
print("Request Content-Type:", req.headers[HeaderKey.CONTENT_TYPE])
print("Request Body:", to_string(req.body_raw))
if HeaderKey.CONTENT_TYPE in req.headers:
print("Request Content-Type:", req.headers[HeaderKey.CONTENT_TYPE])
if req.body_raw:
print("Request Body:", to_string(req.body_raw))

return OK(req.body_raw)

Expand Down
10 changes: 9 additions & 1 deletion tests/lightbug_http/http/test_request.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ def test_request_from_bytes():


def test_read_body():
...
alias data = "GET /redirect HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nUser-Agent: python-requests/2.32.3\r\nAccept-Encoding: gzip, deflate, br, zstd\r\nAccept: */\r\nContent-Length: 17\r\nconnection: keep-alive\r\n\r\nThis is the body!"
var request = HTTPRequest.from_bytes("127.0.0.1", 4096, data.as_bytes())
testing.assert_equal(request.protocol, "HTTP/1.1")
testing.assert_equal(request.method, "GET")
testing.assert_equal(request.uri.request_uri, "/redirect")
testing.assert_equal(request.headers["Host"], "127.0.0.1:8080")
testing.assert_equal(request.headers["User-Agent"], "python-requests/2.32.3")

testing.assert_equal(request.get_body(), "This is the body!")


def test_encode():
Expand Down

0 comments on commit 0cbb77b

Please sign in to comment.