1 | module vweb |
2 | |
3 | import net.urllib |
4 | import net.http |
5 | |
6 | // Parsing function attributes for methods and path. |
7 | fn parse_attrs(name string, attrs []string) !([]http.Method, string, string, string) { |
8 | if attrs.len == 0 { |
9 | return [http.Method.get], '/${name}', '', '' |
10 | } |
11 | |
12 | mut x := attrs.clone() |
13 | mut methods := []http.Method{} |
14 | mut middleware := '' |
15 | mut path := '' |
16 | mut host := '' |
17 | |
18 | for i := 0; i < x.len; { |
19 | attr := x[i] |
20 | attru := attr.to_upper() |
21 | m := http.method_from_str(attru) |
22 | if attru == 'GET' || m != .get { |
23 | methods << m |
24 | x.delete(i) |
25 | continue |
26 | } |
27 | if attr.starts_with('/') { |
28 | if path != '' { |
29 | return http.MultiplePathAttributesError{} |
30 | } |
31 | path = attr |
32 | x.delete(i) |
33 | continue |
34 | } |
35 | if attr.starts_with('middleware:') { |
36 | middleware = attr.all_after('middleware:').trim_space() |
37 | x.delete(i) |
38 | continue |
39 | } |
40 | if attr.starts_with('host:') { |
41 | host = attr.all_after('host:').trim_space() |
42 | x.delete(i) |
43 | continue |
44 | } |
45 | i++ |
46 | } |
47 | if x.len > 0 { |
48 | return http.UnexpectedExtraAttributeError{ |
49 | attributes: x |
50 | } |
51 | } |
52 | if methods.len == 0 { |
53 | methods = [http.Method.get] |
54 | } |
55 | if path == '' { |
56 | path = '/${name}' |
57 | } |
58 | // Make host lowercase for case-insensitive comparisons |
59 | return methods, path, middleware, host.to_lower() |
60 | } |
61 | |
62 | fn parse_query_from_url(url urllib.URL) map[string]string { |
63 | mut query := map[string]string{} |
64 | for qvalue in url.query().data { |
65 | query[qvalue.key] = qvalue.value |
66 | } |
67 | return query |
68 | } |
69 | |
70 | const boundary_start = 'boundary=' |
71 | |
72 | fn parse_form_from_request(request http.Request) !(map[string]string, map[string][]http.FileData) { |
73 | if request.method !in [http.Method.post, .put, .patch] { |
74 | return map[string]string{}, map[string][]http.FileData{} |
75 | } |
76 | ct := request.header.get(.content_type) or { '' }.split(';').map(it.trim_left(' \t')) |
77 | if 'multipart/form-data' in ct { |
78 | boundaries := ct.filter(it.starts_with(vweb.boundary_start)) |
79 | if boundaries.len != 1 { |
80 | return error('detected more that one form-data boundary') |
81 | } |
82 | boundary := boundaries[0].all_after(vweb.boundary_start) |
83 | if boundary.len > 0 && boundary[0] == `"` { |
84 | // quotes are send by our http.post_multipart_form/2: |
85 | return http.parse_multipart_form(request.data, boundary.trim('"')) |
86 | } |
87 | // Firefox and other browsers, do not use quotes around the boundary: |
88 | return http.parse_multipart_form(request.data, boundary) |
89 | } |
90 | return http.parse_form(request.data), map[string][]http.FileData{} |
91 | } |