platform/services/QueryService.cpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #include "QueryService.hpp"
00021 #include <boost/bind.hpp>
00022 #include <pion/net/HTTPResponseWriter.hpp>
00023 #include <pion/net/PionUser.hpp>
00024 #include "PlatformConfig.hpp"
00025 
00026 using namespace pion;
00027 using namespace pion::net;
00028 
00029 namespace pion {        // begin namespace pion
00030 namespace plugins {     // begin namespace plugins
00031 
00032     
00033 // QueryService member functions
00034 
00036 void QueryService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
00037 {
00038     // split out the path branches from the HTTP request
00039     PathBranches branches;
00040     splitPathBranches(branches, request->getResource());
00041 
00042     // use a response in case we want to change any of the headers/etc.
00043     // while processing the request
00044     HTTPResponsePtr response_ptr(new HTTPResponse(*request));
00045 
00046     // use a stringstream for the response content
00047     // since HTTPResponseWriter does not yet have a stream wrapper available
00048     std::ostringstream ss;
00049 
00050 /*
00051     for (int i = 0; i < branches.size() ; i++ )
00052         xml += branches[i] + "::";
00053 
00054     xml += "\r\n";
00055 */
00056 
00057     if (request->getMethod() == HTTPTypes::REQUEST_METHOD_GET) {
00058         if (!branches.empty() && branches.front() == "reactors") {
00059             /*
00060              *  branches[0] == reactors
00061              *  branches[1] == UUID
00062              *  branches[2] == aggregate/example/info
00063              */
00064 
00065             if (branches.size() >= 2) {
00066                 const std::string reactor_id(branches.at(1));
00067                 if (getConfig().getReactionEngine().hasPlugin(reactor_id)) {
00068 
00069                     // Check whether the User has permission for this Reactor.
00070                     bool reactor_allowed = getConfig().getUserManagerPtr()->accessAllowed(request->getUser(), getConfig().getReactionEngine(), reactor_id);
00071                     if (! reactor_allowed) {
00072                         // Log an error and send a 403 (Forbidden) response.
00073                         std::string error_msg = "User doesn't have permission for Reactor " + reactor_id + ".";
00074                         handleForbiddenRequest(request, tcp_conn, error_msg);
00075                         return;
00076                     }
00077 
00078                     getConfig().getReactionEngine().query(
00079                         reactor_id, ss, branches,
00080                         request->getQueryParams());
00081                 } else {
00082                     // Log an error and send a 404 (Not Found) response.
00083                     handleNotFoundRequest(request, tcp_conn);
00084                     return;
00085                 }
00086             } else {
00087                 // send detailed statistics for all Reactors
00088                 getConfig().getReactionEngine().writeStatsXML(ss, "", true);
00089             }
00090         } else if (! branches.empty() && branches.front() == "permissions") {
00091             getConfig().getUserManagerPtr()->writePermissionsXML(ss, request->getUser()->getUsername());
00092         } else {
00093             throw UnknownQueryException();
00094         }
00095     } else {
00096         // Log an error and send a 405 (Method Not Allowed) response.
00097         handleMethodNotAllowed(request, tcp_conn, "GET");
00098         return;
00099     }
00100 
00101     // Set Content-type to "text/xml"
00102     HTTPResponseWriterPtr writer(HTTPResponseWriter::create(tcp_conn, response_ptr,
00103                                                             boost::bind(&TCPConnection::finish, tcp_conn)));
00104     writer->getResponse().setContentType(HTTPTypes::CONTENT_TYPE_XML);
00105 
00106     writer->write(ss.str());
00107     
00108     // send the writer
00109     writer->send();
00110 }
00111 
00112 
00113 }   // end namespace plugins
00114 }   // end namespace pion
00115 
00116 
00118 extern "C" PION_SERVICE_API pion::server::PlatformService *pion_create_QueryService(void)
00119 {
00120     return new pion::plugins::QueryService();
00121 }
00122 
00124 extern "C" PION_SERVICE_API void pion_destroy_QueryService(pion::plugins::QueryService *service_ptr)
00125 {
00126     delete service_ptr;
00127 }

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7