mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vweb: fix parsing of form fields, send with multipart/form-data (by JS fetch)
This commit is contained in:
@@ -67,22 +67,25 @@ fn parse_query_from_url(url urllib.URL) map[string]string {
|
||||
return query
|
||||
}
|
||||
|
||||
const boundary_start = 'boundary='
|
||||
|
||||
fn parse_form_from_request(request http.Request) !(map[string]string, map[string][]http.FileData) {
|
||||
mut form := map[string]string{}
|
||||
mut files := map[string][]http.FileData{}
|
||||
if request.method in methods_with_form {
|
||||
ct := request.header.get(.content_type) or { '' }.split(';').map(it.trim_left(' \t'))
|
||||
if 'multipart/form-data' in ct {
|
||||
boundary := ct.filter(it.starts_with('boundary='))
|
||||
if boundary.len != 1 {
|
||||
return error('detected more that one form-data boundary')
|
||||
}
|
||||
// omit 'boundary="' and the last '"'
|
||||
boundary_str := boundary[0].substr(10, boundary[0].len - 1)
|
||||
form, files = http.parse_multipart_form(request.data, boundary_str)
|
||||
} else {
|
||||
form = http.parse_form(request.data)
|
||||
}
|
||||
if request.method !in [http.Method.post, .put, .patch] {
|
||||
return map[string]string{}, map[string][]http.FileData{}
|
||||
}
|
||||
return form, files
|
||||
ct := request.header.get(.content_type) or { '' }.split(';').map(it.trim_left(' \t'))
|
||||
if 'multipart/form-data' in ct {
|
||||
boundaries := ct.filter(it.starts_with(vweb.boundary_start))
|
||||
if boundaries.len != 1 {
|
||||
return error('detected more that one form-data boundary')
|
||||
}
|
||||
boundary := boundaries[0].all_after(vweb.boundary_start)
|
||||
if boundary.len > 0 && boundary[0] == `"` {
|
||||
// quotes are send by our http.post_multipart_form/2:
|
||||
return http.parse_multipart_form(request.data, boundary.trim('"'))
|
||||
}
|
||||
// Firefox and other browsers, do not use quotes around the boundary:
|
||||
return http.parse_multipart_form(request.data, boundary)
|
||||
}
|
||||
return http.parse_form(request.data), map[string][]http.FileData{}
|
||||
}
|
||||
|
@@ -238,6 +238,19 @@ fn test_http_client_multipart_form_data() {
|
||||
assert x.body == files[0].data
|
||||
}
|
||||
|
||||
fn test_login_with_multipart_form_data_send_by_fetch() {
|
||||
mut form_config := http.PostMultipartFormConfig{
|
||||
form: {
|
||||
'username': 'myusername'
|
||||
'password': 'mypassword123'
|
||||
}
|
||||
}
|
||||
x := http.post_multipart_form('http://${localserver}/login', form_config)!
|
||||
assert x.status_code == 200
|
||||
assert x.status_msg == 'OK'
|
||||
assert x.body == 'username: xmyusernamex | password: xmypassword123x'
|
||||
}
|
||||
|
||||
fn test_host() {
|
||||
mut req := http.Request{
|
||||
url: 'http://${localserver}/with_host'
|
||||
|
@@ -89,6 +89,11 @@ pub fn (mut app App) json_echo() vweb.Result {
|
||||
return app.ok(app.req.data)
|
||||
}
|
||||
|
||||
['/login'; post]
|
||||
pub fn (mut app App) login_form(username string, password string) vweb.Result {
|
||||
return app.html('username: x${username}x | password: x${password}x')
|
||||
}
|
||||
|
||||
['/form_echo'; post]
|
||||
pub fn (mut app App) form_echo() vweb.Result {
|
||||
app.set_content_type(app.req.header.get(.content_type) or { '' })
|
||||
|
Reference in New Issue
Block a user