From 65cf842500ff05c3610b5a40835fbe58acaaed8a Mon Sep 17 00:00:00 2001 From: Yorhel Date: Sun, 16 Mar 2025 18:26:57 +0100 Subject: [PATCH] FU: Some fixes and consistency in fu->json and fu->formdata --- FU.pm | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/FU.pm b/FU.pm index d6b9268..d5978e2 100644 --- a/FU.pm +++ b/FU.pm @@ -393,13 +393,13 @@ sub _do_req($c) { } my $proc_ms = ($REQ->{trace_end} - $REQ->{trace_start}) * 1000; - log_write(sprintf "%.0fms%s %s-%s %s-%d\n", $proc_ms, + log_write(sprintf "%.0fms%s %s-%s %d-%s\n", $proc_ms, $REQ->{trace_nsql} ? sprintf ' (sql %.0f+%.0fms, %d/%d/%d)', ($REQ->{trace_sqlexec}||0)*1000, ($REQ->{trace_sqlprep}||0)*1000, $REQ->{trace_nsqldirect}||0, $REQ->{trace_nsqlprep}||0, $REQ->{trace_nsql} : '', $REQ->{status}, ($REQ->{reshdr}{'content-type'}//'-') =~ s/;.+$//r, - $REQ->{reshdr}{'content-encoding'}//'bytes', length($REQ->{resbody}), + length($REQ->{resbody}), substr($REQ->{reshdr}{'content-encoding'}//'bytes', 0, 1) ) if FU::debug || $proc_ms > (FU::log_slow_reqs||1e10); } @@ -657,8 +657,10 @@ sub query { sub json { shift; + fu->error(400, "Invalid content type for json") if (fu->header('content-type')||'') ne 'application/json'; + return FU::Util::utf8_decode(my $x = $FU::REQ->{body}) if !@_; $FU::REQ->{json} ||= eval { - FU::Util::json_parse($FU::REQ->{data}, utf8 => 1) + FU::Util::json_parse($FU::REQ->{body}, utf8 => 1) } || fu->error(400, "JSON parse error: $@"); return $FU::REQ->{json} if !@_; _getfield $FU::REQ->{json}, @_; @@ -666,10 +668,10 @@ sub json { sub formdata { shift; + fu->error(400, "Invalid content type for form data") if (fu->header('content-type')||'') ne 'application/x-www-form-urlencoded'; + return FU::Util::utf8_decode(my $x = $FU::REQ->{body}) if !@_; $FU::REQ->{formdata} ||= eval { - confess "Invalid content type for form data" - if (fu->header('content-type')||'') ne 'application/x-www-form-urlencoded'; - FU::Util::query_decode($FU::REQ->{data}); + FU::Util::query_decode($FU::REQ->{body}); } || fu->error(400, $@); _getfield $FU::REQ->{formdata}, @_; } @@ -1235,9 +1237,9 @@ C this returns C. =item fu->query($name) Parses the raw query string with C in L and returns the -value with the given $name. Beware: multiple values are returned as an array. -Prefer to use the C<$schema>-based validation methods below to reliably handle -all sorts of query strings. +value with the given $name. Beware: an array is returned if the given key is +repeated in the query string. Prefer to use the C<$schema>-based validation +methods below to reliably handle all sorts of query strings. =item fu->query($name => $schema) @@ -1260,12 +1262,19 @@ Parse, validate and return multiple query parameters. # Or, more concisely: my $data = fu->query(a => {anybool => 1}, b => {}); -=item fu->json(@args) +To fetch all query paramaters as decoded by C, use: -Like C<< fu->query() >> but parses the request body as JSON. Returns the -decoded JSON value if C<@args> is empty. + my $data = fu->query({type=>'any'}); -=item fu->formdata(@args) +=item fu->json(...) + +Like C<< fu->query() >> but parses the request body as JSON. Returns the raw +(unvalidated!) JSON Unicode string if no arguments are given. To retrieve the +decoded JSON data without performing further validation, use: + + my $data = fu->json({type=>'any'}); + +=item fu->formdata(...) Like C<< fu->query() >> but returns data from the POST request body. This method only supports form data encoded as C,