x.vweb: accept query params as method arguments (#21201)

This commit is contained in:
Casper Küthe 2024-04-07 08:20:55 +02:00 committed by GitHub
parent c2c83f78f3
commit d0cbfc1461
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 5 deletions

View File

@ -249,6 +249,12 @@ fn test_login_with_multipart_form_data_send_by_fetch() {
assert x.body == 'username: xmyusernamex | password: xmypassword123x' assert x.body == 'username: xmyusernamex | password: xmypassword123x'
} }
fn test_query_params_are_passed_as_arguments() {
x := http.get('http://${localserver}/query_echo?c=3&a="test"&b=20')!
assert x.status() == .ok
assert x.body == 'a: x"test"x | b: x20x'
}
fn test_host() { fn test_host() {
mut req := http.Request{ mut req := http.Request{
url: 'http://${localserver}/with_host' url: 'http://${localserver}/with_host'

View File

@ -114,6 +114,11 @@ pub fn (mut app ServerApp) file_echo(mut ctx ServerContext) vweb.Result {
return ctx.text(ctx.files['file'][0].data) return ctx.text(ctx.files['file'][0].data)
} }
@['/query_echo']
pub fn (mut app ServerApp) query_echo(mut ctx ServerContext, a string, b int) vweb.Result {
return ctx.text('a: x${a}x | b: x${b}x')
}
// Make sure [post] works without the path // Make sure [post] works without the path
@[post] @[post]
pub fn (mut app ServerApp) json(mut ctx ServerContext) vweb.Result { pub fn (mut app ServerApp) json(mut ctx ServerContext) vweb.Result {

View File

@ -824,6 +824,8 @@ fn handle_route[A, X](mut app A, mut user_context X, url urllib.URL, host string
// Skip if the host does not match or is empty // Skip if the host does not match or is empty
if route.host == '' || route.host == host { if route.host == '' || route.host == host {
can_have_data_args := user_context.Context.req.method == .post
|| user_context.Context.req.method == .get
// Route immediate matches first // Route immediate matches first
// For example URL `/register` matches route `/:user`, but `fn register()` // For example URL `/register` matches route `/:user`, but `fn register()`
// should be called first. // 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
} }
} }
if user_context.Context.req.method == .post && method.args.len > 1 { if method.args.len > 1 && can_have_data_args {
// Populate method args with form values // Populate method args with form or query values
mut args := []string{cap: method.args.len + 1} mut args := []string{cap: method.args.len + 1}
for param in method.args[1..] { data := if user_context.Context.req.method == .get {
args << user_context.Context.form[param.name] user_context.Context.query
} else {
user_context.Context.form
} }
for param in method.args[1..] {
args << data[param.name]
}
app.$method(mut user_context, args) app.$method(mut user_context, args)
} else { } else {
app.$method(mut user_context) 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
} }
} }
app.$method(mut user_context) 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]
}
app.$method(mut user_context, args)
} else {
app.$method(mut user_context)
}
return return
} }