forked from vieter-v/vieter
refactor(web): some small refactors
parent
8a0214babe
commit
8099acff01
|
@ -6,7 +6,7 @@ import os
|
|||
|
||||
// reader_to_writer tries to consume the entire reader & write it to the writer.
|
||||
pub fn reader_to_writer(mut reader io.Reader, mut writer io.Writer) ! {
|
||||
mut buf := []u8{len: 10 * 1024}
|
||||
mut buf := []u8{len: 8192}
|
||||
|
||||
for {
|
||||
bytes_read := reader.read(mut buf) or { break }
|
||||
|
@ -27,7 +27,7 @@ pub fn reader_to_file(mut reader io.BufferedReader, length int, path string) ! {
|
|||
file.close()
|
||||
}
|
||||
|
||||
mut buf := []u8{len: reader_buf_size}
|
||||
mut buf := []u8{len: 8192}
|
||||
mut bytes_left := length
|
||||
|
||||
// Repeat as long as the stream still has data
|
||||
|
@ -47,49 +47,3 @@ pub fn reader_to_file(mut reader io.BufferedReader, length int, path string) ! {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// match_array_in_array<T> returns how many elements of a2 overlap with a1. For
|
||||
// example, if a1 = "abcd" & a2 = "cd", the result will be 2. If the match is
|
||||
// not at the end of a1, the result is 0.
|
||||
pub fn match_array_in_array<T>(a1 []T, a2 []T) int {
|
||||
mut i := 0
|
||||
mut match_len := 0
|
||||
|
||||
for i + match_len < a1.len {
|
||||
if a1[i + match_len] == a2[match_len] {
|
||||
match_len += 1
|
||||
} else {
|
||||
i += match_len + 1
|
||||
match_len = 0
|
||||
}
|
||||
}
|
||||
|
||||
return match_len
|
||||
}
|
||||
|
||||
// read_until_separator consumes an io.Reader until it encounters some
|
||||
// separator array. The data read is stored inside the provided res array.
|
||||
pub fn read_until_separator(mut reader io.Reader, mut res []u8, sep []u8) ! {
|
||||
mut buf := []u8{len: sep.len}
|
||||
|
||||
for {
|
||||
c := reader.read(mut buf)!
|
||||
res << buf[..c]
|
||||
|
||||
match_len := match_array_in_array(buf[..c], sep)
|
||||
|
||||
if match_len == sep.len {
|
||||
break
|
||||
}
|
||||
|
||||
if match_len > 0 {
|
||||
match_left := sep.len - match_len
|
||||
c2 := reader.read(mut buf[..match_left])!
|
||||
res << buf[..c2]
|
||||
|
||||
if buf[..c2] == sep[match_len..] {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,7 @@ module util
|
|||
import os
|
||||
import crypto.sha256
|
||||
|
||||
const (
|
||||
reader_buf_size = 1_000_000
|
||||
prefixes = ['B', 'KB', 'MB', 'GB']
|
||||
)
|
||||
const prefixes = ['B', 'KB', 'MB', 'GB']
|
||||
|
||||
// Dummy struct to work around the fact that you can only share structs, maps &
|
||||
// arrays
|
||||
|
@ -24,18 +21,13 @@ pub fn exit_with_message(code int, msg string) {
|
|||
|
||||
// hash_file returns the sha256 hash of a given file
|
||||
pub fn hash_file(path &string) !string {
|
||||
file := os.open(path) or { return error('Failed to open file.') }
|
||||
file := os.open(path)!
|
||||
|
||||
mut sha256sum := sha256.new()
|
||||
mut buf := []u8{len: 8192}
|
||||
|
||||
buf_size := int(1_000_000)
|
||||
mut buf := []u8{len: buf_size}
|
||||
mut bytes_left := os.file_size(path)
|
||||
|
||||
for bytes_left > 0 {
|
||||
// TODO check if just breaking here is safe
|
||||
bytes_read := file.read(mut buf) or { return error('Failed to read from file.') }
|
||||
bytes_left -= u64(bytes_read)
|
||||
for !file.eof() {
|
||||
bytes_read := file.read(mut buf)!
|
||||
|
||||
// This function never actually fails, but returns an option to follow
|
||||
// the Writer interface.
|
||||
|
|
|
@ -75,7 +75,7 @@ fn (mut ctx Context) send_string(s string) ! {
|
|||
// to the TCP connection socket. Internally, a 10KB buffer is used, to avoid
|
||||
// having to store all bytes in memory at once.
|
||||
fn (mut ctx Context) send_reader(mut reader io.Reader, size u64) ! {
|
||||
mut buf := []u8{len: 10_000}
|
||||
mut buf := []u8{len: 8192}
|
||||
mut bytes_left := size
|
||||
|
||||
// Repeat as long as the stream still has data
|
||||
|
@ -156,15 +156,11 @@ pub fn (mut ctx Context) json<T>(status http.Status, j T) Result {
|
|||
return Result{}
|
||||
}
|
||||
|
||||
// file Response HTTP_OK with file as payload
|
||||
// This function manually implements responses because it needs to stream the file contents
|
||||
// File serves the given file path by streaming its content to the client.
|
||||
pub fn (mut ctx Context) file(f_path string) Result {
|
||||
// If the file doesn't exist, just respond with a 404
|
||||
if !os.is_file(f_path) {
|
||||
ctx.status = .not_found
|
||||
ctx.send()
|
||||
|
||||
return Result{}
|
||||
return ctx.status(.not_found)
|
||||
}
|
||||
|
||||
ctx.header.add(.accept_ranges, 'bytes')
|
||||
|
@ -180,9 +176,11 @@ pub fn (mut ctx Context) file(f_path string) Result {
|
|||
}
|
||||
|
||||
mut file := os.open(f_path) or {
|
||||
eprintln(err.msg())
|
||||
ctx.server_error(500)
|
||||
return Result{}
|
||||
lock ctx.logger {
|
||||
ctx.logger.error('Error in file(): $err.msg()')
|
||||
}
|
||||
|
||||
return ctx.status(.internal_server_error)
|
||||
}
|
||||
|
||||
defer {
|
||||
|
@ -217,8 +215,11 @@ pub fn (mut ctx Context) file(f_path string) Result {
|
|||
|
||||
// Move cursor to start of data to read
|
||||
file.seek(start, .start) or {
|
||||
ctx.server_error(500)
|
||||
return Result{}
|
||||
lock ctx.logger {
|
||||
ctx.logger.error('Error in file(): $err.msg()')
|
||||
}
|
||||
|
||||
return ctx.status(.internal_server_error)
|
||||
}
|
||||
|
||||
length := end - u64(start) + 1
|
||||
|
@ -242,13 +243,6 @@ pub fn (mut ctx Context) status(status http.Status) Result {
|
|||
return Result{}
|
||||
}
|
||||
|
||||
// server_error Response a server error
|
||||
pub fn (mut ctx Context) server_error(ecode int) Result {
|
||||
ctx.send_custom_response(http_500) or {}
|
||||
|
||||
return Result{}
|
||||
}
|
||||
|
||||
// redirect Redirect to an url
|
||||
pub fn (mut ctx Context) redirect(url string) Result {
|
||||
mut resp := http_302
|
||||
|
@ -335,8 +329,11 @@ fn handle_conn<T>(mut conn net.TcpConn, mut app T, routes map[string]Route) {
|
|||
head := http.parse_request_head(mut reader) or {
|
||||
// Prevents errors from being thrown when BufferedReader is empty
|
||||
if '$err' != 'none' {
|
||||
eprintln('error parsing request head: $err')
|
||||
lock app.logger {
|
||||
app.logger.error('error parsing request head: $err')
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -357,7 +354,10 @@ fn handle_conn<T>(mut conn net.TcpConn, mut app T, routes map[string]Route) {
|
|||
|
||||
// URL Parse
|
||||
url := urllib.parse(head.url) or {
|
||||
eprintln('error parsing path: $err')
|
||||
lock app.logger {
|
||||
app.logger.error('error parsing path: $err')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue