Skip to content

Commit 9c068ce

Browse files
DracksWertzui123
authored andcommitted
vweb: avoid the controllers having to be defined in specific order (vlang#19182)
1 parent 5d02d14 commit 9c068ce

3 files changed

Lines changed: 40 additions & 6 deletions

File tree

vlib/vweb/tests/controller_test.v

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ fn test_other_path() {
8888
assert x.body == 'Other path'
8989
}
9090

91+
fn test_other_hided_home() {
92+
x := http.get('http://${localserver}/other/hide') or { panic(err) }
93+
assert x.body == 'Other'
94+
}
95+
96+
fn test_other_hided_path() {
97+
x := http.get('http://${localserver}/other/hide/path') or { panic(err) }
98+
assert x.body == 'Other path'
99+
}
100+
91101
fn test_different_404() {
92102
res_app := http.get('http://${localserver}/zxcnbnm') or { panic(err) }
93103
assert res_app.status() == .not_found

vlib/vweb/tests/controller_test_server.v

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ struct Other {
1818
vweb.Context
1919
}
2020

21+
struct OtherHidedByOther {
22+
vweb.Context
23+
}
24+
2125
fn exit_after_timeout(timeout_in_ms int) {
2226
time.sleep(timeout_in_ms * time.millisecond)
2327
println('>> webserver: pid: ${os.getpid()}, exiting ...')
@@ -38,6 +42,7 @@ fn main() {
3842
controllers: [
3943
vweb.controller('/admin', &Admin{}),
4044
vweb.controller('/other', &Other{}),
45+
vweb.controller('/other/hide', &OtherHidedByOther{}),
4146
]
4247
}
4348

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

93+
['/']
94+
pub fn (mut app OtherHidedByOther) other_home() vweb.Result {
95+
return app.text('Other')
96+
}
97+
98+
['/path']
99+
pub fn (mut app OtherHidedByOther) other_path() vweb.Result {
100+
return app.text('Other path')
101+
}
102+
88103
// utility functions:
89104

90105
pub fn (mut app App) shutdown() vweb.Result {

vlib/vweb/vweb.v

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,16 @@ pub fn run_at[T](global_app &T, params RunParams) ! {
522522

523523
routes := generate_routes(global_app)!
524524
// check duplicate routes in controllers
525+
mut controllers_sorted := []&ControllerPath{}
525526
$if T is ControllerInterface {
526527
mut paths := []string{}
527-
for controller in global_app.controllers {
528+
controllers_sorted = global_app.controllers.clone()
529+
controllers_sorted.sort(a.path.len > b.path.len)
530+
for controller in controllers_sorted {
528531
if controller.host == '' {
532+
if controller.path in paths {
533+
return error('conflicting paths: duplicate controller handling the route "${controller.path}"')
534+
}
529535
paths << controller.path
530536
}
531537
}
@@ -564,6 +570,7 @@ pub fn run_at[T](global_app &T, params RunParams) ! {
564570
ch <- &RequestParams{
565571
connection: connection
566572
global_app: unsafe { global_app }
573+
controllers: controllers_sorted
567574
routes: &routes
568575
}
569576
}
@@ -612,7 +619,7 @@ fn new_request_app[T](global_app &T, ctx Context, tid int) &T {
612619
}
613620

614621
[manualfree]
615-
fn handle_conn[T](mut conn net.TcpConn, global_app &T, routes &map[string]Route, tid int) {
622+
fn handle_conn[T](mut conn net.TcpConn, global_app &T, controllers []&ControllerPath, routes &map[string]Route, tid int) {
616623
conn.set_read_timeout(30 * time.second)
617624
conn.set_write_timeout(30 * time.second)
618625
defer {
@@ -680,7 +687,7 @@ fn handle_conn[T](mut conn net.TcpConn, global_app &T, routes &map[string]Route,
680687

681688
// match controller paths
682689
$if T is ControllerInterface {
683-
for controller in global_app.controllers {
690+
for controller in controllers {
684691
// skip controller if the hosts don't match
685692
if controller.host != '' && host != controller.host {
686693
continue
@@ -1077,8 +1084,9 @@ fn filter(s string) string {
10771084

10781085
// Worker functions for the thread pool:
10791086
struct RequestParams {
1080-
global_app voidptr
1081-
routes &map[string]Route
1087+
global_app voidptr
1088+
controllers []&ControllerPath
1089+
routes &map[string]Route
10821090
mut:
10831091
connection &net.TcpConn
10841092
}
@@ -1103,7 +1111,8 @@ fn (mut w Worker[T]) process_incomming_requests() {
11031111
$if vweb_trace_worker_scan ? {
11041112
eprintln(sid)
11051113
}
1106-
handle_conn[T](mut params.connection, params.global_app, params.routes, w.id)
1114+
handle_conn[T](mut params.connection, params.global_app, params.controllers, params.routes,
1115+
w.id)
11071116
}
11081117
$if vweb_trace_worker_scan ? {
11091118
eprintln('[vweb] closing worker ${w.id}.')

0 commit comments

Comments
 (0)