Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions vlib/vweb/tests/controller_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ fn test_other_path() {
assert x.body == 'Other path'
}

fn test_other_hided_home() {
x := http.get('http://${localserver}/other/hide') or { panic(err) }
assert x.body == 'Other'
}

fn test_other_hided_path() {
x := http.get('http://${localserver}/other/hide/path') or { panic(err) }
assert x.body == 'Other path'
}

fn test_different_404() {
res_app := http.get('http://${localserver}/zxcnbnm') or { panic(err) }
assert res_app.status() == .not_found
Expand Down
15 changes: 15 additions & 0 deletions vlib/vweb/tests/controller_test_server.v
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ struct Other {
vweb.Context
}

struct OtherHidedByOther {
vweb.Context
}

fn exit_after_timeout(timeout_in_ms int) {
time.sleep(timeout_in_ms * time.millisecond)
println('>> webserver: pid: ${os.getpid()}, exiting ...')
Expand All @@ -38,6 +42,7 @@ fn main() {
controllers: [
vweb.controller('/admin', &Admin{}),
vweb.controller('/other', &Other{}),
vweb.controller('/other/hide', &OtherHidedByOther{}),
]
}

Expand Down Expand Up @@ -85,6 +90,16 @@ pub fn (mut app Other) other_path() vweb.Result {
return app.text('Other path')
}

['/']
pub fn (mut app OtherHidedByOther) other_home() vweb.Result {
return app.text('Other')
}

['/path']
pub fn (mut app OtherHidedByOther) other_path() vweb.Result {
return app.text('Other path')
}

// utility functions:

pub fn (mut app App) shutdown() vweb.Result {
Expand Down
21 changes: 15 additions & 6 deletions vlib/vweb/vweb.v
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,16 @@ pub fn run_at[T](global_app &T, params RunParams) ! {

routes := generate_routes(global_app)!
// check duplicate routes in controllers
mut controllers_sorted := []&ControllerPath{}
$if T is ControllerInterface {
mut paths := []string{}
for controller in global_app.controllers {
controllers_sorted = global_app.controllers.clone()
controllers_sorted.sort(a.path.len > b.path.len)
for controller in controllers_sorted {
if controller.host == '' {
if controller.path in paths {
return error('conflicting paths: duplicate controller handling the route "${controller.path}"')
}
paths << controller.path
}
}
Expand Down Expand Up @@ -564,6 +570,7 @@ pub fn run_at[T](global_app &T, params RunParams) ! {
ch <- &RequestParams{
connection: connection
global_app: unsafe { global_app }
controllers: controllers_sorted
routes: &routes
}
}
Expand Down Expand Up @@ -612,7 +619,7 @@ fn new_request_app[T](global_app &T, ctx Context, tid int) &T {
}

[manualfree]
fn handle_conn[T](mut conn net.TcpConn, global_app &T, routes &map[string]Route, tid int) {
fn handle_conn[T](mut conn net.TcpConn, global_app &T, controllers []&ControllerPath, routes &map[string]Route, tid int) {
conn.set_read_timeout(30 * time.second)
conn.set_write_timeout(30 * time.second)
defer {
Expand Down Expand Up @@ -680,7 +687,7 @@ fn handle_conn[T](mut conn net.TcpConn, global_app &T, routes &map[string]Route,

// match controller paths
$if T is ControllerInterface {
for controller in global_app.controllers {
for controller in controllers {
// skip controller if the hosts don't match
if controller.host != '' && host != controller.host {
continue
Expand Down Expand Up @@ -1077,8 +1084,9 @@ fn filter(s string) string {

// Worker functions for the thread pool:
struct RequestParams {
global_app voidptr
routes &map[string]Route
global_app voidptr
controllers []&ControllerPath
routes &map[string]Route
mut:
connection &net.TcpConn
}
Expand All @@ -1103,7 +1111,8 @@ fn (mut w Worker[T]) process_incomming_requests() {
$if vweb_trace_worker_scan ? {
eprintln(sid)
}
handle_conn[T](mut params.connection, params.global_app, params.routes, w.id)
handle_conn[T](mut params.connection, params.global_app, params.controllers, params.routes,
w.id)
}
$if vweb_trace_worker_scan ? {
eprintln('[vweb] closing worker ${w.id}.')
Expand Down