Skip to content

Commit d0cbfc1

Browse files
authored
x.vweb: accept query params as method arguments (#21201)
1 parent c2c83f7 commit d0cbfc1

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

vlib/x/vweb/tests/vweb_test.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ fn test_login_with_multipart_form_data_send_by_fetch() {
249249
assert x.body == 'username: xmyusernamex | password: xmypassword123x'
250250
}
251251

252+
fn test_query_params_are_passed_as_arguments() {
253+
x := http.get('http://${localserver}/query_echo?c=3&a="test"&b=20')!
254+
assert x.status() == .ok
255+
assert x.body == 'a: x"test"x | b: x20x'
256+
}
257+
252258
fn test_host() {
253259
mut req := http.Request{
254260
url: 'http://${localserver}/with_host'

vlib/x/vweb/tests/vweb_test_server.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ pub fn (mut app ServerApp) file_echo(mut ctx ServerContext) vweb.Result {
114114
return ctx.text(ctx.files['file'][0].data)
115115
}
116116

117+
@['/query_echo']
118+
pub fn (mut app ServerApp) query_echo(mut ctx ServerContext, a string, b int) vweb.Result {
119+
return ctx.text('a: x${a}x | b: x${b}x')
120+
}
121+
117122
// Make sure [post] works without the path
118123
@[post]
119124
pub fn (mut app ServerApp) json(mut ctx ServerContext) vweb.Result {

vlib/x/vweb/vweb.v

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string
824824

825825
// Skip if the host does not match or is empty
826826
if route.host == '' || route.host == host {
827+
can_have_data_args := user_context.Context.req.method == .post
828+
|| user_context.Context.req.method == .get
827829
// Route immediate matches first
828830
// For example URL `/register` matches route `/:user`, but `fn register()`
829831
// should be called first.
@@ -836,12 +838,19 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string
836838
}
837839
}
838840

839-
if user_context.Context.req.method == .post && method.args.len > 1 {
840-
// Populate method args with form values
841+
if method.args.len > 1 && can_have_data_args {
842+
// Populate method args with form or query values
841843
mut args := []string{cap: method.args.len + 1}
844+
data := if user_context.Context.req.method == .get {
845+
user_context.Context.query
846+
} else {
847+
user_context.Context.form
848+
}
849+
842850
for param in method.args[1..] {
843-
args << user_context.Context.form[param.name]
851+
args << data[param.name]
844852
}
853+
845854
app.$method(mut user_context, args)
846855
} else {
847856
app.$method(mut user_context)
@@ -857,7 +866,24 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string
857866
}
858867
}
859868

860-
app.$method(mut user_context)
869+
if method.args.len > 1 && can_have_data_args {
870+
// Populate method args with form or query values
871+
mut args := []string{cap: method.args.len + 1}
872+
873+
data := if user_context.Context.req.method == .get {
874+
user_context.Context.query
875+
} else {
876+
user_context.Context.form
877+
}
878+
879+
for param in method.args[1..] {
880+
args << data[param.name]
881+
}
882+
883+
app.$method(mut user_context, args)
884+
} else {
885+
app.$method(mut user_context)
886+
}
861887
return
862888
}
863889

0 commit comments

Comments
 (0)