/
Response.pm
126 lines (106 loc) · 3.27 KB
/
Response.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# JSON-RPC for Foswiki
#
# Copyright (C) 2011-2015 Michael Daum http://michaeldaumconsulting.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version. For
# more details read LICENSE in the root of this distribution.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# As per the GPL, removal of this notice is prohibited.
package Foswiki::Contrib::JsonRpcContrib::Response;
use v5.14;
use Assert;
use Compress::Zlib ();
use JSON ();
use Foswiki::Class qw(app);
extends qw(Foswiki::Object);
use constant TRACE => 0; # toggle me
has id => ( is => 'rw', );
has message => ( is => 'rw', );
has code => (
is => 'rw',
lazy => 1,
default => 0,
isa => sub {
Foswiki::Exception::Fatal->throw(
text => __PACKAGE__ . "::code object attribute cannot be undef" )
unless defined $_[0];
},
);
has json => (
is => 'ro',
lazy => 1,
default => sub {
my $json = JSON->new;
$json->pretty(DEBUG);
$json->convert_blessed(1);
return $json;
},
);
##############################################################################
# static constructor
sub print {
my $class = shift;
my $app = shift;
my $this = $app->create( $class, @_ );
my $response = $this->app->response;
my $text = $this->encode;
my $hopts = {
'status' => $this->code ? 500 : 200,
'Content-Type' => 'application/json',
};
# SMELL: code duplication with core ($Foswiki::UNICODE only)
my $encoding = $app->env->{'HTTP_ACCEPT_ENCODING'} || 'gzip';
$encoding =~ s/^.*(x-gzip|gzip).*/$1/g;
my $compressed = 0;
if ( $Foswiki::cfg{HttpCompress} || $app->env->{'HTTP2'} ) {
$hopts->{'Content-Encoding'} = $encoding;
$hopts->{'Vary'} = 'Accept-Encoding';
$text = Encode::encode_utf8($text);
$text = Compress::Zlib::memGzip($text);
$compressed = 1;
}
$response->setDefaultHeaders($hopts);
if ($compressed) {
$response->body($text);
}
else {
$response->print($text);
}
}
################################################################################
sub isError {
my $this = shift;
return ( $this->code == 0 ) ? 0 : 1;
}
################################################################################
sub encode {
my $this = shift;
my $code = $this->code;
my $message = $this->message;
if ( $this->isError ) {
$message = {
jsonrpc => "2.0",
error => {
code => $code + 0, # Sometimes code comes as a string, not int.
message => $message,
},
};
}
else {
$message = {
jsonrpc => "2.0",
result => $message,
};
}
my $id = $this->id;
$message->{id} = $id if defined $id;
return $this->json->encode($message);
}
1;