POD documentation
This commit is contained in:
parent
621c0b3e68
commit
10cf213ffa
|
@ -210,3 +210,226 @@ sub _run {
|
|||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
=encoding utf8
|
||||
|
||||
Lemonldap::NG::Common::PSGI - Base library for PSGI modules of Lemonldap::NG.
|
||||
Use Lemonldap::NG::Common::PSGI::Router for REST API.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package My::PSGI;
|
||||
|
||||
use base Lemonldap::NG::Common::PSGI;
|
||||
|
||||
sub init {
|
||||
my ($self,$args) = splice @_;
|
||||
# Will be called 1 time during startup
|
||||
|
||||
# Store debug level
|
||||
$self->logLevel('info');
|
||||
# Can use syslog for user actions
|
||||
$self->syslog('daemon');
|
||||
|
||||
# Return a boolean. If false, then error message has to be stored in
|
||||
# $self->error
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub router {
|
||||
my ( $self, $req ) = splice @_;
|
||||
# Do something and return a PSGI response
|
||||
# NB: $req is a Lemonldap::NG::Common::PSGI::Request object
|
||||
|
||||
return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Body lines' ] ];
|
||||
}
|
||||
|
||||
This package could then be called as a CGI, using FastCGI,...
|
||||
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use My::PSGI;
|
||||
use Plack::Handler::FCGI; # or Plack::Handler::CGI
|
||||
|
||||
Plack::Handler::FCGI->new->run( My::PSGI->run() );
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This package provides base class for Lemonldap::NG web interfaces but could be
|
||||
used regardless.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 Running methods
|
||||
|
||||
=head3 run ( $args )
|
||||
|
||||
Main method that will manage requests. It can be called using class or already
|
||||
created object:
|
||||
|
||||
=over
|
||||
|
||||
=item Class->run($args): launch new($args), init(), then manage requests (using
|
||||
private _run() method
|
||||
|
||||
=item $object->run(): manage directly requests. Initialization must have be done
|
||||
earlier.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Logging
|
||||
|
||||
=head3 lmLog ( $msg, $level)
|
||||
|
||||
Print on STDERR messages if level > $self->{logLevel}. Defined log levels are:
|
||||
debug, info, notice, warn, error.
|
||||
|
||||
=head3 userLog ($msg, $level)
|
||||
|
||||
If $self->syslog is configured, store message with it, else called simply lmLog().
|
||||
$self->syslog must be empty or contain syslog facility
|
||||
|
||||
=head3 userError() userNotice() userInfo()
|
||||
|
||||
Alias for userLog(level).
|
||||
|
||||
=head2 Content sending
|
||||
|
||||
Note that $req, the first argument of these functions, is a
|
||||
L<Lemonldap::NG::Common::PSGI::Request>. See the corresponding documentation.
|
||||
|
||||
=head3 sendHtml ( $req, $template )
|
||||
|
||||
This method build HTML response using HTML::Template and the template $template.
|
||||
$template file must be in $self->templateDir directory.
|
||||
HTML template will receive 5 variables:
|
||||
|
||||
=over
|
||||
|
||||
=item SCRIPT_NAME: the path to the (F)CGI
|
||||
|
||||
=item STATIC_PREFIX: content of $self->staticPrefix
|
||||
|
||||
=item AVAILABLE_LANGUAGES: content of $self->languages
|
||||
|
||||
=item LINKS: JSON stringification of $self->links
|
||||
|
||||
=item VERSION: Lemonldap::NG version
|
||||
|
||||
=back
|
||||
|
||||
The response is always send with a 200 code.
|
||||
|
||||
=head3 sendJSONresponse ( $req, $json, %args )
|
||||
|
||||
Stringify $json object and send it to the client. $req is the
|
||||
Lemonldap::NG::Common::PSGI::Request object; %args can define the HTTP error
|
||||
code (200 by default).
|
||||
|
||||
If client is not json compatible (`Accept` header), response is send in XML.
|
||||
|
||||
Examples:
|
||||
|
||||
$self->sendJSONresponse ( $req, { result => 0 }, code => 400 );
|
||||
|
||||
$self->sendJSONresponse ( $req, { result => 1 } );
|
||||
|
||||
=head3 sendError ( $req, $msg, $code )
|
||||
|
||||
Call sendJSONresponse with `{ error => $msg }` and code (default to 500) and
|
||||
call lmLog() to duplicate error in logs
|
||||
|
||||
=head3 abort ( $msg )
|
||||
|
||||
When an error is detected during startup (init() sub), you must not call
|
||||
sendError() but call abort(). Each request received later will receive the
|
||||
error (abort uses sendError() behind the scene).
|
||||
|
||||
=head2 Accessors
|
||||
|
||||
=head3 error
|
||||
|
||||
String error. Used if init() fails or if sendError is called without argument.
|
||||
|
||||
=head3 languages
|
||||
|
||||
String containing list of languages (ie "fr, en'). Used by sendHtml().
|
||||
|
||||
=head3 logLevel
|
||||
|
||||
See lmLog().
|
||||
|
||||
=head3 staticPrefix
|
||||
|
||||
String indicating the path of static content (js, css,...). Used by sendHtml().
|
||||
|
||||
=head3 templateDir
|
||||
|
||||
Directory containing template files.
|
||||
|
||||
=head3 links
|
||||
|
||||
Array of links to display by sendHtml(). Each element has the form:
|
||||
|
||||
{ target => 'http://target', title => 'string to display' }
|
||||
|
||||
=head3 syslog
|
||||
|
||||
Syslog facility. If empty, STDERR will be used for logging
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<Lemonldap::NG::Common::PSGI::Request>,
|
||||
L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over
|
||||
|
||||
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
||||
|
||||
=item François-Xavier Deltombe, E<lt>fxdeltombe@gmail.com.E<gt>
|
||||
|
||||
=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=item Thomas Chemineau, E<lt>thomas.chemineau@gmail.comE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUG REPORT
|
||||
|
||||
Use OW2 system to report bug or ask for features:
|
||||
L<http://jira.ow2.org>
|
||||
|
||||
=head1 DOWNLOAD
|
||||
|
||||
Lemonldap::NG is available at
|
||||
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
=over
|
||||
|
||||
=item Copyright (C) 2015 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=back
|
||||
|
||||
This library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see L<http://www.gnu.org/licenses/>.
|
||||
|
||||
=cut
|
||||
|
|
|
@ -139,3 +139,193 @@ sub jsonBodyToObj {
|
|||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
=encoding utf8
|
||||
|
||||
Lemonldap::NG::Common::PSGI::Request - HTTP request object for Lemonldap::NG
|
||||
PSGIs
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package My::PSGI;
|
||||
|
||||
use base Lemonldap::NG::Common::PSGI;
|
||||
|
||||
# See Lemonldap::NG::Common::PSGI
|
||||
...
|
||||
|
||||
sub router {
|
||||
my ( $self, $req ) = splice @_;
|
||||
# Do something and return a PSGI response
|
||||
# NB: $req is a Lemonldap::NG::Common::PSGI::Request object
|
||||
if ( $req->accept eq 'text/plain' ) { ... }
|
||||
|
||||
return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Body lines' ] ];
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This package provides HTTP request objects used by Lemonldap::NG PSGIs. It
|
||||
contains common accessors to work with request
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 Accessors
|
||||
|
||||
=head3 accept
|
||||
|
||||
'Accept' header content.
|
||||
|
||||
=head3 encodings
|
||||
|
||||
'Accept-Encoding' header content.
|
||||
|
||||
=head3 languages
|
||||
|
||||
'Accept-Language header content.
|
||||
|
||||
=head3 cookies
|
||||
|
||||
'Cookie' header content.
|
||||
|
||||
=head3 hostname
|
||||
|
||||
'Host' header content.
|
||||
|
||||
=head3 remote_ip
|
||||
|
||||
Client IP address.
|
||||
|
||||
=head3 port
|
||||
|
||||
Client TCP port.
|
||||
|
||||
=head3 method
|
||||
|
||||
HTTP method asked by client (GET/POST/PUT/DELETE).
|
||||
|
||||
=head3 scriptname
|
||||
|
||||
SCRIPT_NAME environment variable provided by HTTP server.
|
||||
|
||||
=head3 get_server_port
|
||||
|
||||
Server port.
|
||||
|
||||
=head3 path
|
||||
|
||||
PATH_INFO content which has been substracted `scriptname`. So it's the relative
|
||||
path_info for REST calls.
|
||||
|
||||
=head3 uri
|
||||
|
||||
REQUEST_URI environment variable.
|
||||
|
||||
=head3 unparsed_uri
|
||||
|
||||
Same as `uri` but without decoding.
|
||||
|
||||
=head3 user
|
||||
|
||||
REMOTE_USER environment variable. It contains username when a server authentication
|
||||
is done.
|
||||
|
||||
=head3 userData
|
||||
|
||||
Hash reference to be used by Lemonldap::NG::Handler::PSGI. If a server authentication
|
||||
is done, it contains:
|
||||
|
||||
{ _whatToTrace => `user()` }
|
||||
|
||||
=head3 params
|
||||
|
||||
GET parameters.
|
||||
|
||||
=head3 body
|
||||
|
||||
Content of POST requests
|
||||
|
||||
=head3 error
|
||||
|
||||
Set if an error occurs
|
||||
|
||||
=head3 contentType
|
||||
|
||||
Content type of posted datas.
|
||||
|
||||
=head3 contentLength
|
||||
|
||||
Length of posted datas.
|
||||
|
||||
=head2 Private accessors
|
||||
|
||||
=head3 _psgixBuffered
|
||||
|
||||
PSGI psgix.input.buffered variable.
|
||||
|
||||
=head3 _psgiInput
|
||||
|
||||
PSGI psgix.input variable.
|
||||
|
||||
=head2 Methods
|
||||
|
||||
=head3 jsonBodyToObj()
|
||||
|
||||
Get the content of a JSON POST request as Perl object.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<Lemonldap::NG::Common::PSGI::Request>,
|
||||
L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over
|
||||
|
||||
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
||||
|
||||
=item François-Xavier Deltombe, E<lt>fxdeltombe@gmail.com.E<gt>
|
||||
|
||||
=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=item Thomas Chemineau, E<lt>thomas.chemineau@gmail.comE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUG REPORT
|
||||
|
||||
Use OW2 system to report bug or ask for features:
|
||||
L<http://jira.ow2.org>
|
||||
|
||||
=head1 DOWNLOAD
|
||||
|
||||
Lemonldap::NG is available at
|
||||
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
=over
|
||||
|
||||
=item Copyright (C) 2015 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=back
|
||||
|
||||
This library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see L<http://www.gnu.org/licenses/>.
|
||||
|
||||
=cut
|
||||
|
|
|
@ -150,3 +150,210 @@ sub followPath {
|
|||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
=encoding utf8
|
||||
|
||||
Lemonldap::NG::Common::PSGI::Router - Base library for REST APIs of Lemonldap::NG.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package My::PSGI;
|
||||
|
||||
use base Lemonldap::NG::Common::PSGI::Router;
|
||||
|
||||
sub init {
|
||||
my ($self,$args) = splice @_;
|
||||
# Will be called 1 time during startup
|
||||
|
||||
# Declare REST routes (could be HTML templates or methods)
|
||||
$self->addRoute ( 'index.html', undef, ['GET'] )
|
||||
->addRoute ( books => { ':book' => 'booksMethod' }, ['GET', 'POST'] )
|
||||
->addRoute ( properties => { '*' => 'propertiesMethod' }, ['GET', 'POST', 'PUT', 'DELETE']);
|
||||
|
||||
# Default route (ie: PATH_INFO == '/')
|
||||
$self->defaultRoute('index.html');
|
||||
|
||||
# See Lemonldap::NG::Common::PSGI for other options
|
||||
|
||||
# Return a boolean. If false, then error message has to be stored in
|
||||
# $self->error
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub booksMethod {
|
||||
my ( $self, $req, @otherPathInfo ) = splice @_;
|
||||
my $book = $req->params('book');
|
||||
my $method = $req->method;
|
||||
...
|
||||
$self->sendJSONresponse(...);
|
||||
}
|
||||
|
||||
sub propertiesMethod {
|
||||
my ( $self, $property, @otherPathInfo ) = splice @_;
|
||||
my $method = $req->method;
|
||||
...
|
||||
$self->sendJSONresponse(...);
|
||||
}
|
||||
|
||||
This package could then be called as a CGI, using FastCGI,...
|
||||
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use My::PSGI;
|
||||
use Plack::Handler::FCGI; # or Plack::Handler::CGI
|
||||
|
||||
Plack::Handler::FCGI->new->run( My::PSGI->run() );
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This package provides base class for Lemonldap::NG REST API but could be
|
||||
used regardless.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
See L<Lemonldap::NG::Common::PSGI> for logging methods, content sending,...
|
||||
|
||||
=head2 Initialization methods
|
||||
|
||||
=head3 addRoute ( $word, $dest, $methods )
|
||||
|
||||
Declare a REST route. Arguments:
|
||||
|
||||
=over
|
||||
|
||||
=item $word: the first word of /path/info.
|
||||
|
||||
=item $dest: string, sub ref or hash ref (see "Route types" bellow)
|
||||
|
||||
=item $methods: array ref containing the methods concerned by this route.
|
||||
|
||||
=back
|
||||
|
||||
=head4 Route types
|
||||
|
||||
As seen in "SYNOPSIS", you can declare routes with variable component. $dest
|
||||
can be:
|
||||
|
||||
=over
|
||||
|
||||
=item a word: the name of the method to call
|
||||
|
||||
=item undef: $word is used as $dest
|
||||
|
||||
=item a ref to code: an anonymous subroutin to call
|
||||
|
||||
=item a hash ref: it's a recursive call to `{ $word => $dest }`
|
||||
|
||||
=item an array ref: in this case each element of the array will be considered as
|
||||
`{ $element => $element }`. So each element must be a word that makes a
|
||||
correspondance between a path_info word and a subroutine
|
||||
|
||||
=back
|
||||
|
||||
Some special $word:
|
||||
|
||||
=over
|
||||
|
||||
=item ':name': the word in path_info will be stored in GET parameters
|
||||
|
||||
=item '*': the subroutine will be called with the word of path_info as second argument
|
||||
(after $req)
|
||||
|
||||
=item 'something.html': if $word finishes with '.html', then sendHtml() will be called
|
||||
with 'something.tpl' as template name. In this case, $dest is not used.
|
||||
|
||||
=back
|
||||
|
||||
Examples:
|
||||
|
||||
=over
|
||||
|
||||
=item to manage http://.../books/127 with book() where 127 is the book number, use:
|
||||
|
||||
$self->addRoute( books => { ':bookId' => 'book' }, ['GET'] );
|
||||
|
||||
booId parameter will be stored in $req->params('bookId');
|
||||
|
||||
=item to manage http://.../books/127/pages/5 with page(), use:
|
||||
|
||||
$self->addRoute( books => { ':bookId' => { pages => { ':pageId' => 'page' } } }, ['GET'] );
|
||||
|
||||
=item to manage simultaneously the 2 previous examples
|
||||
|
||||
$self->addRoute( books => { ':bookId' => { pages => { ':pageId' => 'page' } } }, ['GET'] )
|
||||
->addRoute( books => { ':bookId' => { '*' => 'book' } }, ['GET'] );
|
||||
|
||||
Note that book() will be called for any path_info containing /books/<$bookid>/<$other>
|
||||
except if $other == 'pages'.
|
||||
|
||||
=item to manage /properties/p1, /properties/p2 with p1() and p2(), use:
|
||||
|
||||
$self->addRoute( properties => [ 'p1', 'p2' ] );
|
||||
|
||||
=back
|
||||
|
||||
=head3 defaultRoute($path)
|
||||
|
||||
This method defined which path_info to use if path_info is '/' or empty.
|
||||
|
||||
=head3 Accessors
|
||||
|
||||
See L<Lemonldap::NG::Common::PSGI> for inherited accessors (error, languages,
|
||||
logLevel, staticPrefix, templateDir, links, syslog).
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<http://lemonldap-ng.org/>, L<Lemonldap::NG::Portal>, L<Lemonldap::NG::Handler>,
|
||||
L<Plack>, L<PSGI>, L<Lemonldap::NG::Common::PSGI::Router>,
|
||||
L<Lemonldap::NG::Common::PSGI::Request>, L<Lemonldap::NG::Common::PSGI::Request>,
|
||||
L<HTML::Template>,
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over
|
||||
|
||||
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
|
||||
|
||||
=item François-Xavier Deltombe, E<lt>fxdeltombe@gmail.com.E<gt>
|
||||
|
||||
=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=item Thomas Chemineau, E<lt>thomas.chemineau@gmail.comE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUG REPORT
|
||||
|
||||
Use OW2 system to report bug or ask for features:
|
||||
L<http://jira.ow2.org>
|
||||
|
||||
=head1 DOWNLOAD
|
||||
|
||||
Lemonldap::NG is available at
|
||||
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
=over
|
||||
|
||||
=item Copyright (C) 2015 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>
|
||||
|
||||
=back
|
||||
|
||||
This library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
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. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see L<http://www.gnu.org/licenses/>.
|
||||
|
||||
=cut
|
||||
|
|
Loading…
Reference in New Issue
Block a user