MuHttpServer.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef MUHTTPSERVER_H
00011 #define MUHTTPSERVER_H
00012 
00013 #include "AttachmentPtr.h"
00014 #include "EnumWrapper.h"
00015 #include "SessionManager.h"
00016 #include <ehs.h>
00017 #include <QtCore/QMap>
00018 #include <QtCore/QObject>
00019 #include <QtCore/QString>
00020 #include <boost/any.hpp>
00021 
00022 class QTextStream;
00023 class QTimer;
00024 class Subject;
00025 
00026 /**
00027  * This class provides a framework for creating HTTP micro servers in Qt.
00028  */
00029 class MuHttpServer : public QObject, public EHS
00030 {
00031    Q_OBJECT
00032 
00033 public:
00034    /**
00035     * This structure contains information used to send a response to an HTTP request.
00036     */
00037    struct Response
00038    {
00039       /**
00040        * The body of the response message if the response is 8-bit safe. (i.e. ASCII)
00041        */
00042       QString mBody;
00043       
00044       /**
00045        * The body of the response message if the response is not 8-bit safe. (i.e. a raw image)
00046        */
00047       QByteArray mOctets;
00048 
00049       /**
00050        * Additional HTTP headers to attach to the response message.
00051        *
00052        * The key is the name of the header and the value is the header data.
00053        */
00054       QMap<QString,QString> mHeaders;
00055 
00056       /**
00057        * The type of response.
00058        *
00059        * This can be the numeric code defined by the HTTP RFCs or
00060        * a convenience enum value as defined by the EHS library. (for example, HTTPRESPONSE_200_OK)
00061        */
00062       ResponseCode mCode;
00063 
00064       // What character encoding is the response body?
00065       enum CharacterEncodingTypeEnum
00066       {
00067          ASCII, /**< The response body is ASCII encoded and contained in the mBody member. */
00068          UTF8,  /**< The response body is UTF-8 encoded and contained in the mBody member. */
00069          OCTET  /**< The response body consists of raw octets and is contained in the mOctets member. */
00070       };
00071       
00072       /**
00073        * @EnumWrapper MuHttpServer::Response::CharacterEncodingTypeEnum.
00074        */
00075       typedef EnumWrapper<CharacterEncodingTypeEnum> CharacterEncodingType;
00076       
00077       /**
00078        * What character encoding is the response body?
00079        */
00080       CharacterEncodingType mEncoding;
00081 
00082       /**
00083        * Create an uninitialized Response with a default encoding type of ASCII.
00084        */
00085       Response() : mCode(HTTPRESPONSECODE_INVALID), mEncoding(ASCII) {}
00086    };
00087 
00088    /**
00089     * Initialize a MuHttpServer object.
00090     *
00091     * @param port
00092     *        The TCP port that this server will listen. If port is 0, this
00093     *        object is assumed to be a child handler and no network socket
00094     *        will be set up.
00095     * @param pParent
00096     *        The Qt parent of this object.
00097     *
00098     * @see registerPath()
00099     */
00100    MuHttpServer(int port = 80, QObject *pParent = NULL);
00101 
00102    /**
00103     * Clean up the MuHttpServer object and close network sockets.
00104     */
00105    virtual ~MuHttpServer();
00106 
00107    /**
00108     * Listen to the network and start processing requests.
00109     *
00110     * @return True if successful or if the server is already running, false if there is an error.
00111     */
00112    bool start();
00113 
00114    /**
00115     * Stop the server.
00116     */
00117    void stop(Subject &subject, const std::string &signal, const boost::any &v);
00118 
00119    /**
00120     * Attach a server path to a response object.
00121     *
00122     * Requests from the registered path will be handled by pObj.
00123     * For example, registerPath("/test", this) will cause the following
00124     * requests to be handled by the this object.
00125     *  http://localhost/test/
00126     *  http://localhost/test/foo
00127     *  http://localhost/test/bar
00128     * The following will not be handled by the this object.
00129     *  http://localhost/test
00130     *  http://localhost/test/foo/
00131     *  http://localhost/test/foo/bar
00132     *  http://localhost/foo/
00133     *
00134     * Any paths not explicitly registered will be handled by the root EHS object.
00135     *
00136     * @param path
00137     *        The path prefix for processing.
00138     * @param pObj
00139     *        The object that wants to processing path.
00140     */
00141    void registerPath(const QString &path, EHS *pObj);
00142 
00143 protected:
00144    /**
00145     * This handles HTTP POST requests.
00146     *
00147     * POST requests encode form data in the request body.
00148     *
00149     * The default behavior is to return an HTTP 403 Forbidden response
00150     * to the requesting client.
00151     *
00152     * @param uri
00153     *        The URI of the request. If this object is handling sub requests
00154     *        via registerPath(), this will be a partial URI rooted at the path
00155     *        this object is registered to handle.
00156     * @param contentType
00157     *        The HTTP Content-type of the request.
00158     * @param body
00159     *        The body of the request.
00160     * @param form
00161     *        Form data from the request body.
00162     * @return An HTTP Response.
00163     */
00164    virtual Response postRequest(const QString& uri, const QString& contentType, const QString& body,
00165       const FormValueMap& form);
00166 
00167    /**
00168     * This handles HTTP GET requests.
00169     *
00170     * GET requests encode form data in the request URL using ? and &.
00171     *
00172     * @param uri
00173     *        The URI of the request. If this object is handling sub requests
00174     *        via registerPath(), this will be a partial URI rooted at the path
00175     *        this object is registered to handle.
00176     * @param contentType
00177     *        The HTTP Content-type of the request.
00178     * @param body
00179     *        The body of the request. This is usually empty with GET requests.
00180     * @param form
00181     *        Form data encoded in the request URL.
00182     * @return An HTTP Response.
00183     */
00184    virtual Response getRequest(const QString& uri, const QString& contentType, const QString& body,
00185       const FormValueMap& form) = 0;
00186 
00187 protected slots:
00188    /**
00189     * Handle new and existing connections.
00190     *
00191     * This runs one cycle of the server's request loop.
00192     * The default behavior of a MuHttpServer is to call this slot
00193     * every 250ms.
00194     */
00195    void processServer();
00196 
00197    /**
00198     * This provides debugging information about an HttpRequest.
00199     *
00200     * The default behavior is to do nothing. If an implementation wants
00201     * to log all requests for debugging purposes, this method should be overridden.
00202     *
00203     * @param pHttpRequest
00204     *        The request object.
00205     */
00206    virtual void debug(HttpRequest *pHttpRequest);
00207 
00208    /**
00209     * Display a waning message.
00210     *
00211     * The default behavior is to do nothing. If an implementation wants
00212     * to display extra warning messages, this method should be overridden.
00213     * This method is called when the underlying HTTP server code throws an error
00214     * during socket setup, conntection, or processing. It is also called when
00215     * postRequest() or getRequest() return an HTTPRESPONSECODE_INVALID indicating
00216     * an internal server error.
00217     *
00218     * @param msg
00219     *        A user displayable warning message.
00220     */
00221    virtual void warning(const QString &msg);
00222 
00223    /**
00224     * Allow connections from machines other than localhost.
00225     *
00226     * The default is to allow only localhost connections.
00227     *
00228     * @param val
00229     *        If true, any machine can connect. If false, only localhost can connect.
00230     */
00231    void allowNonLocalConnections(bool val)
00232    {
00233       mAllowNonLocal = val;
00234    }
00235 
00236 private:
00237    MuHttpServer(const MuHttpServer& rhs);
00238    MuHttpServer& operator=(const MuHttpServer& rhs);
00239    ResponseCode HandleRequest(HttpRequest *pHttpRequest, HttpResponse *pHttpResponse);
00240 
00241    EHSServerParameters mParams;
00242    QTimer* mpTimer;
00243    QMap<QString, EHS*> mRegistrations;
00244    bool mServerIsRunning;
00245    bool mAllowNonLocal;
00246    AttachmentPtr<SessionManager> mSession;
00247 };
00248 
00249 #endif

Software Development Kit - Opticks 4.9.0 Build 16218