00001
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
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
00034
00035
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
00043
00044
00045 IG_DEFINE_STATE_ELEMENT (IgServerSocket, "Server socket");
00046
00047
00048
00049
00050
00051 IgServerSocket::IgServerSocket (IgState *state, bool mainPort )
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
00095
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 )
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 }