Files

104 lines
2.4 KiB
Plaintext

parseHead = import("parse.noja").parseHead;
Version = {
major: int,
minor: int
};
Host = {
name: String,
port: ?int
};
URL = {
schema: ?String,
host : ?Host,
path : String,
query : ?String,
fragment: ?String
};
Request = {
method : String,
url : URL,
version: Version,
body : String
};
fun bodyBytesToString(body: None | Buffer | [Buffer, Buffer]) {
if type(body) == None:
body = "";
else if type(body) == Buffer:
body = buffer.toString(body);
else
body = cat(buffer.toString(body[0]),
buffer.toString(body[1]));
return body;
}
fun printBody(body: None | Buffer | [Buffer, Buffer])
print(bodyToString(body));
fun fromSocket(fd: int, max_head: int = 1024) {
{
# Create a buffer to hold the received bytes
head_buffer = buffer.new(max_head);
# Receive bytes up to the buffer's size
received_bytes, error = net.recv(fd, head_buffer);
if error != none:
return none, error, true;
# Downsize the buffer to the received amount
head_buffer = buffer.sliceUp(head_buffer, 0, received_bytes);
assert(count(head_buffer) == received_bytes);
# Convert the received data to a string
text, error = buffer.toString(head_buffer);
if error != none:
return none, error, false; # Request isn't UTF-8
}
{
# Parse the request head's information
request, error, parsed_bytes = parseHead(text);
if error != none:
return none, error, false;
# Split the received data into head and body.
head_bytes = buffer.sliceUp(head_buffer, 0, parsed_bytes);
body_bytes = buffer.sliceUp(head_buffer, parsed_bytes, count(head_buffer) - parsed_bytes);
}
# Receive the remaining portion of the
# request's body (if it wasn't already)
{
x = request.headers['Content-Length'];
if x == none:
content_length = 0;
else
content_length = string.toInt(string.trim(x));
# TODO: Limit the content length
waiting_bytes = content_length - count(body_bytes);
assert(waiting_bytes >= 0);
if waiting_bytes > 0: {
second_half = buffer.new(waiting_bytes);
received_bytes, error = net.recv(fd, second_half);
if error != none:
return none, error, true; # Failed to receive the second half of the body
assert(received_bytes == waiting_bytes);
body_bytes = [body_bytes, second_half];
}
}
request.body = bodyBytesToString(body_bytes);
return request;
}