HTTPSServer
Class for defining and running a REST-server.
use HTTPSServer;
# instantiate
my $srv=HTTPSServer->new(LocalAddr=>"10.0.0.1:1234",Listen=>11,servername=>"My REST-server",SSL_key_file=>"/folder/myprivate.key",SSL_cert_file=>"/folder/mypublic.key");
# add method to server
$srv->addMethod("/MyServerMethod",\&MySourceCodeFunctionReference,"Some method comment");
# set authentication handler
$srv->setAuthHandler (\&SomeAuthFunction);
# set database handler
$srv->setDBHandler (\&someDatabaseFunction);
# attempt bind
if (!$srv->bind()) { print "Unable to bind to interface: ".$srv->error()."\n"; exit; }
# run server loop
while ($srv->bound()) {
if (!$srv->loop()) {
print "Error! ".$srv->error()."\n";
}
}
Class to define and run a REST-server. It basically have methods to define an authentication handler and a database handler. These two should return information that is passed on to all methods in the REST-server defined through the addMethod()-method.
The Authentication-handler should return any ID or information that the methods of the server know to use to identify the credentials of the one calling the REST-method. For AURORA the handler returns either 0 for not authenticated or a number higher than 0 for a user ID from the AURORA database. All the methods in AURORA expects such a behaviour and can use that ID to identify who it is by talking to the database.
The database handler is meant to ensure that we have a valid database handler for the AURORA database that can be given to the method-function that handles the REST-method call. The database handler is expected to return this database instance (DBI-class type) or undef upon failure.
The loop-method of the HTTPSServer-class handles the waiting for connection and forking out of connections when a client connects. It also handles upgrading the HTTP-connection to a HTTPS or SSL-based connections. All connections to the server needs to be HTTPS-connections.
All calls to the HTTPSServer-class by clients are expected to be POST-type HTTP-data. It does not support different HTTP-method, such as GET, DELETE or what not. The type of HTTP-method being performed is instead defined by the method name itself, such as /getDatasetMetadata or /getName. This deviates from the typical REST-server implementation (where it is normal to use the HTTP-method to signify the verb of the resource being manipulated).
Constructor. Creates class-instance.
Accepts the following input parameters:
converter Specifies a Content-instance reference that is used as the converter type for the data coming into the HTTPS-server. Optional. If not specified defaults to Content::JSON.
Listen Queue size for listen. See IO::Socket::INET. Optional. Defaults to 5.
LocalPort Local host port address. See IO::Socket::INET/IO::Socket::IP. Optional. Defaults to "1000".
Log Specifies a Log-instance reference (see AURORA Log-class). This is used to write events to the log if something happens and is also shared by all methods of the HTTPS-server. Optional. Creates a new Log-instance if none specified.
servername Service name of the server that is reported as "Server" in the HTTP-response. Optional. If not specified will default to "MyServerService".
settings Specified a Settings-instance (see AURORA Settings-class). It basically brings the configuration settings of the HTTPS-server. This instance is shared by all methods of the HTTPS-server. Optional. Creates a new Settings-instance if none specified (or is invalid).
syslog Specified a SystemLogger-instance (see AURORA SystemLogger-class). It gives a way to syslog when something happens for the HTTPS-server. Optional. Creates a new SystemLogger-instance if none specified or the reference is invalid.
SSL_ca_file Specifies the CA for the key set (SSL_key_file and SSL_cert_file). Optional. Defaults to undef. See IO::Socket::SSL.
SSL_cert_file Specifies the public SSL key of the HTTPS-server. Optional. Defaults to undef. See IO::Socket::SSL.
SSL_key_file Specifies the servers private SSL key. Optional. Defaults to undef. See IO::Socket::SSL.
SSL_verify_mode Sets how the certificate of the client is to be checked. Optional. Does not need to be changed and defaults to SSL_VERIFY_NONE (no need to verify the client in other words).
Timeout Sets the HTTPS-server timeout of sockets. Optional. Defaults to 300.
Besides the parameters given, this method accepts any option from IO::Socket::SSL and/or IO::Socket::INET/IO::Socket::IP. Please note that from version 6.05 of HTTP::Daemon, it uses the IO::Socket::IP instead of IO::Socket::INET. This is preferred because the HTTP::Daemon then supports binding to both ipv4 and ipv6 addresses/interfaces.
By default this module enforces both ipv4 and ipv6 binding by setting the Family-parameter to AF_INET6. To bind to both ipv4 and ipv6 at the same time, only set the LocalPort-parameter and not the LocalAddr and/or LocalHost-parameters.
Returns an HTTPSServer-instance.
Attempts to bind to the local address specified.
No input parameters accepted.
This method uses the parameters specified to new() and attempts to bind to the local interface specified. It will only bind by using a HTTP::Daemon-instance as per recommendation in the IO::Socket::SSL documentation. The connection will attempt upgrade to SSL as soon as the client has connected.
Returns 1 upon success, 0 upon failure. Please check the error()-method for more information upon failure.
Returns if the instance is bound to the interface or not.
No input accepted.
Returns 1 if bound, 0 if not.
Add a method to the HTTPS-server.
Accepts input in the following order: method-link, function-reference, comment.
The method-link is the absolute path from the server root of the REST-method being added. SCALAR. Required. In other words it is the link that the client needs to refer to in order to invoke that REST-method. Eg.: /getDatasetMetadata.
The function-reference is a reference to a Perl-function that does all the work of the REST-method. Required. Eg.: \&MyFunctionReference.
Description is the explanation/comment to the REST-method. SCALAR. Required.
The methods added here are the methods available through the HTTPS-server.
Returns 1 upon success, 0 upon failure. Please check the error()-method for more information upon failure.
Removes method from the REST-server.
Input is the method-link. See the addMethod() for information on formatting of it.
If the given method-link exists it is removed as a method for the REST-server.
Returns 1 upon success, 0 upon failure. Please check the error()-method for more information upon failure.
Sets the function handling retrieving a functioning database instance.
Accepts input in the following order: function reference to the function handling connecting/ retrieving the database-instance.
The function handling the authentication process is expected to receive: message-instance (using Content-class of the HTTPSServer, eg. Content::JSON), database instance (same as returned from this method), Settings-instance and Log-instance.
It is up to the user of the HTTPSServer and its methods to define what is considered an acceptable database-instance in return. AURORA returns a connected instance of the AuroraDB-class (which are passed on to the REST-method function).
Returns a database instance upon success, undef upon failure. Please check the error()-method for more information upon failure.
Sets the function handling the authentication of the REST-server.
Accepts one input: function reference to Perl function handling the authentication.
The function handling the authentication process is expected to receive: message-instance (using Content-class of the HTTPSServer, eg. Content::JSON), database instance (same as returned from the function set in setDBHandler), Settings-instance and Log-instance.
When authenticated the function is expected to return a user id or 0 upon failure.
Returns > 0 on success, 0 upon failure. Please check the error()-method for more information upon failure.
Main loop of the REST-server.
This method accepts no input.
This method is the main loop of the REST-server. It sits and waits for clients to connect and when a connection arrives, it forks out a separate process to handle it.
The separate process for the client-connection immdiately attempts to upgrade it to HTTPS/SSL. When such an upgrade has been successful it goes into a HTTP-request loop that will exists for this one client-call or if the KeepAlive-flag has been set it will loop until the client disconnects.
This loop handles running the database-handler and the authentication-handler. If database connection and authentication fails the REST-server informs the client and closes the connection and the loop.
If database connection and authentication were successful it invokes a REST-method function, if the REST-method exists, and passes these parameters to each function:
- message-instance (Content-class instance of the HTTPS-server) - Method-parameters as a HASH-reference (after being decoded from the data of the Content-class being used - typically JSON), Database instance (typically AuroraDB-instance) - User id from the Authentication-handler - Settings-instance - Log-instance - SystemLogger-instance.
The loop receives any potential feedback from the function performing the job of the REST-method and sends an answer to the client.
Sends a message to the client.
Input accepted: Content-instance and HTTP code.
This method basically handles sending the response back to the calling client and with the HTTP code specified. It is called by the loop()-method and should not be called directly by the user of this HTTPSServer-class.
Returns 1 upon success, 0 upon failure. Please check the error()-method for more information upon failure.
Get or set the Content-class being used for messaging between client and server.
If input is specified it is interpreted as a set and the input must be a valid Content-class.
Returns the Content-class upon success (also on set), undef upon failure. Please check the error()-method for more information upon failure.
Get or set the local interface address and port of the REST-server.
If a set, it accepts one input "addr". It must specify the address and port (if needed) of the REST-server.
Please note that changing/setting the local interface address does not have any effect on already bound HTTPSServer-instances.
Returns the address upon success (also on set), undef upon failure. Please check the error()-method for more information upon failure.
Get or set the port number being used by the HTTPS-server.
If input is specified it is accepted to be a set and must be port number (SCALAR).
Returns the port-number (also on set).
Get the last error of this class.
No input accepted.
Returns the last error message or a blank string.