FU: Add JSON reading & writing methods
This commit is contained in:
parent
17176738a0
commit
70c5199df4
1 changed files with 34 additions and 9 deletions
43
FU.pm
43
FU.pm
|
|
@ -637,7 +637,10 @@ sub headers { $FU::REQ->{hdr} }
|
|||
sub ip { $FU::REQ->{ip} }
|
||||
|
||||
sub _getfield($data, @a) {
|
||||
return $data->{$a[0]} if @a == 1 && !ref $a[0];
|
||||
if (@a == 1 && !ref $a[0]) {
|
||||
fu->error(400, "Expected top-level to be a hash") if ref $data ne 'HASH';
|
||||
return $data->{$a[0]};
|
||||
}
|
||||
require FU::Validate;
|
||||
my $schema = FU::Validate->compile(@a > 1 ? { keys => {@a} } : $a[0]);
|
||||
my $res = eval { $schema->validate($data) };
|
||||
|
|
@ -652,6 +655,15 @@ sub query {
|
|||
_getfield $FU::REQ->{qs_parsed}, @_;
|
||||
}
|
||||
|
||||
sub json {
|
||||
shift;
|
||||
$FU::REQ->{json} ||= eval {
|
||||
FU::Util::json_parse($FU::REQ->{data}, utf8 => 1)
|
||||
} || fu->error(400, "JSON parse error: $@");
|
||||
return $FU::REQ->{json} if !@_;
|
||||
_getfield $FU::REQ->{json}, @_;
|
||||
}
|
||||
|
||||
sub formdata {
|
||||
shift;
|
||||
$FU::REQ->{formdata} ||= eval {
|
||||
|
|
@ -715,6 +727,12 @@ sub set_header($, $hdr, $val=undef) {
|
|||
$FU::REQ->{reshdr}{ lc $hdr } = $val;
|
||||
}
|
||||
|
||||
sub send_json($, $data) {
|
||||
fu->set_header('content-type', 'application/json');
|
||||
fu->set_body(FU::Util::json_format($data, canonical => 1, utf8 => 1));
|
||||
fu->done;
|
||||
}
|
||||
|
||||
sub send_file($, $root, $path) {
|
||||
# This also catches files with '..' somewhere in the middle of the name.
|
||||
# Let's just disallow that to simplify this check, I'd err on the side of
|
||||
|
|
@ -1242,9 +1260,12 @@ Parse, validate and return multiple query parameters.
|
|||
# Or, more concisely:
|
||||
my $data = fu->query(a => {anybool => 1}, b => {});
|
||||
|
||||
=item fu->formdata($name)
|
||||
=item fu->json(@args)
|
||||
|
||||
=item fu->formdata($schema)
|
||||
Like C<< fu->query() >> but parses the request body as JSON. Returns the
|
||||
decoded JSON value if C<@args> is empty.
|
||||
|
||||
=item fu->formdata(@args)
|
||||
|
||||
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>,
|
||||
|
|
@ -1253,13 +1274,11 @@ use C<< fu->multipart >> instead.
|
|||
|
||||
=item fu->multipart
|
||||
|
||||
Parse the request body as C<multipart/form-data> and return an array of fields.
|
||||
Refer to L<FU::MultipartFormData> for more information.
|
||||
Parse the request body as C<multipart/form-data> and return an array of field
|
||||
objects. Refer to L<FU::MultipartFormData> for more information.
|
||||
|
||||
=back
|
||||
|
||||
I<TODO:> Support JSON bodies.
|
||||
|
||||
I<TODO:> Cookie parsing.
|
||||
|
||||
|
||||
|
|
@ -1321,6 +1340,14 @@ templating system or L<FU::XMLWriter>:
|
|||
};
|
||||
});
|
||||
|
||||
=item fu->send_json($data)
|
||||
|
||||
Encode C<$data> as JSON (using C<json_format> in L<FU::Util>), set an
|
||||
appropriate C<Content-Type> header and send it to the client. Calls C<<
|
||||
fu->done >>.
|
||||
|
||||
I<TODO:> Support schema-based normalization.
|
||||
|
||||
=item fu->send_file($root, $path)
|
||||
|
||||
If a file identified by C<"$root/$path"> exists, set that as response and call
|
||||
|
|
@ -1374,8 +1401,6 @@ one of the following status codes or an alias:
|
|||
|
||||
I<TODO:> Setting cookies.
|
||||
|
||||
I<TODO:> JSON output.
|
||||
|
||||
|
||||
=head2 Running the Site
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue