File Coverage

blib/lib/Xpriori/XMS/Http.pm
Criterion Covered Total %
statement 36 233 15.4
branch 0 54 0.0
condition 0 15 0.0
subroutine 12 59 20.3
pod 32 38 84.2
total 80 399 20.0


line stmt bran cond sub pod time code
1             package Xpriori::XMS::Http;
2 1     1   20043 use utf8;
  1         9  
  1         7  
3 1     1   33 use strict;
  1         2  
  1         35  
4 1     1   5 use warnings;
  1         6  
  1         31  
5             #require Exporter;
6             #our @ISA = qw(Exporter);
7              
8 1     1   924 use LWP;
  1         59542  
  1         34  
9 1     1   11 use HTTP::Request;
  1         2  
  1         22  
10 1     1   5 use URI::Escape;
  1         1  
  1         82  
11 1     1   5 use Digest::MD5 qw(md5_hex); # Needed to encrypt login
  1         1  
  1         55  
12 1     1   744 use Xpriori::XMS::Config;
  1         5  
  1         63  
13              
14             our $VERSION = '0.03';
15              
16 1     1   6 use constant CstCRLF => "\x0d\x0a";
  1         2  
  1         68  
17 1     1   5 use constant CstGETLIMIT => 256; #1024;
  1         2  
  1         41  
18 1     1   4 use constant CstNeoAdmin => 'neoadmin';
  1         2  
  1         41  
19 1     1   5 use constant CstNeoQuery => 'neoquery';
  1         1  
  1         3741  
20             #---------------------------------------------------------------------
21             # new: constructor
22             #---------------------------------------------------------------------
23             sub new($$$;%)
24             {
25 0     0 1   my $sClass = shift(@_);
26 0           my $sUrl = shift(@_);
27 0           my ($sUsr, $sPasswd, $iConn);
28 0 0         if(ref($_[0]) eq 'HASH')
29             {
30 0           my $rhConn = shift(@_);
31 0           $iConn = $rhConn->{sid};
32             }
33             else
34             {
35 0           $sUsr = shift(@_);
36 0           $sPasswd = shift(@_);
37             }
38 0           my %hPrmW = @_;
39              
40 0           my %hConf = %Xpriori::XMS::Config::_cnf;
41 0           while(my($sKey, $sVal) = each(%hPrmW))
42             {
43 0           $hConf{$sKey} = $sVal;
44             }
45 0           my $oSelf = \%hConf;
46 0           bless $oSelf, $sClass;
47 0   0       $sUrl ||= $Xpriori::XMS::Config::_connect{METHOD} . '://' .
48             $Xpriori::XMS::Config::_connect{SERVER} . ':' .
49             $Xpriori::XMS::Config::_connect{PORT};
50              
51 0           $oSelf->{fullUrl} = $sUrl;
52 0           $oSelf->{_lwpUa} = LWP::UserAgent->new();
53              
54 0 0         if($iConn)
55             {
56 0           $oSelf->{_sid} = $iConn;
57             }
58             else
59             {
60 0           my $sRes = $oSelf->_sendQueryPost(CstNeoAdmin,
61             ('cmd' => 'GETSESSION',
62             'user' => $sUsr,
63             'passwd' => md5_hex($sPasswd))
64             );
65             #get SID from 2nd-line
66 0           my (undef, $xmlContent) = split("\n", $sRes, 2);
67 0 0         if ($xmlContent =~ m|^\s*<.+>(.+)\s*$| )
68             {
69 0           $oSelf->{_sid} = $1;
70             }
71             else
72             {
73 0           die($sRes);
74             }
75             }
76 0           return $oSelf;
77             }
78             #---------------------------------------------------------------------
79             # getSID method
80             #---------------------------------------------------------------------
81             sub getSID
82             {
83 0     0 1   my($oSelf) = @_;
84 0           return $oSelf->{_sid};
85             }
86             #---------------------------------------------------------------------
87             # setMethod method
88             #---------------------------------------------------------------------
89             sub setMethod
90             {
91 0     0 0   my($oSelf, $sMethod) = @_;
92 0           $oSelf->{METHOD} = $sMethod;
93             }
94             #---------------------------------------------------------------------
95             # setServer method
96             #---------------------------------------------------------------------
97             sub setServer
98             {
99 0     0 0   my($oSelf, $sSvr) = @_;
100 0           $oSelf->{SERVER} = $sSvr;
101             }
102             #---------------------------------------------------------------------
103             # setPort method
104             #---------------------------------------------------------------------
105             sub setPort
106             {
107 0     0 0   my($oSelf, $iPort) = @_;
108 0           $oSelf->{PORT} = $iPort;
109             }
110             #---------------------------------------------------------------------
111             # setCharset method
112             #---------------------------------------------------------------------
113             sub setCharset
114             {
115 0     0 1   my($oSelf, $sChar) = @_;
116 0           $oSelf->{CHARSET} = $sChar;
117             }
118             #---------------------------------------------------------------------
119             # setLanguage method
120             #---------------------------------------------------------------------
121             sub setLanguage
122             {
123 0     0 1   my($oSelf, $sLng) = @_;
124 0           $oSelf->{LANGUAGE} = $sLng;
125             }
126             #---------------------------------------------------------------------
127             # getMethod method
128             #---------------------------------------------------------------------
129             sub getMethod
130             {
131 0     0 0   my($oSelf) = @_;
132 0           return $oSelf->{METHOD};
133             }
134             #---------------------------------------------------------------------
135             # getServer method
136             #---------------------------------------------------------------------
137             sub getServer
138             {
139 0     0 0   my($oSelf) = @_;
140 0           return $oSelf->{SERVER};
141             }
142             #---------------------------------------------------------------------
143             # getPort method
144             #---------------------------------------------------------------------
145             sub getPort
146             {
147 0     0 0   my($oSelf) = @_;
148 0           return $oSelf->{PORT};
149             }
150             #---------------------------------------------------------------------
151             # getCharset method
152             #---------------------------------------------------------------------
153             sub getCharset
154             {
155 0     0 1   my($oSelf) = @_;
156 0           return $oSelf->{CHARSET};
157             }
158             #---------------------------------------------------------------------
159             # getLanguage method
160             #---------------------------------------------------------------------
161             sub getLanguage
162             {
163 0     0 1   my($oSelf) = @_;
164 0           return $oSelf->{LANGUAGE};
165             }
166             #---------------------------------------------------------------------
167             # _buildParam : for request
168             #---------------------------------------------------------------------
169             sub _buildParam($%)
170             {
171 0     0     my($oSelf, %hParam) = @_;
172 0           my $sPrm = '';
173 0 0         if(%hParam)
174             {
175 0           while(my($sKey, $sVal) = each(%hParam))
176             {
177 0 0         $sPrm .= '&' if($sPrm ne '');
178             #$sVal = ($sVal)? URI::Escape::uri_escape($sVal) : '';
179 0 0         $sVal = ($sVal)? URI::Escape::uri_escape_utf8($sVal) : '';
180 0           $sPrm .= "$sKey=$sVal";
181             }
182             }
183 0           return $sPrm;
184             }
185             #---------------------------------------------------------------------
186             # _setHeader : for Request
187             #---------------------------------------------------------------------
188             sub _setHeader($$)
189             {
190 0     0     my($oSelf, $oReq) = @_;
191 0           $oReq->header('Accept-Charset', $oSelf->{CHARSET});
192 0           $oReq->header('Accept-Language', $oSelf->{LANGUAGE});
193 0 0         $oReq->header('sid' => $oSelf->{_sid}) if(defined($oSelf->{_sid}));
194             }
195             #---------------------------------------------------------------------
196             # READ File and replace \n -> CRLF
197             #---------------------------------------------------------------------
198             sub _readFileCRLF
199             {
200 0     0     my ($sFile) = @_;
201             #If exists get contents
202             {
203 0           local(*XMLFILE, $/);
  0            
204 0 0         open(XMLFILE, '<', $sFile) or
205             die( "Can't open $sFile: $!");
206 0           my $sXml = ;
207 0           close XMLFILE;
208 0           my $sCRLF = CstCRLF;
209 0           $sXml =~ s/\n+/$sCRLF/sg;
210 0           return $sXml;
211             }
212             }
213             #---------------------------------------------------------------------
214             # sendQueryGet : send query with GET
215             #---------------------------------------------------------------------
216             sub _sendQueryGet($$;@)
217             {
218 0     0     my($oSelf, $sPath, %hParam) = @_;
219 0           my $sxPath = $oSelf->{fullUrl} . "/$sPath";
220 0           my $sPrm = $oSelf->_buildParam(%hParam);
221 0 0         $sxPath .= '?' . $sPrm if($sPrm);
222              
223 0           my $oReq = new HTTP::Request('GET', $sxPath);
224 0           $oReq->header('Content-Type', q{text/xml; charset='} . $oSelf->{CHARSET} . q{'});
225 0           $oSelf->_setHeader($oReq);
226 0           my $response = $oSelf->{_lwpUa}->request($oReq);
227 0 0         if ($response->is_success)
228             {
229 0           return scalar($response->content());
230             }
231             else
232             {
233 0           return $response->as_string;
234             }
235             }
236             #---------------------------------------------------------------------
237             # sendQueryPost : send query with POST
238             #---------------------------------------------------------------------
239             sub _sendQueryPost($$;@)
240             {
241 0     0     my($oSelf, $sPath, %hParam) = @_;
242 0           my $sURL = $oSelf->{fullUrl} . "/$sPath";
243 0           my $sPrm = $oSelf->_buildParam(%hParam);
244              
245 0           my $oReq = new HTTP::Request('POST', $sURL);
246 0           $oReq->header('Content-Type', q{text/xml; charset='} . $oSelf->{CHARSET} . q{'});
247 0           $oSelf->_setHeader($oReq);
248 0           $oReq->add_content($sPrm . CstCRLF);
249              
250 0           my $response = $oSelf->{_lwpUa}->request($oReq);
251 0 0         if ($response->is_success)
252             {
253 0           return $response->content;
254             }
255             else
256             {
257 0           return $response->as_string;
258             }
259             }
260             #---------------------------------------------------------------------
261             # make request that has Multipart
262             #---------------------------------------------------------------------
263             sub _mkReqMultipart($$@)
264             {
265 0     0     my ($oSelf, $request, @aPrm) = @_;
266              
267             # Create POST method boundary
268 0           my $boundaryHeader = ('-' x 27) . sprintf("%lx", time());
269 0           my $boundary = '--' . $boundaryHeader;
270 0           $request->header('Content-Type', 'multipart/form-data; '.
271             'charset=' . $oSelf->{CHARSET} . '; ' .
272             'boundary=' . $boundaryHeader);
273 0 0         if(@aPrm)
274             {
275 0           my $bInit = 1;
276 0           foreach my $rhPrm (@aPrm)
277             {
278 0 0         if($bInit == 1)
279             {
280 0           $bInit = 0;
281 0           $request->content($boundary . CstCRLF);
282             }
283             else
284             {
285 0           $request->add_content(CstCRLF . $boundary . CstCRLF);
286             }
287 0           $request->add_content(
288             'Content-Disposition: form-data; ' .
289             'name="' . $rhPrm->{name} . '"; '.
290             'filename="' . $rhPrm->{filename} . '"' . CstCRLF);
291 0 0         if($rhPrm->{type})
292             {
293 0           $request->add_content(
294             'Content-Type: ' . $rhPrm->{type} . CstCRLF . CstCRLF);
295             }
296 0           my $sCnt = $rhPrm->{content};
297 0           utf8::encode($sCnt);
298 0           $request->add_content($sCnt);
299             }
300 0           $request->add_content(CstCRLF . $boundary . '--');
301             }
302 0           return $request;
303             }
304             #---------------------------------------------------------------------
305             # _sendQueryPostMultipart :
306             #---------------------------------------------------------------------
307             sub _sendQueryPostMultipart
308             {
309 0     0     my($oSelf, $sPath, $cmd, @aPrm) = @_;
310 0           my $uri= $oSelf->{fullUrl} . '/' . $sPath . '?' . 'cmd=' . $cmd;
311 0           my $request = new HTTP::Request('POST', $uri);
312 0           $oSelf->_setHeader($request);
313 0           $oSelf->_mkReqMultipart($request, @aPrm);
314              
315 0           my $response = $oSelf->{_lwpUa}->request($request);
316 0 0         if ($response->is_success)
317             {
318 0           return $response->content;
319             }
320             else
321             {
322 0           return $response->as_string;
323             }
324             }
325             #---------------------------------------------------------------------
326             # _queryGeneralCmd:
327             #---------------------------------------------------------------------
328             sub _queryGeneralCmd($$;$@)
329             {
330 0     0     my ($oSelf, $sCmd, $sInput, %hOpt) = @_;
331 0           my %hPrm = ();
332 0 0         %hPrm = %hOpt if(%hOpt);
333 0           $hPrm{'cmd'} = $sCmd;
334 0 0         $hPrm{'input'} = $sInput if(defined($sInput));
335 0           return $oSelf->_sendQueryGet(CstNeoQuery, %hPrm);
336             }
337             #---------------------------------------------------------------------
338             # logout
339             #---------------------------------------------------------------------
340             sub logout
341             {
342 0     0 1   my($oSelf) = @_;
343 0           return $oSelf->_sendQueryGet(CstNeoAdmin, 'cmd' => 'ENDSESSION');
344             }
345             #---------------------------------------------------------------------
346             # setTraceLevels method
347             #---------------------------------------------------------------------
348             sub setTraceLevels
349             {
350 0     0 1   my($oSelf, $sLvl) = @_;
351 0           return $oSelf->_sendQueryGet(CstNeoAdmin,
352             'cmd' => 'TRCLVL',
353             'RHTRCLVL' => $sLvl,
354             );
355             }
356             #---------------------------------------------------------------------
357             # getTraceLevels method
358             #---------------------------------------------------------------------
359             sub getTraceLevels
360             {
361 0     0 1   my($oSelf) = @_;
362 0           return $oSelf->_sendQueryGet(CstNeoAdmin,
363             'cmd' => 'GETTRCLVL',
364             );
365             }
366             #---------------------------------------------------------------------
367             # activateAccessControl method
368             #---------------------------------------------------------------------
369             sub activateAccessControl
370             {
371 0     0 1   my($oSelf) = @_;
372 0           return $oSelf->_sendQueryGet(CstNeoAdmin,
373             'cmd' => 'ACTIVATEAC',
374             );
375             }
376             #---------------------------------------------------------------------
377             # setPassword method
378             #---------------------------------------------------------------------
379             sub setPassword
380             {
381 0     0 1   my ($oSelf, $sUser, $sPasswd) = @_;
382 0           return $oSelf->_sendQueryPost(CstNeoAdmin,
383             'cmd' => 'SETPASSWD',
384             'user' => $sUser,
385             'passwd' => md5_hex($sPasswd)
386             );
387             }
388             #---------------------------------------------------------------------
389             # setIsolationLevel method
390             #
391             # IsolationLevel can be READ_COMMITTED, READ_UNCOMMITTED,
392             # REPEATABLE_READ (SERIALIZABLE is no longer supported)
393             #---------------------------------------------------------------------
394             sub setIsolationLevel
395             {
396 0     0 1   my($oSelf, $iIsoLvl) = @_;
397 0           return $oSelf->_queryGeneralCmd('TRANSACTION_ISOLATION', $iIsoLvl);
398             }
399             #---------------------------------------------------------------------
400             # startTransaction method
401             # no parameter version of this method
402             #---------------------------------------------------------------------
403             sub startTransaction
404             {
405 0     0 1   my ($oSelf, @aPrm) = @_;
406 0 0         if ( @aPrm == 3)
    0          
407             {
408             #my ($tx_flush, $maxdur, $inactdur) = @aPrm;
409 0           return $oSelf->_queryGeneralCmd('TRANSACTION_START', $aPrm[0],
410             MAXDURATION => $aPrm[1],
411             INACTIVITYDURATION => $aPrm[2]);
412             }
413             elsif ( @aPrm == 1)
414             {
415 0           return $oSelf->_queryGeneralCmd('TRANSACTION_START', $aPrm[0]);
416             }
417             else
418             {
419 0           return $oSelf->_queryGeneralCmd('TRANSACTION_START');
420             }
421             }
422             #---------------------------------------------------------------------
423             # commitTransaction method
424             #---------------------------------------------------------------------
425             sub commitTransaction
426             {
427 0     0 1   my ($oSelf) = @_;
428 0           return $oSelf->_queryGeneralCmd('TRANSACTION_COMMIT');
429             }
430             #---------------------------------------------------------------------
431             # rollbackTransaction method
432             #---------------------------------------------------------------------
433             sub rollbackTransaction
434             {
435 0     0 1   my ($oSelf) = @_;
436 0           return $oSelf->_queryGeneralCmd('TRANSACTION_ROLLBACK');
437             }
438             #---------------------------------------------------------------------
439             # queryXML method :
440             #---------------------------------------------------------------------
441             sub queryXML
442             {
443 0     0 1   my ($oSelf, $query, $rhOpt) = @_;
444 0 0 0       if ( $rhOpt->{POST} || (length($query) > CstGETLIMIT ))
445             {
446 0           return $oSelf->_sendQueryPostMultipart(CstNeoQuery, 'QUERY',
447             {
448             name => 'input',
449             filename => '',
450             content => $query,
451             }
452             );
453             }
454             else
455             {
456 0           return $oSelf->_queryGeneralCmd('QUERY', $query);
457             }
458             }
459             #---------------------------------------------------------------------
460             # deleteXML
461             #---------------------------------------------------------------------
462             sub deleteXML
463             {
464 0     0 1   my($oSelf, $query) = @_;
465 0           return $oSelf->_queryGeneralCmd('DELETE', $query);
466             }
467             #---------------------------------------------------------------------
468             # insertXML method
469             #---------------------------------------------------------------------
470             sub insertXML_File
471             {
472 0     0 1   my ($oSelf, $query, $fXml, $rhOpt) = @_;
473 0           return $oSelf->insertXML($query,
474             _readFileCRLF($fXml), $rhOpt);
475             }
476             #---------------------------------------------------------------------
477             # insertXML method
478             #---------------------------------------------------------------------
479             sub insertXML
480             {
481 0     0 1   my ($oSelf, $query, $insertString, $rhOpt) = @_;
482 0 0 0       if ($rhOpt->{POST} || (length($query) + length($insertString) > CstGETLIMIT ))
483             {
484 0           return $oSelf->_sendQueryPostMultipart(CstNeoQuery,
485             'INSERT', (
486             {
487             name => 'input',
488             filename => '',
489             content => $query,
490             },
491             {
492             name => 'data',
493             filename => '',
494             content => $insertString,
495             },
496             ));
497             }
498             else
499             {
500 0           return $oSelf->_queryGeneralCmd('INSERT', $query,
501             'data' => $insertString);
502             }
503             }
504             #---------------------------------------------------------------------
505             # modifyXML method
506             #---------------------------------------------------------------------
507             sub modifyXML_File
508             {
509 0     0 1   my ($oSelf, $query, $modXML, $rhOpt) = @_;
510 0           return $oSelf->modifyXML($query,
511             _readFileCRLF($modXML), $rhOpt);
512             }
513             #---------------------------------------------------------------------
514             # modifyXML method
515             #---------------------------------------------------------------------
516             sub modifyXML
517             {
518 0     0 1   my ($oSelf, $query, $modString, $rhOpt) = @_;
519 0 0 0       if ($rhOpt->{POST} || (length($query) + length($modString) > CstGETLIMIT ))
520             {
521 0           return $oSelf->_sendQueryPostMultipart(CstNeoQuery,
522             'MODIFY', (
523             {
524             name => 'input',
525             filename => '',
526             content => $query,
527             },
528             {
529             name => 'data',
530             filename => '',
531             content => $modString,
532             },
533             ));
534             }
535             else
536             {
537 0           return $oSelf->_queryGeneralCmd('MODIFY', $query,
538             'data' => $modString);
539             }
540             }
541             #---------------------------------------------------------------------
542             # copyXML method : ?
543             #---------------------------------------------------------------------
544             sub copyXML
545             {
546 0     0 1   my ($oSelf, $query) = @_;
547 0           return $oSelf->_queryGeneralCmd('COPY', $query);
548             }
549             #---------------------------------------------------------------------
550             # queryFlatXML : ?
551             #---------------------------------------------------------------------
552             sub queryFlatXML
553             {
554 0     0 1   my ($oSelf, $query) = @_;
555 0           return $oSelf->_queryGeneralCmd('FLAT', $query);
556             }
557             #---------------------------------------------------------------------
558             # queryXMLUpdateIntent : ?
559             #---------------------------------------------------------------------
560             sub queryXMLUpdateIntent
561             {
562 0     0 1   my ($oSelf, $query) = @_;
563 0           return $oSelf->_queryGeneralCmd('QUERYUPDATE', $query);
564             }
565             #---------------------------------------------------------------------
566             # queryCountXML : ?
567             #---------------------------------------------------------------------
568             sub queryCountXML
569             {
570 0     0 1   my ($oSelf, $query, $bNotAcid) = @_;
571 0 0         if($bNotAcid)
572             {
573 0           return $oSelf->_queryGeneralCmd('COUNTNOTACID', $query);
574             }
575             else
576             {
577 0           return $oSelf->_queryGeneralCmd('COUNT', $query);
578             }
579             }
580             #---------------------------------------------------------------------
581             # queryTreeXML : get node name
582             #---------------------------------------------------------------------
583             sub queryTreeXML
584             {
585 0     0 1   my($oSelf, $query) = @_;
586 0           return $oSelf->_queryGeneralCmd('TREE', $query);
587             }
588             #---------------------------------------------------------------------
589             # queryDataContextXML method
590             # The search string must be quoted
591             #---------------------------------------------------------------------
592             sub queryDataContextXML
593             {
594 0     0 1   my($oSelf, $query) = @_;
595 0           return $oSelf->_queryGeneralCmd('DATAQUERY', qq{"$query"});
596             }
597             #---------------------------------------------------------------------
598             # getServerStatistics method
599             # query_string parameter :
600             # ''(=ALL), ADMIN, STORAGE, ACCESS, BUFFER, TRANSACTION, WINDOW
601             #---------------------------------------------------------------------
602             sub getServerStatistics
603             {
604 0     0 1   my($oSelf, $sCmd) = @_;
605 0           my $sCmdS = 'GETSTATS';
606 0 0         $sCmdS .= '_' . $sCmd if($sCmd);
607 0           return $oSelf->_queryGeneralCmd($sCmdS);
608             }
609             #---------------------------------------------------------------------
610             # clearServerStatistics method
611             #---------------------------------------------------------------------
612             sub clearServerStatistics
613             {
614 0     0 1   my($oSelf) = @_;
615 0           return $oSelf->_queryGeneralCmd('CLEARSTATS');
616             }
617             #---------------------------------------------------------------------
618             # getServerVersion method
619             #---------------------------------------------------------------------
620             sub getServerVersion
621             {
622 0     0 1   my($oSelf) = @_;
623 0           return $oSelf->_queryGeneralCmd('VERSION');
624             }
625             #---------------------------------------------------------------------
626             # storeXML_File
627             #---------------------------------------------------------------------
628             sub storeXML_File
629             {
630 0     0 1   my ($oSelf, $xml, $schemaURI, $prefix) = @_;
631 0           my $xmlString = _readFileCRLF($xml);
632 0           return $oSelf->storeXML($xmlString, $schemaURI, $prefix);
633             }
634             #---------------------------------------------------------------------
635             # storeXML method
636             # stores an XML string
637             # if only used with one parameter, assumes schemaURI and prefix are null
638             #---------------------------------------------------------------------
639             sub storeXML
640             {
641 0     0 1   my ($oSelf, $xmlString, $schemaURI, $prefix) = @_;
642 0           my @aPrm = ();
643 0 0         push(@aPrm, {
644             name => 'schemafile',
645             filename => '',
646             content => $schemaURI,
647             }) if($schemaURI);
648 0 0         push(@aPrm, {
649             name => 'prefixfile',
650             filename => $prefix,
651             type => 'text/xml',
652             content => $prefix,
653             }) if($prefix);
654 0           push(@aPrm,
655             {
656             name => 'xmlsourcefile',
657             filename => '',
658             type => 'text/xml',
659             content => $xmlString,
660             },
661             );
662 0           return $oSelf->_sendQueryPostMultipart(CstNeoQuery, 'STORE', @aPrm);
663             }
664             sub DESTROY
665             {
666 0     0     my($oSelf) = @_;
667 0           local $@; #Keep previous die-message.
668 0 0 0       $oSelf->logout()
669             if($oSelf->{AUTO_LOGOUT} && $oSelf->{_sid});
670             }
671             1;
672              
673             1;
674             __END__