CMS 3D CMS Logo

IgServerSocket.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "Iguana/WebFramework/interface/IgServerSocket.h"
00004 #include "Iguana/WebFramework/interface/IgSocket.h"
00005 #include "Iguana/WebFramework/interface/IgSessionManager.h"
00006 #include "Iguana/Framework/interface/IgState.h"
00007 #include "Iguana/Framework/interface/IgArgsElement.h"
00008 #include "Iguana/WebFramework/interface/IgServerPool.h"
00009 #include "Iguana/WebFramework/interface/IgFileManager.h"
00010 #include "Iguana/WebFramework/interface/IgWebService.h"
00011 #include <classlib/utils/StringOps.h>
00012 #include <classlib/utils/StringList.h>
00013 #include <qtimer.h>
00014 #include <qdatetime.h>
00015 #include <stdlib.h>
00016 #include <string>
00017 #include <vector>
00018 #include <iostream>
00019 #include <unistd.h>
00020 #include <sys/types.h>
00021 #include <classlib/utils/UUID.h>
00022 
00023 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00024 
00025 class IgFreeServerSocket : public QServerSocket
00026 {
00027 public:
00028     IgFreeServerSocket () : QServerSocket (0, 1, (QObject *) 0, 0)
00029     {}
00030     virtual void newConnection (int) {}
00031 };
00032 
00033 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00034 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00035 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00036 
00037 std::string IgServerSocket::m_hostname = "";
00038 std::string IgServerSocket::m_mainHostUrl = "";
00039 std::string IgServerSocket::m_proxy = "";
00040 int IgServerSocket::m_port = 0;
00041 
00042 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00043 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00044 
00045 IG_DEFINE_STATE_ELEMENT (IgServerSocket, "Server socket");
00046 
00047 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00048 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00049 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00050 
00051 IgServerSocket::IgServerSocket (IgState *state, bool mainPort /* = true */)
00052     : QServerSocket (cmdLinePort (state, mainPort))
00053 {
00054     initialize (state);
00055     if (mainPort)
00056         new IgSessionManager (state);
00057 }
00058 
00059 void
00060 IgServerSocket::initialize (IgState *state)
00061 {
00062     m_state = state;
00063     m_state->put (s_key, this);
00064     m_timeout = -1;
00065     m_timer = 0;
00066     m_clientCookieID = "";
00067     
00068     cmdLineProxy (state);       
00069     cmdLinePort (state);
00070     cmdLineHostname (state);
00071     ASSERT (!m_hostname.empty());
00072     
00073     if (!IgServerPool::get (m_state))
00074     {
00075         IgArgsElement *args = IgArgsElement::get (m_state);
00076         args->find ("--ig-main-hosturl", m_mainHostUrl);
00077         args->find ("--ig-timeout", m_timeout);
00078     
00079         if (m_timeout > 0)
00080         {
00081             m_timer = new QTimer (this);
00082             connect (m_timer, SIGNAL (timeout()), this, SLOT (timedOut()));
00083         }
00084     }
00085     std::cerr << "Bound to port:" <<this->port () << std::endl;
00086 }
00087 
00088 void
00089 IgServerSocket::newConnection (int port)
00090 {
00091     if (!m_state) return;
00092     IgSocket *socket = new IgSocket (m_state);
00093     connect (socket, SIGNAL(readyRead()), socket, SLOT(dump()));
00094     //connect (socket, SIGNAL(delayedCloseFinished()),
00095     //         this, SLOT(socketClosed()));
00096     socket->setSocket (port);
00097 }
00098 
00099 void
00100 IgServerSocket::startTimer ()
00101 {
00102     if (m_timer)
00103         m_timer->start (m_timeout*1000, true);
00104 }
00105 
00106 void
00107 IgServerSocket::timedOut ()
00108 { exit (0); }
00109 
00110 void
00111 IgServerSocket::socketClosed ()
00112 {
00113     IgSocket* socket = (IgSocket*)sender ();
00114     if (socket)
00115         delete socket;
00116 }
00117 
00118 void
00119 IgServerSocket::setClientCookieID (const std::string& cookieID)
00120 { m_clientCookieID = cookieID; }
00121 
00122 const std::string&
00123 IgServerSocket::getClientCookieID () const
00124 { return m_clientCookieID; }
00125 
00126 const std::string&
00127 IgServerSocket::cmdLineProxy ()
00128 { return m_proxy; }
00129 
00130 const std::string&
00131 IgServerSocket::cmdLineMainHostUrl ()
00132 { return m_mainHostUrl; }
00133 
00134 const std::string&
00135 IgServerSocket::cmdLineHostname ()
00136 { return m_hostname; }
00137 
00138 int
00139 IgServerSocket::cmdLinePort ()
00140 { return m_port; }
00141 
00142 std::string
00143 IgServerSocket::hostnameUrl ()
00144 { return m_hostname+":"+QString::number(cmdLinePort ()); }
00145 
00146 const std::string&
00147 IgServerSocket::cmdLineHostname (IgState *state)
00148 {
00149     cmdLineProxy (state);
00150     IgArgsElement *args = IgArgsElement::get (state);
00151     args->find ("--ig-hostname", m_hostname, false);
00152     if (m_proxy.empty() && !m_hostname.empty())
00153       m_hostname = "https://" + m_hostname;
00154     return m_hostname;
00155 }
00156 
00157 const std::string&
00158 IgServerSocket::cmdLineProxy (IgState *state)
00159 {
00160     IgArgsElement *args = IgArgsElement::get (state);
00161     args->find ("--ig-proxy", m_proxy, false);
00162     if(!m_proxy.empty() && m_proxy[0] != '/')
00163         m_proxy = "/"+ m_proxy;
00164     return m_proxy;
00165 }
00166 
00167 int
00168 IgServerSocket::cmdLinePort (IgState *state, bool mainPort /* = true */)
00169 {
00170     if (mainPort)
00171     {
00172         IgArgsElement *args = IgArgsElement::get (state);
00173         args->find ("--ig-port", m_port, false);
00174         return m_port;
00175     }
00176     return 0;
00177 }
00178 
00179 const std::string&
00180 IgServerSocket::generateCookie (std::string& cookie)
00181 {
00182     using namespace lat;
00183     char *uuidBuffer = new char[37];    
00184     UUID uuid = UUID::generateTime ();
00185     uuid.format (uuidBuffer);
00186     cookie = uuidBuffer;
00187     delete[] uuidBuffer;
00188     return cookie;
00189 }
00190 
00191 std::string
00192 IgServerSocket::redirect (const std::string& url, const std::string& redir,
00193                           const std::string& cookie)
00194 {
00195     std::string targetCookie = "";
00196     std::string newRedir = redir;
00197     
00198     if (!cookie.empty())
00199     {
00200         if (m_proxy.empty())
00201             targetCookie = "Set-Cookie: USER=" + cookie +"; path=/\r\n";
00202         else
00203             targetCookie = "Set-Cookie: USER=" + cookie +"; path=" + m_proxy + "\r\n";
00204     }
00205       
00206     if (!m_proxy.empty())
00207     {
00208         if (!redir.empty())
00209             targetCookie += "Set-Cookie: igtarget=" + redir + "; path=" + m_proxy + "\r\n";
00210         newRedir = url;
00211     }
00212     else
00213         newRedir += url;
00214     
00215     std::string result = "HTTP/1.1 302 Redirect\r\n"
00216              "Location: " + newRedir + "\r\n"
00217              "Content-Type: text/html; charset=\"utf-8\"\r\n"
00218              "Connection: Close\r\n"
00219              + targetCookie +
00220              "\r\n"
00221              "<html>"        
00222              "<body>"
00223              "<style  type=\"text/css\">"
00224              "a {color:#FFFFFF}"
00225              "</style>"
00226              "<h1><a href=\"" + newRedir + 
00227              "\">Click here if not redirected automatically</a></h1>"
00228              "</body>"
00229              "</html>\r\n\r\n";
00230     
00231     std::cerr << result << std::endl;
00232     
00233     return result;
00234 }
00235 
00236 int
00237 IgServerSocket::getFreePort ()
00238 {
00239     IgFreeServerSocket* server = new IgFreeServerSocket ();
00240     while (server->ok () == false)
00241         usleep (1000);
00242     int port = server->port ();
00243     delete server;
00244     return port;
00245 }
00246 
00247 void
00248 IgServerSocket::ping (QIODevice *socket)
00249 {
00250     IgFileManager* fileManager = getFileManager ();
00251     QByteArray writeBuffer = fileManager->lookup("images/ping.png");
00252     IgWebService::sendBinary(socket,writeBuffer,"png");
00253     socket->close ();
00254     socket->flush ();
00255 }
00256 
00257 void
00258 IgServerSocket::clientInitialization (QIODevice *socket)
00259 {
00260     IgFileManager* fileManager = getFileManager ();
00261     QByteArray writeBuffer =
00262       fileManager->lookup("htdocs/Ig_Modules/IgSocketDriver/html/iguanaInit.html");
00263     QTextStream client (socket);
00264     client << "HTTP/1.0 200 Ok\r\n"
00265               "Content-Type: text/html;\r\n"
00266               "\r\n"
00267               "<html><body><SCRIPT language=\"JavaScript\">var proxy =\"" +
00268               m_proxy + "\";</SCRIPT>\r\n";
00269 
00270     socket->writeBlock (writeBuffer.data (), 
00271                         writeBuffer.size ());
00272                         
00273     client << "</body></html>\r\n";
00274     socket->close ();
00275     socket->flush ();
00276 }
00277 
00278 IgFileManager*
00279 IgServerSocket::getFileManager () const
00280 {
00281     IgFileManager* fileManager = IgFileManager::get (m_state);
00282     if (fileManager) return fileManager;
00283     return new IgFileManager (m_state);
00284 }

Generated on Tue Jun 9 17:39:03 2009 for CMSSW by  doxygen 1.5.4