#!/usr/bin/perl # main.fcgi is part of Calliope, an open source music management system. # main.fcgi is the same as home.fcgi, they function as protected and # unprotected gateways to calliope, respectively. # # This is the interface between the apache fast cgi module, and the # Dispatch module of calliope, which accepts all incoming web requests. # It's based on several snippets of example code I found on the web, # which i can no longer find. # # Changes Copyright (C) 02006-02007 Neil Verplank # http://neil.verplank.org/opensource/calliope/ # # 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 1, or (at your option) # version 2. # # 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. # # See ~/LICENSE for more details. use lib "/usr/local/calliope/lib"; use strict; use Web::Dispatch (); use CGI::Fast; my $handling_request = 0; my $exit_requested = 0; my $request; # sig_handler is "called by" fastcgi when it decides to terminate # a no longer needed thread. exiting directly causes an error, # because this thread is also in an infinite while loop, # and must receive one more request in order to terminate # gracefully. so, we set the global exit flag, and return a # thumbs up. sub sig_handler { $exit_requested = 1; return 1; } $SIG{USR1} = \&sig_handler; $SIG{TERM} = \&sig_handler; $SIG{PIPE} = sub {die 'SIGPIPE\n';}; # the main entry point - receives incoming requests, attempts to handle # them and their potential failure gracefully, and aborts upon a fatal # error or SIGPIPE. while ($request = new CGI::Fast) { eval {&abort_request;} if (!eval {&do_request;} && $@ ne 'SIGPIPE\n'); $handling_request = 0; last if $exit_requested; } exit(0); # sends a received request to calliope's web entry point, Dispatch. sub do_request() { $handling_request = 1; my $result = &Web::Dispatch::dispatch($request); # 1 if no DB connection return 1; } # what to do when it all goes pear-shaped. sub abort_request() { $exit_requested = 1; # assume the error isn't recoverable print STDERR "fatal error in process $$ (fastcgi), request aborted, shutting down: $@\n"; }