From f252d3e2e0294a91940c0adc11a8041744c095c6 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 26 Nov 2025 08:35:51 +0200 Subject: [PATCH] veb: remove commented code, cleanup formatting --- vlib/veb/context.v | 40 ++++------------------------- vlib/veb/tests/veb_test_server.v | 2 -- vlib/veb/tr.v | 11 -------- vlib/veb/veb.v | 24 ------------------ vlib/veb/veb_picoev.v | 43 +++----------------------------- 5 files changed, 8 insertions(+), 112 deletions(-) diff --git a/vlib/veb/context.v b/vlib/veb/context.v index 5573eaece..9441b815b 100644 --- a/vlib/veb/context.v +++ b/vlib/veb/context.v @@ -93,12 +93,6 @@ pub fn (mut ctx Context) set_custom_header(key string, value string) ! { // send_response_to_client finalizes the response headers and sets Content-Type to `mimetype` // and the response body to `response` pub fn (mut ctx Context) send_response_to_client(mimetype string, response string) Result { - // println('send_response_to_client') - // print_backtrace() - // println('ctx=') - // println(ctx) - // println('sending resp=') - // println(response) if ctx.done && !ctx.takeover { eprintln('[veb] a response cannot be sent twice over one connection') return Result{} @@ -112,7 +106,6 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, response strin ctx.res.body = response.replace('', '\n') } } - // set Content-Type and Content-Length headers mut custom_mimetype := if ctx.content_type.len == 0 { mimetype } else { ctx.content_type } if custom_mimetype != '' { @@ -133,7 +126,6 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, response strin if ctx.res.status_code == 0 { ctx.res.set_status(.ok) } - if ctx.takeover { println('calling fast send resp') fast_send_resp(mut ctx.conn, ctx.res) or {} @@ -171,9 +163,7 @@ pub fn (mut ctx Context) file(file_path string) Result { eprintln('[veb] file "${file_path}" does not exist') return ctx.not_found() } - ext := os.file_ext(file_path) - mut content_type := ctx.content_type if content_type.len == 0 { if ct := ctx.custom_mime_types[ext] { @@ -182,12 +172,10 @@ pub fn (mut ctx Context) file(file_path string) Result { content_type = mime_types[ext] } } - if content_type.len == 0 { eprintln('[veb] no MIME type found for extension "${ext}"') return ctx.server_error('') } - return ctx.send_file(content_type, file_path) } @@ -197,7 +185,6 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { ctx.res.set_status(.not_found) return ctx.text('resource does not exist') } - // seek from file end to get the file size file.seek(0, .end) or { eprintln('[veb] error while trying to read file: ${err.msg()}') @@ -208,24 +195,19 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { return ctx.server_error('could not read resource') } file.close() - // Check which encodings the client accepts accept_encoding := ctx.req.header.get(.accept_encoding) or { '' } client_accepts_zstd := accept_encoding.contains('zstd') client_accepts_gzip := accept_encoding.contains('gzip') - max_size_bytes := ctx.static_compression_max_size - // Determine which compression modes are enabled use_zstd := (ctx.enable_static_zstd && client_accepts_zstd) || (ctx.enable_static_compression && client_accepts_zstd) use_gzip := (ctx.enable_static_gzip && client_accepts_gzip) || (ctx.enable_static_compression && client_accepts_gzip) - // Try to serve pre-compressed files if any compression is enabled if use_zstd || use_gzip { orig_mtime := os.file_last_mod_unix(file_path) - // Try zstd first if enabled (better compression), then gzip if use_zstd { if ctx.serve_precompressed_file(content_type, file_path, '.zst', 'zstd', orig_mtime) { @@ -237,7 +219,6 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { return Result{} } } - // No pre-compressed file available: create one if file is small enough if file_size < max_size_bytes { // Load, compress, save, and serve @@ -245,7 +226,6 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { eprintln('[veb] error while trying to read file: ${err.msg()}') return ctx.server_error('could not read resource') } - // Try zstd first if enabled, then gzip if use_zstd { if result := ctx.serve_compressed_static(content_type, file_path, data, @@ -261,7 +241,6 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { return result } } - // Compression failed: serve uncompressed in streaming mode ctx.return_type = .file ctx.return_file = file_path @@ -269,7 +248,6 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { return ctx.send_response_to_client(content_type, '') } } - // Takeover mode: load file in memory (backward compatibility) if ctx.takeover { data := os.read_file(file_path) or { @@ -278,13 +256,11 @@ fn (mut ctx Context) send_file(content_type string, file_path string) Result { } return ctx.send_response_to_client(content_type, data) } - // Default: serve uncompressed file in streaming mode (zero-copy sendfile) ctx.return_type = .file ctx.return_file = file_path ctx.res.header.set(.content_length, file_size.str()) - ctx.send_response_to_client(content_type, '') - return Result{} + return ctx.send_response_to_client(content_type, '') } // serve_precompressed_file serves an existing pre-compressed file (.zst or .gz) if it exists and is fresh. @@ -305,8 +281,8 @@ fn (mut ctx Context) serve_precompressed_file(content_type string, file_path str ctx.res.header.set(.vary, 'Accept-Encoding') compressed_size := os.file_size(compressed_path) ctx.res.header.set(.content_length, compressed_size.str()) - ctx.send_response_to_client(content_type, '') ctx.already_compressed = true + ctx.send_response_to_client(content_type, '') return true } @@ -323,16 +299,14 @@ fn (mut ctx Context) serve_compressed_static(content_type string, file_path stri c, '.gz', 'gzip' } } - compressed_path := '${file_path}${ext}' - // Try to save compressed version for future requests mut write_success := true os.write_file(compressed_path, compressed.bytestr()) or { eprintln('[veb] warning: could not save ${ext} file (readonly filesystem?): ${err.msg()}') write_success = false } - + ctx.already_compressed = true if write_success { // Serve the newly cached file in streaming mode (zero-copy) ctx.return_type = .file @@ -340,16 +314,13 @@ fn (mut ctx Context) serve_compressed_static(content_type string, file_path stri ctx.res.header.set(.content_encoding, encoding_name) ctx.res.header.set(.vary, 'Accept-Encoding') ctx.res.header.set(.content_length, compressed.len.str()) - ctx.send_response_to_client(content_type, '') - ctx.already_compressed = true + return ctx.send_response_to_client(content_type, '') } else { // Fallback: serve compressed content from memory (no caching) ctx.res.header.set(.content_encoding, encoding_name) ctx.res.header.set(.vary, 'Accept-Encoding') - ctx.send_response_to_client(content_type, compressed.bytestr()) - ctx.already_compressed = true + return ctx.send_response_to_client(content_type, compressed.bytestr()) } - return Result{} } // Response HTTP_OK with s as payload @@ -392,7 +363,6 @@ pub: pub fn (mut ctx Context) redirect(url string, params RedirectParams) Result { status := http.Status(params.typ) ctx.res.set_status(status) - ctx.res.header.add(.location, url) return ctx.send_response_to_client('text/plain', status.str()) } diff --git a/vlib/veb/tests/veb_test_server.v b/vlib/veb/tests/veb_test_server.v index 02ec2ae1d..41aeac558 100644 --- a/vlib/veb/tests/veb_test_server.v +++ b/vlib/veb/tests/veb_test_server.v @@ -93,7 +93,6 @@ pub fn (mut app ServerApp) user_repo_settings(mut ctx ServerContext, username st @['/json_echo'; post] pub fn (mut app ServerApp) json_echo(mut ctx ServerContext) veb.Result { - // eprintln('>>>>> received http request at /json_echo is: $app.req') ctx.set_content_type(ctx.req.header.get(.content_type) or { '' }) return ctx.ok(ctx.req.data) } @@ -127,7 +126,6 @@ pub fn (mut app ServerApp) query_echo(mut ctx ServerContext, a string, b int) ve // Make sure [post] works without the path @[post] pub fn (mut app ServerApp) json(mut ctx ServerContext) veb.Result { - // eprintln('>>>>> received http request at /json is: $app.req') ctx.set_content_type(ctx.req.header.get(.content_type) or { '' }) return ctx.ok(ctx.req.data) } diff --git a/vlib/veb/tr.v b/vlib/veb/tr.v index d7b4b2325..a5e13a715 100644 --- a/vlib/veb/tr.v +++ b/vlib/veb/tr.v @@ -11,13 +11,6 @@ pub fn raw(s string) RawHtml { return RawHtml(s) } -/* -struct TrData { - data -} - m map[string]TrData - */ - // This function is run once, on app startup. Setting the `tr_map` const. // m['en']['house'] == 'House' fn load_tr_map() map[string]map[string]string { @@ -32,14 +25,10 @@ fn load_tr_map() map[string]map[string]string { } x := text.split('-----\n') for s in x { - // println('val="${val}"') nl_pos := s.index('\n') or { continue } key := s[..nl_pos] val := s[nl_pos + 1..] - // v := vals[i + 1] - // println('key="${key}" => val="${v}"') res[lang][key] = val - // println(val) } } return res diff --git a/vlib/veb/veb.v b/vlib/veb/veb.v index 532fd1d79..5f1a0ba79 100644 --- a/vlib/veb/veb.v +++ b/vlib/veb/veb.v @@ -144,7 +144,6 @@ mut: } fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string, routes &map[string]Route) { - // println('\n\nhandle_route() url=${url} routes=${routes}') mut route := Route{} mut middleware_has_sent_response := false mut not_found := false @@ -220,11 +219,6 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string } } - // defer { - // println('USER CONTEXT at end of handle_route') - // println(user_context) - //} - // Route matching and match route specific middleware as last step $for method in A.methods { $if method.return_type is Result { @@ -253,7 +247,6 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string return } } - if method.args.len > 1 && can_have_data_args { // Populate method args with form or query values mut args := []string{cap: method.args.len + 1} @@ -262,21 +255,16 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string } else { user_context.Context.form } - for param in method.args[1..] { args << data[param.name] } - - // println('m1') app.$method(mut user_context, args) } else { - // println('m2') app.$method(mut user_context) } return } - // println('route_words=${route_words} method=${method}') if url_words.len == 0 && route_words == ['index'] && method.name == 'index' { $if A is MiddlewareApp { if validate_middleware[X](mut user_context, route.middlewares) == false { @@ -288,21 +276,16 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string if method.args.len > 1 && can_have_data_args { // Populate method args with form or query values mut args := []string{cap: method.args.len + 1} - data := if user_context.Context.req.method == .get { user_context.Context.query } else { user_context.Context.form } - for param in method.args[1..] { args << data[param.name] } - - // println('m3') app.$method(mut user_context, args) } else { - // println('m4') app.$method(mut user_context) } return @@ -315,12 +298,10 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string return } } - method_args := params.clone() if method_args.len + 1 != method.args.len { eprintln('[veb] warning: uneven parameters count (${method.args.len}) in `${method.name}`, compared to the veb route `${method.attrs}` (${method_args.len})') } - // println('m5') app.$method(mut user_context, method_args) return } @@ -335,7 +316,6 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string } fn route_matches(url_words []string, route_words []string) ?[]string { - // println('route_matches(url_words:${url_words} route_words:${route_words}') // URL path should be at least as long as the route path // except for the catchall route (`/:path...`) if route_words.len == 1 && route_words[0].starts_with(':') && route_words[0].ends_with('...') { @@ -344,7 +324,6 @@ fn route_matches(url_words []string, route_words []string) ?[]string { if url_words.len < route_words.len { return none } - mut params := []string{cap: url_words.len} if url_words.len == route_words.len { for i in 0 .. url_words.len { @@ -474,9 +453,6 @@ fn send_string_ptr(mut conn net.TcpConn, ptr &u8, len int) !int { $if trace_send_string_conn ? { eprintln('> send_string: conn: ${ptr_str(conn)}') } - // $if trace_response ? { - // eprintln('> send_string:\n${s}\n') - // } if voidptr(conn) == unsafe { nil } { return error('connection was closed before send_string') } diff --git a/vlib/veb/veb_picoev.v b/vlib/veb/veb_picoev.v index 732e4422a..989cf2560 100644 --- a/vlib/veb/veb_picoev.v +++ b/vlib/veb/veb_picoev.v @@ -19,35 +19,26 @@ $if !new_veb ? { if params.port <= 0 || params.port > 65535 { return error('invalid port number `${params.port}`, it should be between 1 and 65535') } - routes := generate_routes[A, X](global_app)! controllers_sorted := check_duplicate_routes_in_controllers[A](global_app, routes)! - if params.show_startup_message { host := if params.host == '' { 'localhost' } else { params.host } println('[veb] Running app on http://${host}:${params.port}/') } flush_stdout() - mut pico_context := &RequestParams{ global_app: unsafe { global_app } controllers: controllers_sorted routes: &routes timeout_in_seconds: params.timeout_in_seconds } - pico_context.idx = []int{len: picoev.max_fds} // reserve space for read and write buffers pico_context.buf = unsafe { malloc_noscan(picoev.max_fds * max_read + 1) } - defer { - unsafe { - free(pico_context.buf) - } - } + defer { unsafe { free(pico_context.buf) } } pico_context.incomplete_requests = []http.Request{len: picoev.max_fds} pico_context.file_responses = []FileResponse{len: picoev.max_fds} pico_context.string_responses = []StringResponse{len: picoev.max_fds} - mut pico := picoev.new( port: params.port raw_cb: ev_callback[A, X] @@ -56,11 +47,9 @@ $if !new_veb ? { family: params.family host: params.host )! - $if A is BeforeAcceptApp { global_app.before_accept_loop() } - // Forever accept every connection that comes pico.serve() } @@ -68,18 +57,15 @@ $if !new_veb ? { @[direct_array_access] fn ev_callback[A, X](mut pv picoev.Picoev, fd int, events int) { mut params := unsafe { &RequestParams(pv.user_data) } - if events == picoev.picoev_timeout { $if trace_picoev_callback ? { eprintln('> request timeout on file descriptor ${fd}') } - handle_timeout(mut pv, mut params, fd) } else if events == picoev.picoev_write { $if trace_picoev_callback ? { eprintln('> write event on file descriptor ${fd}') } - if params.file_responses[fd].open { handle_write_file(mut pv, mut params, fd) } else if params.string_responses[fd].open { @@ -97,7 +83,6 @@ $if !new_veb ? { $if trace_picoev_callback ? { eprintln('> read event on file descriptor ${fd}') } - // println('ev_callback fd=${fd} params.routes=${params.routes.len}') handle_read[A, X](mut pv, mut params, fd) } else { // should never happen @@ -111,7 +96,6 @@ $if !new_veb ? { handle: fd is_blocking: false } - fast_send_resp(mut conn, http_408) or {} pv.close_conn(fd) params.request_done(fd) @@ -143,7 +127,6 @@ $if !new_veb ? { is_blocking: false write_timeout: params.timeout_in_seconds * time.second } - params.file_responses[fd].file.read_into_ptr(data, bytes_to_write) or { params.file_responses[fd].done() pv.close_conn(fd) @@ -156,7 +139,6 @@ $if !new_veb ? { } params.file_responses[fd].pos += actual_written } - if params.file_responses[fd].pos == params.file_responses[fd].total { // file is done writing params.file_responses[fd].done() @@ -203,20 +185,14 @@ $if !new_veb ? { // and the connection stays open until it is ready to read again @[direct_array_access; manualfree] fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) { - // println('handle_read() fd=${fd} params.routes=${params.routes}') mut conn := &net.TcpConn{ sock: net.tcp_socket_from_handle_raw(fd) handle: fd is_blocking: false } - // cap the max_read to 8KB mut reader := io.new_buffered_reader(reader: conn, cap: max_read) - defer { - unsafe { - reader.free() - } - } + defer { unsafe { reader.free() } } // take the previous incomplete request mut req := params.incomplete_requests[fd] // check if there is an incomplete request for this file descriptor @@ -338,9 +314,7 @@ $if !new_veb ? { } } } - defer { - params.request_done(fd) - } + defer { params.request_done(fd) } if completed_context := handle_request[A, X](mut conn, req, params) { if completed_context.takeover { // the connection should be kept open, but removed from the picoev loop. @@ -426,20 +400,16 @@ $if !new_veb ? { } fn handle_request[A, X](mut conn net.TcpConn, req http.Request, params &RequestParams) ?&Context { - // println('handle_request() params.routes=${params.routes}') mut global_app := unsafe { &A(params.global_app) } - // TODO: change this variable to include the total wait time over each network cycle // maybe store it in Request.user_ptr ? page_gen_start := time.ticks() - $if trace_request ? { dump(req) } $if trace_request_url ? { dump(req.url) } - // parse the URL, query and form data mut url := urllib.parse(req.url) or { eprintln('[veb] error parsing path "${req.url}": ${err}') @@ -452,11 +422,9 @@ $if !new_veb ? { conn.write(http_400.bytes()) or {} return none } - // remove the port from the HTTP Host header host_with_port := req.header.get(.host) or { '' } host, _ := urllib.split_host_port(host_with_port) - // Create Context with request data mut ctx := &Context{ req: req @@ -466,7 +434,6 @@ $if !new_veb ? { form: form files: files } - if connection_header := req.header.get(.connection) { // A client that does not support persistent connections MUST send the // "close" connection option in every request message. @@ -474,11 +441,9 @@ $if !new_veb ? { ctx.client_wants_to_close = true } } - $if A is StaticApp { ctx.custom_mime_types = global_app.static_mime_types.clone() } - // match controller paths $if A is ControllerInterface { if completed_context := handle_controllers[X](params.controllers, ctx, mut @@ -487,11 +452,9 @@ $if !new_veb ? { return completed_context } } - // create a new user context and pass the veb's context mut user_context := X{} user_context.Context = ctx - handle_route[A, X](mut global_app, mut user_context, url, host, params.routes) // we need to explicitly tell the V compiler to return a reference return &user_context.Context -- 2.39.5