Fawkes API  Fawkes Development Version
webview_reqproc.cpp
00001 
00002 /***************************************************************************
00003  *  webview_reqproc.cpp - Webview ROS request processor
00004  *
00005  *  Created: Fri May 06 17:31:35 2011
00006  *  Copyright  2006-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include "webview_reqproc.h"
00024 #include <core/exception.h>
00025 #include <logging/logger.h>
00026 #include <webview/error_reply.h>
00027 #include <webview_msgs/ProcessRequest.h>
00028 
00029 using namespace fawkes;
00030 
00031 /** @class ROSWebviewRequestProcessor "webview_reqproc.h"
00032  * Convert webview requests to ROS service calls.
00033  * This request processor calls a ROS service to process the request and
00034  * produce the reply. This reply is then passed back to webview.
00035  *
00036  * This class requires the webview_msgs ROS package to be available.
00037  *
00038  * @author Tim Niemueller
00039  */
00040 
00041 /** Constructor.
00042  * @param nh node handle to create service client handle
00043  * @param logger logger for log output
00044  * @param baseurl Base URL this processor is registered for
00045  * @param srv_name the ROS service name to query for requests
00046  */
00047 ROSWebviewRequestProcessor::ROSWebviewRequestProcessor(LockPtr<ros::NodeHandle> nh,
00048                                                        Logger *logger,
00049                                                        std::string &baseurl,
00050                                                        std::string &srv_name)
00051   :  logger(logger)
00052 {
00053   __baseurl  = baseurl;
00054   __srv_name = srv_name;
00055   __logcomp  = std::string("ROSWebviewRP[") + srv_name + "]";
00056 
00057   __srv_client = nh->serviceClient<webview_msgs::ProcessRequest>(srv_name);
00058 }
00059 
00060 /** Destructor. */
00061 ROSWebviewRequestProcessor::~ROSWebviewRequestProcessor()
00062 {
00063   __srv_client.shutdown();
00064 }
00065 
00066 fawkes::WebReply *
00067 ROSWebviewRequestProcessor::process_request(const char *url,
00068                                             const char *method,
00069                                             const char *version,
00070                                             const char *upload_data,
00071                                             size_t *upload_data_size,
00072                                             void **session_data)
00073 {
00074   logger->log_debug(__logcomp.c_str(), "Processing %s", url);
00075 
00076   webview_msgs::ProcessRequest srv;
00077   srv.request.url = url;
00078   srv.request.method = method;
00079   srv.request.version = version;
00080   srv.request.upload_data =
00081     std::vector<uint8_t>((uint8_t *)upload_data,
00082                          (uint8_t *)&upload_data[*upload_data_size]);
00083 
00084   if (! __srv_client.exists()) {
00085     return new WebErrorPageReply(WebReply::HTTP_GONE,
00086                                  "Service %s is no longer available",
00087                                  __srv_name.c_str());
00088 
00089   } else if (__srv_client.call(srv)) {
00090     if (srv.response.code == WebReply::HTTP_OK) {
00091       WebReply *r = NULL;
00092       if (srv.response.wrap_in_page) {
00093         WebPageReply *pr =
00094           new WebPageReply(srv.response.title, srv.response.body);
00095         pr->set_html_header(srv.response.html_header);
00096         r = pr;
00097       } else {
00098         r = new StaticWebReply(WebReply::HTTP_OK, srv.response.body);
00099       }
00100 
00101       std::vector<std::string>::iterator h;
00102       for (h = srv.response.headers.begin(); h != srv.response.headers.end(); ++h)
00103       {
00104         try {
00105           r->add_header(*h);
00106         } catch (Exception &e) {
00107           // ignore
00108         }
00109       }
00110 
00111       return r;
00112     } else {
00113       return new WebErrorPageReply((WebReply::response_code_t)srv.response.code,
00114                                    "Execution of service %s failed: %s",
00115                                    __srv_name.c_str(),
00116                                    srv.response.error.c_str());
00117     }
00118   } else {
00119     return new WebErrorPageReply(WebReply::HTTP_INTERNAL_SERVER_ERROR,
00120                                  "Execution of service %s failed",
00121                                  __srv_name.c_str());
00122   }
00123 
00124   // should not happen...
00125   return NULL;
00126 }