← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:15 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Contrib/JsonRpcContrib/Request.pm
StatementsExecuted 19 statements in 1.07ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11115µs28µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@19Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@19
11111µs15µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@20Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@20
11110µs52µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@28Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@28
1118µs103µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@25Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@25
1114µs4µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@24Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@24
1114µs4µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@26Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@26
1114µs4µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@22Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@22
1114µs4µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@23Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@23
1113µs3µsFoswiki::Contrib::JsonRpcContrib::Request::::BEGIN@27Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@27
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::idFoswiki::Contrib::JsonRpcContrib::Request::id
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::initFromStringFoswiki::Contrib::JsonRpcContrib::Request::initFromString
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::jsonFoswiki::Contrib::JsonRpcContrib::Request::json
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::methodFoswiki::Contrib::JsonRpcContrib::Request::method
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::namespaceFoswiki::Contrib::JsonRpcContrib::Request::namespace
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::newFoswiki::Contrib::JsonRpcContrib::Request::new
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::paramFoswiki::Contrib::JsonRpcContrib::Request::param
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::paramsFoswiki::Contrib::JsonRpcContrib::Request::params
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::toSiteCharSetFoswiki::Contrib::JsonRpcContrib::Request::toSiteCharSet
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::versionFoswiki::Contrib::JsonRpcContrib::Request::version
0000s0sFoswiki::Contrib::JsonRpcContrib::Request::::writeDebugFoswiki::Contrib::JsonRpcContrib::Request::writeDebug
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# JSON-RPC for Foswiki
2#
3# Copyright (C) 2011-2015 Michael Daum http://michaeldaumconsulting.com
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version. For
9# more details read LICENSE in the root of this distribution.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14#
15# As per the GPL, removal of this notice is prohibited.
16
17package Foswiki::Contrib::JsonRpcContrib::Request;
18
19227µs240µs
# spent 28µs (15+12) within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@19 which was called: # once (15µs+12µs) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 19
use strict;
# spent 28µs making 1 call to Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@19 # spent 12µs making 1 call to strict::import
20224µs219µs
# spent 15µs (11+4) within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@20 which was called: # once (11µs+4µs) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 20
use warnings;
# spent 15µs making 1 call to Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@20 # spent 4µs making 1 call to warnings::import
21
22219µs14µs
# spent 4µs within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@22 which was called: # once (4µs+0s) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 22
use JSON ();
23227µs14µs
# spent 4µs within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@23 which was called: # once (4µs+0s) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 23
use Encode ();
24223µs14µs
# spent 4µs within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@24 which was called: # once (4µs+0s) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 24
use Foswiki::Contrib::JsonRpcContrib::Error ();
25227µs2197µs
# spent 103µs (8+94) within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@25 which was called: # once (8µs+94µs) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 25
use Error qw( :try );
# spent 103µs making 1 call to Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@25 # spent 94µs making 1 call to Error::import
26221µs14µs
# spent 4µs within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@26 which was called: # once (4µs+0s) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 26
use Foswiki::Func ();
27222µs13µs
# spent 3µs within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@27 which was called: # once (3µs+0s) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 27
use Foswiki::Plugins ();
282879µs294µs
# spent 52µs (10+42) within Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@28 which was called: # once (10µs+42µs) by Foswiki::Contrib::JsonRpcContrib::Server::BEGIN@25 at line 28
use constant TRACE => 0; # toggle me
# spent 52µs making 1 call to Foswiki::Contrib::JsonRpcContrib::Request::BEGIN@28 # spent 42µs making 1 call to constant::import
29
30###############################################################################
31sub new {
32 my ( $class, $session ) = @_;
33
34 my $request = $session->{request};
35
36 my $this = bless( {}, $class );
37
38 # get json-rpc request object
39 my $data = $request->param('POSTDATA');
40 if ($data) {
41 $data = toSiteCharSet($data);
42 }
43 else {
44
45 # minimal setup
46 $data = '{"jsonrpc":"2.0"}';
47 }
48 writeDebug("data=$data") if TRACE;
49 $this->initFromString($data);
50
51 # get namespace from path info, maybe separate a REST-like method as well
52 my $namespace = $request->pathInfo();
53 my $method;
54 if ( $namespace =~ /^\/?([^\/]+)(?:\/(.*))?$/ ) {
55 $namespace = $1;
56 $method = $2;
57 }
58 $this->namespace($namespace);
59 writeDebug("namespace=$namespace") if TRACE;
60
61 # override json-rpc params using url params
62 foreach my $key ( $request->multi_param() ) {
63 next if $key =~ /^(POSTDATA|method|id|jsonrpc)$/; # these are different
64 my @vals = map( toSiteCharSet($_), $request->multi_param($key) );
65 if ( scalar(@vals) == 1 ) {
66 $this->param( $key => $vals[0] )
67 ; # set json-rpc params using url params
68 }
69 else {
70 $this->param( $key => \@vals )
71 ; # set json-rpc params using url params
72 }
73 }
74
75 # copy id from url params to json-rpc request if required
76 my $id = $request->param('id') || $this->id();
77 $this->id($id) if defined $id;
78
79 # copy method to json-rpc request
80 $method = $request->param('method') if defined $request->param("method");
81 $this->method($method) if defined $method;
82
83 # check that this is a http POST
84 my $httpMethod = $request->method() || "jsonrpc";
85
86 throw Foswiki::Contrib::JsonRpcContrib::Error( -32600,
87 "Method must be POST" )
88 unless $httpMethod =~ /post|jsonrpc/i;
89
90 # some basic checks if this is a proper json-rpc 2.0 request
91
92 # must have a version tag
93 if ( ( $this->version() || '' ) ne "2.0" ) {
94 throw Foswiki::Contrib::JsonRpcContrib::Error( -32600,
95 "Invalid JSON-RPC request - must be jsonrpc: '2.0'" );
96 }
97
98 # must have a method
99 throw Foswiki::Contrib::JsonRpcContrib::Error( -32600,
100 "Invalid JSON-RPC request - no method" )
101 unless defined $this->method();
102
103 writeDebug( "method=" . $this->method() ) if TRACE;
104
105 # must not have any other keys other than these
106 foreach my $key ( keys %{ $this->{data} } ) {
107 throw Foswiki::Contrib::JsonRpcContrib::Error( -32600,
108 "Invalid JSON-RPC request - unknown key $key" )
109 unless $key =~ /^(jsonrpc|method|params|id)$/;
110 }
111
112 return $this;
113}
114
115##############################################################################
116sub initFromString {
117 my ( $this, $data ) = @_;
118
119 # parse json-rpc request
120 eval { $this->{data} = $this->json->decode($data); };
121
122 if ($@) {
123 my $error = $@;
124 $error =~ s/,? +at.*$//s;
125 throw Foswiki::Contrib::JsonRpcContrib::Error( -32700,
126 "Parse error - invalid json-rpc request: $error" );
127 }
128
129 $this->{data}{params} ||= {};
130
131 return $this->{data};
132}
133
134##############################################################################
135sub version {
136 my ( $this, $value ) = @_;
137
138 $this->{data}{jsonrpc} = $value if defined $value;
139 return $this->{data}{jsonrpc};
140}
141
142##############################################################################
143sub id {
144 my ( $this, $value ) = @_;
145
146 $this->{data}{id} = $value if defined $value;
147 return $this->{data}{id};
148}
149
150##############################################################################
151sub param {
152 my ( $this, $key, $value ) = @_;
153
154 return unless $key;
155
156 $this->{data}{params}{$key} = $value if defined $value;
157 return $this->{data}{params}{$key};
158}
159
160##############################################################################
161sub params {
162 return $_[0]->{data}{params};
163}
164
165##############################################################################
166sub method {
167 my ( $this, $value ) = @_;
168
169 $this->{data}{method} = $value if defined $value;
170 return $this->{data}{method};
171}
172
173##############################################################################
174sub namespace {
175 my ( $this, $value ) = @_;
176
177 $this->{namespace} = $value if defined $value;
178 return $this->{namespace};
179}
180
181##############################################################################
182sub json {
183 my $this = shift;
184
185 unless ( defined $this->{json} ) {
186 $this->{json} = new JSON;
187 }
188
189 return $this->{json};
190}
191
192################################################################################
193# static
194sub writeDebug {
195 Foswiki::Func::writeDebug("- JsonRpcContrib::Request - $_[0]");
196}
197
198###############################################################################
199sub toSiteCharSet {
200 my $string = shift;
201
202 return $string unless $string;
203
204 # Convert to unicode if the core supports it
205 return $string if $Foswiki::UNICODE;
206
207 return $string
208 if ( $Foswiki::cfg{Site}{CharSet} =~ /^utf-?8/i );
209
210 # If the site charset is not utf-8, need to convert it
211 return Encode::encode(
212 $Foswiki::cfg{Site}{CharSet},
213 Encode::decode_utf8($string),
214 Encode::FB_PERLQQ
215 );
216}
217
21812µs1;