FU: Some fixes and consistency in fu->json and fu->formdata

This commit is contained in:
Yorhel 2025-03-16 18:26:57 +01:00
parent 3382deba9a
commit 65cf842500

35
FU.pm
View file

@ -393,13 +393,13 @@ sub _do_req($c) {
} }
my $proc_ms = ($REQ->{trace_end} - $REQ->{trace_start}) * 1000; 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} ? $REQ->{trace_nsql} ?
sprintf ' (sql %.0f+%.0fms, %d/%d/%d)', sprintf ' (sql %.0f+%.0fms, %d/%d/%d)',
($REQ->{trace_sqlexec}||0)*1000, ($REQ->{trace_sqlprep}||0)*1000, ($REQ->{trace_sqlexec}||0)*1000, ($REQ->{trace_sqlprep}||0)*1000,
$REQ->{trace_nsqldirect}||0, $REQ->{trace_nsqlprep}||0, $REQ->{trace_nsql} : '', $REQ->{trace_nsqldirect}||0, $REQ->{trace_nsqlprep}||0, $REQ->{trace_nsql} : '',
$REQ->{status}, ($REQ->{reshdr}{'content-type'}//'-') =~ s/;.+$//r, $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); ) if FU::debug || $proc_ms > (FU::log_slow_reqs||1e10);
} }
@ -657,8 +657,10 @@ sub query {
sub json { sub json {
shift; 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::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: $@"); } || fu->error(400, "JSON parse error: $@");
return $FU::REQ->{json} if !@_; return $FU::REQ->{json} if !@_;
_getfield $FU::REQ->{json}, @_; _getfield $FU::REQ->{json}, @_;
@ -666,10 +668,10 @@ sub json {
sub formdata { sub formdata {
shift; 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 { $FU::REQ->{formdata} ||= eval {
confess "Invalid content type for form data" FU::Util::query_decode($FU::REQ->{body});
if (fu->header('content-type')||'') ne 'application/x-www-form-urlencoded';
FU::Util::query_decode($FU::REQ->{data});
} || fu->error(400, $@); } || fu->error(400, $@);
_getfield $FU::REQ->{formdata}, @_; _getfield $FU::REQ->{formdata}, @_;
} }
@ -1235,9 +1237,9 @@ C<https://example.com/some/path?query> this returns C<query>.
=item fu->query($name) =item fu->query($name)
Parses the raw query string with C<query_decode> in L<FU::Util> and returns the Parses the raw query string with C<query_decode> in L<FU::Util> and returns the
value with the given $name. Beware: multiple values are returned as an array. value with the given $name. Beware: an array is returned if the given key is
Prefer to use the C<$schema>-based validation methods below to reliably handle repeated in the query string. Prefer to use the C<$schema>-based validation
all sorts of query strings. methods below to reliably handle all sorts of query strings.
=item fu->query($name => $schema) =item fu->query($name => $schema)
@ -1260,12 +1262,19 @@ Parse, validate and return multiple query parameters.
# Or, more concisely: # Or, more concisely:
my $data = fu->query(a => {anybool => 1}, b => {}); my $data = fu->query(a => {anybool => 1}, b => {});
=item fu->json(@args) To fetch all query paramaters as decoded by C<query_decode()>, use:
Like C<< fu->query() >> but parses the request body as JSON. Returns the my $data = fu->query({type=>'any'});
decoded JSON value if C<@args> is empty.
=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 Like C<< fu->query() >> but returns data from the POST request body. This
method only supports form data encoded as C<application/x-www-form-urlencoded>, method only supports form data encoded as C<application/x-www-form-urlencoded>,