Skip to content

Commit ac7bd4d

Browse files
authored
Merge pull request #43 from saviorand/feature/static-files-basic
Enable serving static files
2 parents bc99c93 + ec01303 commit ac7bd4d

File tree

16 files changed

+271
-165
lines changed

16 files changed

+271
-165
lines changed

β€ŽREADME.mdβ€Ž

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,33 +127,55 @@ Once you have Mojo set up locally,
127127

128128
<p align="right">(<a href="#readme-top">back to top</a>)</p>
129129

130-
### Using the client
130+
### Serving static files
131131

132-
Create a file, e.g `client.mojo` with the following code:
132+
The default welcome screen shows an example of how to serve files like images or HTML using Lightbug. Mojo has built-in `open`, `read` and `read_bytes` methods that you can use to read files from e.g. a `static` directory and serve them on a route:
133133

134134
```mojo
135-
from lightbug_http.http import HTTPRequest
136-
from lightbug_http.uri import URI
137-
from lightbug_http.sys.client import MojoClient
135+
@value
136+
struct Welcome(HTTPService):
137+
fn func(self, req: HTTPRequest) raises -> HTTPResponse:
138+
var uri = req.uri()
139+
140+
if uri.path() == "/":
141+
var html: Bytes
142+
with open("static/lightbug_welcome.html", "r") as f:
143+
html = f.read_bytes()
144+
return OK(html, "text/html; charset=utf-8")
145+
146+
if uri.path() == "/logo.png":
147+
var image: Bytes
148+
with open("static/logo.png", "r") as f:
149+
image = f.read_bytes()
150+
return OK(image, "image/png")
151+
152+
return NotFound(uri.path())
153+
```
154+
155+
### Using the client
138156

157+
Create a file, e.g `client.mojo` with the following code. Run `mojo client.mojo` to execute the request to a given URL.
158+
159+
```mojo
139160
fn test_request(inout client: MojoClient) raises -> None:
140-
var uri = URI("http://httpbin.org/")
161+
var uri = URI("http://httpbin.org/status/404")
141162
var request = HTTPRequest(uri)
142163
var response = client.do(request)
143164
144165
# print status code
145166
print("Response:", response.header.status_code())
146167
147-
# print various parsed headers
148-
print("Header", response.header.content_length())
168+
# print raw headers
169+
# print("Headers:", response.header.headers())
170+
171+
# print parsed headers (only some are parsed for now)
172+
print("Content-Type:", String(response.header.content_type()))
173+
print("Content-Length", response.header.content_length())
174+
print("Connection:", response.header.connection_close())
175+
print("Server:", String(response.header.server()))
149176
150177
# print body
151178
print(String(response.get_body()))
152-
153-
154-
fn main() raises -> None:
155-
var client = MojoClient()
156-
test_request(client)
157179
```
158180

159181
Pure Mojo-based client is available by default. This client is also used internally for testing the server.

β€Žclient.mojoβ€Ž

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from lightbug_http.http import HTTPRequest, encode
2+
from lightbug_http.header import RequestHeader
3+
from lightbug_http.uri import URI
4+
from lightbug_http.sys.client import MojoClient
5+
6+
fn test_request(inout client: MojoClient) raises -> None:
7+
var uri = URI("http://httpbin.org/status/404")
8+
var request = HTTPRequest(uri)
9+
var response = client.do(request)
10+
11+
# print status code
12+
print("Response:", response.header.status_code())
13+
14+
# print raw headers
15+
# print("Headers:", response.header.headers())
16+
17+
# print parsed headers (only some are parsed for now)
18+
print("Content-Type:", String(response.header.content_type()))
19+
print("Content-Length", response.header.content_length())
20+
print("Connection:", response.header.connection_close())
21+
print("Server:", String(response.header.server()))
22+
23+
# print body
24+
print(String(response.get_body()))
25+
26+
27+
fn main() raises -> None:
28+
var client = MojoClient()
29+
test_request(client)

β€Žexternal/libc.mojoβ€Ž

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from lightbug_http.io.bytes import Bytes
2+
13
alias IPPROTO_IPV6 = 41
24
alias IPV6_V6ONLY = 26
35
alias EPROTONOSUPPORT = 93
@@ -83,6 +85,12 @@ fn to_char_ptr(s: String) -> Pointer[c_char]:
8385
return ptr
8486

8587

88+
fn to_char_ptr(s: Bytes) -> Pointer[c_char]:
89+
var ptr = Pointer[c_char]().alloc(len(s))
90+
for i in range(len(s)):
91+
ptr.store(i, int(s[i]))
92+
return ptr
93+
8694
fn c_charptr_to_string(s: Pointer[c_char]) -> String:
8795
return String(s.bitcast[Int8](), strlen(s))
8896

β€Žlightbug.πŸ”₯β€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from lightbug_http import *
2-
from sys import is_defined
32

43
fn main() raises:
54
var server = SysServer()

β€Žlightbug_http/error.mojoβ€Ž

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,4 @@ from lightbug_http.header import ResponseHeader
66
@value
77
struct ErrorHandler:
88
fn Error(self) -> HTTPResponse:
9-
return HTTPResponse(ResponseHeader(), String("TODO").as_bytes())
10-
11-
12-
alias errNeedMore = Error("need more data: cannot find trailing lf")
13-
alias errInvalidName = Error("invalid header name")
14-
alias errSmallBuffer = Error("small read buffer. Increase ReadBufferSize")
9+
return HTTPResponse(ResponseHeader(), String("TODO")._buffer)

0 commit comments

Comments
Β (0)