Skip to content

Commit

Permalink
Merge pull request #43 from saviorand/feature/static-files-basic
Browse files Browse the repository at this point in the history
Enable serving static files
  • Loading branch information
saviorand authored May 28, 2024
2 parents bc99c93 + ec01303 commit ac7bd4d
Show file tree
Hide file tree
Showing 16 changed files with 271 additions and 165 deletions.
48 changes: 35 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,33 +127,55 @@ Once you have Mojo set up locally,

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

### Using the client
### Serving static files

Create a file, e.g `client.mojo` with the following code:
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:

```mojo
from lightbug_http.http import HTTPRequest
from lightbug_http.uri import URI
from lightbug_http.sys.client import MojoClient
@value
struct Welcome(HTTPService):
fn func(self, req: HTTPRequest) raises -> HTTPResponse:
var uri = req.uri()
if uri.path() == "/":
var html: Bytes
with open("static/lightbug_welcome.html", "r") as f:
html = f.read_bytes()
return OK(html, "text/html; charset=utf-8")
if uri.path() == "/logo.png":
var image: Bytes
with open("static/logo.png", "r") as f:
image = f.read_bytes()
return OK(image, "image/png")
return NotFound(uri.path())
```

### Using the client

Create a file, e.g `client.mojo` with the following code. Run `mojo client.mojo` to execute the request to a given URL.

```mojo
fn test_request(inout client: MojoClient) raises -> None:
var uri = URI("http://httpbin.org/")
var uri = URI("http://httpbin.org/status/404")
var request = HTTPRequest(uri)
var response = client.do(request)
# print status code
print("Response:", response.header.status_code())
# print various parsed headers
print("Header", response.header.content_length())
# print raw headers
# print("Headers:", response.header.headers())
# print parsed headers (only some are parsed for now)
print("Content-Type:", String(response.header.content_type()))
print("Content-Length", response.header.content_length())
print("Connection:", response.header.connection_close())
print("Server:", String(response.header.server()))
# print body
print(String(response.get_body()))
fn main() raises -> None:
var client = MojoClient()
test_request(client)
```

Pure Mojo-based client is available by default. This client is also used internally for testing the server.
Expand Down
29 changes: 29 additions & 0 deletions client.mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from lightbug_http.http import HTTPRequest, encode
from lightbug_http.header import RequestHeader
from lightbug_http.uri import URI
from lightbug_http.sys.client import MojoClient

fn test_request(inout client: MojoClient) raises -> None:
var uri = URI("http://httpbin.org/status/404")
var request = HTTPRequest(uri)
var response = client.do(request)

# print status code
print("Response:", response.header.status_code())

# print raw headers
# print("Headers:", response.header.headers())

# print parsed headers (only some are parsed for now)
print("Content-Type:", String(response.header.content_type()))
print("Content-Length", response.header.content_length())
print("Connection:", response.header.connection_close())
print("Server:", String(response.header.server()))

# print body
print(String(response.get_body()))


fn main() raises -> None:
var client = MojoClient()
test_request(client)
8 changes: 8 additions & 0 deletions external/libc.mojo
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from lightbug_http.io.bytes import Bytes

alias IPPROTO_IPV6 = 41
alias IPV6_V6ONLY = 26
alias EPROTONOSUPPORT = 93
Expand Down Expand Up @@ -83,6 +85,12 @@ fn to_char_ptr(s: String) -> Pointer[c_char]:
return ptr


fn to_char_ptr(s: Bytes) -> Pointer[c_char]:
var ptr = Pointer[c_char]().alloc(len(s))
for i in range(len(s)):
ptr.store(i, int(s[i]))
return ptr

fn c_charptr_to_string(s: Pointer[c_char]) -> String:
return String(s.bitcast[Int8](), strlen(s))

Expand Down
1 change: 0 additions & 1 deletion lightbug.πŸ”₯
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from lightbug_http import *
from sys import is_defined

fn main() raises:
var server = SysServer()
Expand Down
7 changes: 1 addition & 6 deletions lightbug_http/error.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,4 @@ from lightbug_http.header import ResponseHeader
@value
struct ErrorHandler:
fn Error(self) -> HTTPResponse:
return HTTPResponse(ResponseHeader(), String("TODO").as_bytes())


alias errNeedMore = Error("need more data: cannot find trailing lf")
alias errInvalidName = Error("invalid header name")
alias errSmallBuffer = Error("small read buffer. Increase ReadBufferSize")
return HTTPResponse(ResponseHeader(), String("TODO")._buffer)
Loading

0 comments on commit ac7bd4d

Please sign in to comment.