From 8099acff018af77157cabc61fabd457f40c789d4 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 29 Dec 2022 23:25:45 +0100 Subject: [PATCH] refactor(web): some small refactors --- src/util/stream.v | 50 ++--------------------------------------------- src/util/util.v | 18 +++++------------ src/web/web.v | 42 +++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 82 deletions(-) diff --git a/src/util/stream.v b/src/util/stream.v index 15cc618..bfb8b81 100644 --- a/src/util/stream.v +++ b/src/util/stream.v @@ -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 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(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 - } - } - } -} diff --git a/src/util/util.v b/src/util/util.v index 213104c..5e2f755 100644 --- a/src/util/util.v +++ b/src/util/util.v @@ -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. diff --git a/src/web/web.v b/src/web/web.v index 565baff..d5013c4 100644 --- a/src/web/web.v +++ b/src/web/web.v @@ -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(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(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(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 }