SHARE
TWEET

Untitled

a guest Feb 8th, 2014 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. webservermanager.cpp:
  2.  
  3. #include "stdinc.h"
  4. #include "DCPlusPlus.h"
  5.  
  6. #include "WebServerManager.h"
  7.  
  8. #include "QueueManager.h"
  9. #include "FinishedManager.h"
  10. #include "ClientManager.h"
  11. #include "LogManager.h"
  12. #include "StringTokenizer.h"
  13.  
  14. WebServerManager* Singleton<WebServerManager>::instance = NULL;
  15.  
  16. WebServerManager::WebServerManager() : started(false), sended_search(false), hub(-1) {
  17.         SettingsManager::getInstance()->addListener(this);
  18.  
  19.         html_header1 =
  20.                 "<html>\n"
  21.                 "<head>\n"
  22.                 "<title>ZouDC</title>\n"
  23.                 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"
  24.                 ;
  25.         html_header2 =
  26.                 "<link rel=\"stylesheet\" type=\"text/css\" href=\"http://www.123gen.com/monstyle.css\">\n"
  27.                 "<style type=\"text/css\">\n"
  28.                 "body {\n"
  29.                 "text-align: center;\n"
  30.                 "cursor: url(http://www.123gen.com/curseur.ani)\n"
  31.                 "}\n"
  32.                 "td {\n"
  33.                 "text-align: center;\n"
  34.                 "font: x-small Georgia, \"Times New Roman\", Times, serif\n"
  35.                 "}\n"
  36.                 "</style>\n"
  37.                 "</head>\n"
  38.                 "\n"
  39.                 "<body>\n"
  40.                 "<h1><a href=\"index.html\" style=\"color: #FF962D\">Contr&ocirc;le de ZouDC par le web</a></h1>\n"
  41.                 "<font face=\"Georgia, Times New Roman, Times, serif\" size=\"2\"><b>\n"
  42.                 ;
  43.         html_footer =
  44.                 "</blockquote>\n"
  45.                 "</b></font>\n"
  46.                 "</body>\n"
  47.                 "</html>"
  48.                 ;
  49.  
  50.         if(BOOLSETTING(WEBSERVER)) {
  51.                 try {
  52.                         Start();
  53.                 } catch(const Exception&) {     }
  54.         }
  55. }
  56.  
  57. WebServerManager::~WebServerManager() {
  58.         SettingsManager::getInstance()->removeListener(this);
  59.  
  60.         Stop();
  61. }
  62.  
  63. void WebServerManager::Restart() {
  64.         Stop();
  65.         Start();
  66. }
  67.  
  68. string WebServerManager::getLoginPage(bool mauvais_identifiants) {
  69.         string pagehtml =
  70.                 html_header1 +
  71.                 html_header2 +
  72.                 "<blockquote>\n"
  73.                 ;
  74.         if(mauvais_identifiants)
  75.                 pagehtml += "<font color=\"#FF0000\">Mauvais identifiants</font>\n";
  76.         pagehtml +=
  77.                 "<form method=\"post\" action=\"index.html\">\n"
  78.                 "Login :\n"
  79.                 "<input type=\"text\" name=\"login\" size=\"20\"><br>\n"
  80.                 "Passe :\n"
  81.                 "<input type=\"password\" name=\"passe\" size=\"20\"><br>\n"
  82.                 "<input type=\"submit\" value=\"Connexion\">\n"
  83.                 "</form>\n" +
  84.                 html_footer
  85.                 ;
  86.         return
  87.                 "HTTP/1.1 200 OK\r\n"
  88.                 "Content-Type: text/html\r\n"
  89.                 "Content-Length: " + Util::toString((int)pagehtml.size()) + "\r\n"
  90.                 "Connection: close\r\n"
  91.                 "\r\n" +
  92.                 pagehtml
  93.                 ;
  94. }
  95.  
  96. string WebServerManager::getPage(const string& file) {
  97.         string header = "HTTP/1.1 200 OK\r\n", pagehtml = html_header1;
  98.         if(sended_search && (Util::stricmp(file.c_str(), "/rech.htm") == 0))
  99.                 pagehtml += "<meta http-equiv=\"refresh\" content=\"10;URL=rech.htm?stop=true\">";
  100.         bool pas_dans_hub = ((Util::stricmp(file.c_str(), "/hub_.htm") != 0) && (Util::stricmp(file.c_str(), "/chat.htm") != 0));
  101.         if(pas_dans_hub) {
  102.                 pagehtml +=
  103.                         html_header2 +
  104.                         "<a href=\"\"><img src=\"http://www.123gen.com/zoudc/barre.gif\" width=\"216\" height=\"24\" border=\"0\" usemap=\"#Barre\"></a>\n"
  105.                         "<map name=\"Barre\">\n"
  106.                         "<area shape=\"rect\" coords=\"0,0,24,24\" href=\"hubs.htm\" title=\"Hubs\">\n"
  107.                         "<area shape=\"rect\" coords=\"24,0,48,24\" href=\"liste_dl.htm\" title=\"Liste de téléchargement\">\n"
  108.                         "<area shape=\"rect\" coords=\"48,0,72,24\" href=\"dl_finis.htm\" title=\"Téléchargements termin&eacute;s\">\n"
  109.                         "<area shape=\"rect\" coords=\"72,0,96,24\" href=\"ul_finis.htm\" title=\"Envois termin&eacute;s\">\n"
  110.                         "<area shape=\"rect\" coords=\"96,0,120,24\" href=\"rech.htm\" title=\"Recherche\">\n"
  111.                         "<area shape=\"rect\" coords=\"120,0,144,24\" href=\"log.htm\" title=\"Log\">\n"
  112.                         "<area shape=\"rect\" coords=\"144,0,168,24\" href=\"options.htm\" title=\"Options\">\n"
  113.                         "<area shape=\"rect\" coords=\"168,0,192,24\" href=\"arret.htm\" title=\"Arr&ecirc;t automatique\">\n"
  114.                         "<area shape=\"rect\" coords=\"192,0,216,24\" href=\"notepad.htm\" title=\"Bloc-notes\">\n"
  115.                         "</map>\n"
  116.                         "<hr>\n"
  117.                         "<blockquote>\n"
  118.                         ;
  119.         }
  120.         int action_arret = -1;
  121.         if((Util::stricmp(file.c_str(), "/") == 0) || (Util::stricmp(file.c_str(), "/index.html") == 0)) {
  122.                 pagehtml += "Temps de fonctionnement : " + Util::formatSeconds(Util::getUptime()) + "<br>\n";
  123.                 StringList a_afficher = ClientManager::getInstance()->getStats();
  124.                 for(StringIter id_for = a_afficher.begin(); id_for != a_afficher.end(); ++id_for)
  125.                         pagehtml += *id_for + "<br>\n";
  126.         } else if(Util::stricmp(file.c_str(), "/hubs.htm") == 0) {
  127.                 hubs.clear();
  128.                 ClientManager* clientMgr = ClientManager::getInstance();
  129.                 clientMgr->lock();
  130.                 Client::List& clients = clientMgr->getClients();
  131.                 for(Client::Iter i = clients.begin(); i != clients.end(); ++i) {
  132.                         hubs.push_back((*i)->getAddressPort());
  133.                         pagehtml += "<p><a href=\"hub.htm?hub=" + Util::toString(hubs.size() - 1) + "\">" + (*i)->getName() + "</a></p>\n";
  134.                 }
  135.                 clientMgr->unlock();
  136.         } else if(Util::stricmp(file.c_str(), "/hub.htm") == 0) {
  137.                 chat = "";
  138.                 pagehtml +=
  139.                         "</blockquote>\n"
  140.                         "<iframe name=\"cadre_hub_\" width=\"0\" height=\"0\" style=\"display: none; visibility: hidden\"></iframe>\n"
  141.                         "<table width=\"90%\" height=\"50%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
  142.                         "<tr>\n"
  143.                         "<td>\n"
  144.                         "<iframe name=\"cadre_chat\" src=\"chat.htm\" width=\"100%\" height=\"100%\" leftmargin=\"1\" topmargin=\"0\" marginwidth=\"1\" marginheight=\"0\"></iframe>\n"
  145.                         "</td>\n"
  146.                         "<td width=\"200\">\n"
  147.                         "<iframe name=\"cadre_users\" width=\"100%\" height=\"100%\" leftmargin=\"1\" topmargin=\"0\" marginwidth=\"1\" marginheight=\"0\"></iframe>\n"
  148.                         "</td>\n"
  149.                         "</tr>\n"
  150.                         "</table>\n"
  151.                         "<blockquote>\n"
  152.                         "<form name=\"form_envoi\" method=\"post\" action=\"hub_.htm\" target=\"cadre_hub_\" onSubmit=\"submit(); message.value=''; return false\">\n"
  153.                         "<input type=\"text\" name=\"message\" size=\"86\">\n"
  154.                         "<input type=\"submit\" value=\"Envoyer\">\n"
  155.                         "</form>\n"
  156.                         ;
  157.         } else if(Util::stricmp(file.c_str(), "/hub_.htm") == 0) {
  158.                 pagehtml +=
  159.                         "</head>\n"
  160.                         "\n"
  161.                         "<body>\n"
  162.                         "<script language=\"JavaScript\">\n"
  163.                         "with (parent){\n"
  164.                         ;
  165.                 if((hub >= 0) && (hub < (int)hubs.size())) {
  166.                         fire(WebServerListener::CHAT_WEB, hubs[hub]);
  167.                         pagehtml +=
  168.                                 "with (cadre_chat.document){\n"
  169.                                 "body.innerHTML=\"" + chat + "\";\n"
  170.                                 "if (getElementById(\"fin\")){ getElementById(\"fin\").scrollIntoView(); }\n"
  171.                                 "}\n"
  172.                                 "cadre_users.document.body.innerHTML=\"" + users + "\";\n"
  173.                                 "}\n"
  174.                                 "setTimeout(\"location='hub_.htm'\", 1000);\n"
  175.                                 ;
  176.                 } else {
  177.                         pagehtml +=
  178.                                 "cadre_chat.document.body.innerHTML=\"\";\n"
  179.                                 "cadre_users.document.body.innerHTML=\"\";\n"
  180.                                 "}\n"
  181.                                 ;
  182.                 }
  183.                 pagehtml +=
  184.                         "</script>\n"
  185.                         "</body>\n"
  186.                         "</html>"
  187.                         ;
  188.         } else if(Util::stricmp(file.c_str(), "/chat.htm") == 0) {
  189.                 pagehtml +=
  190.                         Util::styles +
  191.                         "</head>\n"
  192.                         "\n"
  193.                         "<body onLoad=\"parent.cadre_hub_.location='hub_.htm'\">\n"
  194.                         "</body>\n"
  195.                         "</html>"
  196.                         ;
  197.         } else if(Util::stricmp(file.c_str(), "/liste_dl.htm") == 0)
  198.                 pagehtml += getDLQueue();
  199.         else if(Util::stricmp(file.c_str(), "/dl_finis.htm") == 0)
  200.                 pagehtml += getFinished(false);
  201.         else if(Util::stricmp(file.c_str(), "/ul_finis.htm") == 0)
  202.                 pagehtml += getFinished(true);
  203.         else if(Util::stricmp(file.c_str(), "/rech.htm") == 0)
  204.                 pagehtml += getSearch();
  205.         else if(Util::stricmp(file.c_str(), "/log.htm") == 0) {
  206.                 pagehtml +=
  207.                         "<p align=\"left\">\n" +
  208.                         fichier_HTML(Util::validateFileName(SETTING(LOG_DIRECTORY) + "Contrôle de ZouDC par le web.log")) +
  209.                         "</p>\n"
  210.                         ;
  211.         } else if(Util::stricmp(file.c_str(), "/options.htm") == 0) {
  212.                 pagehtml +=
  213.                         "<form method=\"get\" action=\"options.htm\">\n"
  214.                         "<input type=\"checkbox\" name=\"deconnexion_lents\""
  215.                         ;
  216.                 if(BOOLSETTING(DISCONNECTING_ENABLE))
  217.                         pagehtml += " checked";
  218.                 pagehtml +=
  219.                         ">Activer la d&eacute;connexion des utilisateurs lents<br>\n"
  220.                         "<input type=\"checkbox\" name=\"limiter\""
  221.                         ;
  222.                 if(BOOLSETTING(THROTTLE_ENABLE))
  223.                         pagehtml += " checked";
  224.                 pagehtml +=
  225.                         ">Limiter la bande passante<br>\n"
  226.                         "<input type=\"submit\" name=\"options\" value=\"Ok !\">\n"
  227.                         "</form>\n"
  228.                         ;
  229.         } else if(Util::stricmp(file.c_str(), "/arret.htm") == 0)
  230.                 pagehtml +=
  231.                 "<p><a href=\"eteindre.htm\">&Eacute;teindre l'ordinateur</a></p>\n"
  232.                 "<p><a href=\"session.htm\">Fermer la session</a></p>\n"
  233.                 "<p><a href=\"redem.htm\">Red&eacute;marrer l'ordinateur</a></p>\n"
  234.                 "<p><a href=\"quitter.htm\">Quitter ZouDC</a></p>\n"
  235.                 ;
  236.         else if(Util::stricmp(file.c_str(), "/eteindre.htm") == 0)
  237.                 action_arret = 0;
  238.         else if(Util::stricmp(file.c_str(), "/session.htm") == 0)
  239.                 action_arret = 1;
  240.         else if(Util::stricmp(file.c_str(), "/redem.htm") == 0)
  241.                 action_arret = 2;
  242.         else if(Util::stricmp(file.c_str(), "/quitter.htm") == 0)
  243.                 action_arret = 3;
  244.         else if(Util::stricmp(file.c_str(), "/notepad.htm") == 0) {
  245.                 pagehtml +=
  246.                         "<p align=\"left\">\n" +
  247.                         fichier_HTML(Util::getAppPath() + "Notepad.txt") +
  248.                         "</p>\n"
  249.                         ;
  250.         } else {
  251.                 header = "HTTP/1.1 404 Not Found\r\n";
  252.                 pagehtml += "Page introuvable\n";
  253.         }
  254.         if(action_arret != -1) {
  255.                 fire(WebServerListener::ARRET, action_arret);
  256.                 pagehtml +=
  257.                         "Demande d'arr&ecirc;t envoy&eacute;e<br>\n"
  258.                         "Temps avant l'arr&ecirc;t : " + Util::toTime(SETTING(SHUTDOWN_TIMEOUT)) + "\n"
  259.                         ;
  260.         }
  261.         if(pas_dans_hub) {
  262.                 pagehtml +=
  263.                         "</blockquote>\n"
  264.                         "<hr>\n"
  265.                         "<blockquote>\n"
  266.                         "<a href=\"javascript:location.reload()\">Rafra&icirc;chir</a> - <a href=\"index.html\">Retour à la page d'accueil</a> - <a href=\"?deconnexion=1\">D&eacute;connexion</a>\n" +
  267.                         html_footer
  268.                         ;
  269.         }
  270.         header +=
  271.                 "Content-Type: text/html\r\n"
  272.                 "Content-Length: " + Util::toString((int)pagehtml.size()) + "\r\n"
  273.                 "Connection: close\r\n"
  274.                 "\r\n"
  275.                 ;
  276.         return header + pagehtml;
  277. }
  278.  
  279. void WebServerManager::search(string search_str, int search_type) {
  280.         if(!sended_search) {
  281.                 int i = 0;
  282.                 while((i = search_str.find("+", i)) != string::npos) {
  283.                         search_str.replace(i, 1, " ");
  284.                         i++;
  285.                 }
  286.                 if((SearchManager::TypeModes)search_type == SearchManager::TYPE_HASH)
  287.                         search_str = "TTH:" + search_str;
  288.                 SearchManager::getInstance()->addListener(this);
  289.                 SearchManager::getInstance()->search(search_str, (SearchManager::TypeModes)search_type);
  290.                 results = Util::emptyString;
  291.                 row = 0;
  292.                 sended_search = true;
  293.         }
  294. }
  295.  
  296. void WebServerManager::reset() {
  297.         row = 0;
  298.         SearchManager::getInstance()->removeListener(this);
  299. }
  300.  
  301. void WebServerManager::Start() {
  302.         if(started)
  303.                 return;
  304.  
  305.         Lock l(cs);
  306.         started = true;
  307.  
  308.         socket.addListener(this);
  309.         socket.waitForConnections((uint16_t)SETTING(WEBSERVER_PORT));
  310.         fire(WebServerListener::SETUP);
  311. }
  312.  
  313. void WebServerManager::Stop() {
  314.         if(!started)
  315.                 return;
  316.  
  317.         started = false;
  318.         Lock l(cs);
  319.  
  320.         socket.removeListener(this);
  321.         socket.disconnect();
  322. }
  323.  
  324. string WebServerManager::getDLQueue() {
  325.         string ret =
  326.                 "</blockquote>\n"
  327.                 "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
  328.                 "<tr>\n"
  329.                 "<td><b>Nom du fichier</b></td>\n"
  330.                 "<td><b>Taille</b></td>\n"
  331.                 "<td><b>T&eacute;l&eacute;charg&eacute;</b></td>\n"
  332.                 "</tr>\n"
  333.                 ;
  334.         const QueueItem::StringMap& li = QueueManager::getInstance()->lockQueue();
  335.         for(QueueItem::StringMap::const_iterator j = li.begin(); j != li.end(); ++j) {
  336.                 QueueItem* aQI = j->second;
  337.                 double percent = (aQI->getSize() > 0) ? aQI->getDownloadedBytes() * 100.0 / aQI->getSize() : 0;
  338.                 ret +=
  339.                         "<tr>\n"
  340.                         "<td>" + aQI->getTargetFileName() + "</td>\n"
  341.                         "<td>" + Util::formatBytes(aQI->getSize()) + "</td>\n"
  342.                         "<td>" + Util::formatBytes(aQI->getDownloadedBytes()) + " (" + Util::toString(percent) + "%)</td>\n"
  343.                         "</tr>\n"
  344.                         ;
  345.         }
  346.         QueueManager::getInstance()->unlockQueue();
  347.         ret +=
  348.                 "</table>\n"
  349.                 "<blockquote>\n"
  350.                 ;
  351.         return ret;
  352. }
  353.  
  354. string WebServerManager::getFinished(bool uploads) {
  355.         string ret =
  356.                 "</blockquote>\n"
  357.                 "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
  358.                 "<tr>\n"
  359.                 "<td><b>Temps</b></td>\n"
  360.                 "<td><b>Fichier</b></td>\n"
  361.                 "<td><b>Taille</b></td>\n"
  362.                 "</tr>\n"
  363.                 ;
  364.         const FinishedItem::List& fl = FinishedManager::getInstance()->lockList(uploads);
  365.         for(FinishedItem::List::const_iterator i = fl.begin(); i != fl.end(); ++i) {
  366.                 ret +=
  367.                         "<tr>\n"
  368.                         "<td>" + Util::formatTime(SETTING(TIMESTAMPS_LOGS), (*i)->getTime()) + "</td>\n"
  369.                         "<td>" + Util::getFileName((*i)->getTarget()) + "</td>\n"
  370.                         "<td>" + Util::formatBytes((*i)->getSize()) + "</td>\n"
  371.                         "</tr>\n"
  372.                         ;
  373.         }
  374.         FinishedManager::getInstance()->unlockList();
  375.         ret +=
  376.                 "</table>\n"
  377.                 "<blockquote>\n"
  378.                 ;
  379.         return ret;
  380. }
  381.  
  382. string WebServerManager::getSearch() {
  383.         string ret = "<form method=\"post\" action=\"rech.htm\" enctype=\"multipart/form-data\">\n";
  384.         if(sended_search) {
  385.                 ret +=
  386.                         "Recherche en cours...<br>\n"
  387.                         "<input type=\"submit\" name=\"stop\" value=\"Arr&ecirc;ter la recherche\">\n"
  388.                         "</form>\n"
  389.                         ;
  390.                 sended_search = false;
  391.         } else {
  392.                 ret +=
  393.                         "Rechercher :\n"
  394.                         "<input type=\"text\" name=\"recherche\" size=\"20\"><br>\n"
  395.                         "<select name=\"type\">\n"
  396.                         "<option value=\"0\" selected>Tous</option>\n"
  397.                         "<option value=\"1\">Audio</option>\n"
  398.                         "<option value=\"2\">Fichier compressé</option>\n"
  399.                         "<option value=\"3\">Document</option>\n"
  400.                         "<option value=\"4\">Programme</option>\n"
  401.                         "<option value=\"5\">Image</option>\n"
  402.                         "<option value=\"6\">Vidéo</option>\n"
  403.                         "<option value=\"7\">Dossier</option>\n"
  404.                         "<option value=\"8\">TTH</option>\n"
  405.                         "</select><br>\n"
  406.                         "<input type=\"submit\" value=\"Recherche\">\n"
  407.                         "</form>\n"
  408.                         ;
  409.                 if(!results.empty()) {
  410.                         ret +=
  411.                                 "</blockquote>\n"
  412.                                 "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
  413.                                 "<tr>\n"
  414.                                 "<td><b>Utilisateur</b></td>\n"
  415.                                 "<td><b>Fichier</b></td>\n"
  416.                                 "<td><b>Taille</b></td>\n"
  417.                                 "<td><b>TTH</b></td>\n"
  418.                                 "</tr>\n" +
  419.                                 results +
  420.                                 "</table>\n"
  421.                                 ;
  422.                 }
  423.                 results = Util::emptyString;
  424.         }
  425.         return ret;
  426. }
  427.  
  428. string WebServerManager::fichier_HTML(const string& chemin) {
  429.         string a_retourner;
  430.         try {
  431.                 a_retourner = File(chemin, File::READ, File::OPEN).read();
  432.         } catch (const FileException&) { }
  433.         if(!a_retourner.empty())
  434.                 Util::remplacer("\r\n", "<br>\n", a_retourner);
  435.         return a_retourner;
  436. }
  437.  
  438. // ServerSocketListener
  439. void WebServerManager::onAction(ServerSocketListener::Types type) throw() {
  440.         if(type == ServerSocketListener::INCOMING_CONNECTION) {
  441.                 WebServerSocket* wss = new WebServerSocket();
  442.                 wss->accept(&socket);
  443.                 wss->start();
  444.         }
  445. }
  446.  
  447. // SettingsManagerListener
  448. void WebServerManager::onAction(SettingsManagerListener::Types type, SimpleXML* /*xml*/) throw() {
  449.         if((type == SettingsManagerListener::LOAD) || (type == SettingsManagerListener::SAVE))
  450.                 BOOLSETTING(WEBSERVER) ? Restart() : Stop();
  451. }
  452.  
  453. // SearchManagerListener
  454. void WebServerManager::onAction(SearchManagerListener::Types type, SearchResult* sr) throw() {
  455.         if(type == SearchManagerListener::SEARCH_RESULT) {
  456.                 {
  457.                         Lock l(cs);
  458.                         if(sr->getType() == SearchResult::TYPE_FILE) {
  459.                                 string TTH = (sr->getTTH() == NULL) ? Util::emptyString : sr->getTTH()->toBase32();
  460.                                 results +=
  461.                                         "<tr style=\"cursor: hand\" onMouseOver=\"this.style.background='#DEFFBD'\" onMouseOut=\"this.style.background=''\" onClick=\"form" + Util::toString(row) + ".submit()\">\n"
  462.                                         "<td>\n"
  463.                                         "<form method=\"post\" name=\"form" + Util::toString(row) + "\" action=\"rech.htm\">\n"
  464.                                         "<input type=\"hidden\" name=\"taille\" value=\"" + Util::toString(sr->getSize()) + "\">\n"
  465.                                         "<input type=\"hidden\" name=\"fichier\" value=\"" + sr->getFileName() + "\">\n"
  466.                                         "<input type=\"hidden\" name=\"tth\" value=\"" + TTH + "\">\n"
  467.                                         "<input type=\"hidden\" name=\"type\" value=\"" + Util::toString(sr->getType()) + "\">\n"
  468.                                         "</form>\n" +
  469.                                         sr->getUser()->getNick() + "\n"
  470.                                         "</td>\n"
  471.                                         "<td>" + sr->getFileName() + "</td>\n"
  472.                                         "<td>" + Util::formatBytes(sr->getSize()) + "</td>\n"
  473.                                         "<td>" + (TTH.empty() ? "Pas de TTH" : "<span title=\"" + TTH + "\">" + TTH.substr(0, 2) + "..." + TTH.substr(TTH.size() - 2) + "</span>") + "</td>\n"
  474.                                         "</tr>\n"
  475.                                         ;
  476.                                 row++;
  477.                         }
  478.                 }
  479.         }
  480. }
  481.  
  482. void WebServerSocket::accept(ServerSocket* s) {
  483.         int fromlen = sizeof(from);
  484.         sock = ::accept(s->getSocket(), (struct sockaddr*)&from, &fromlen);
  485.         u_long b = 1;
  486.         ::ioctlsocket(sock, FIONBIO, &b);
  487. }
  488.  
  489. string WebServerSocket::erreur(const string& contenu) {
  490.         return
  491.                 "HTTP/1.1 " + contenu + "\r\n"
  492.                 "Connection: close\r\n"
  493.                 "\r\n"
  494.                 ;
  495. }
  496.  
  497. StringMap WebServerSocket::getArgs(const string& arguments) {
  498.         StringMap args;
  499.         string::size_type i, j = 0, idx;
  500.         while((i = arguments.find("=", j)) != string::npos) {
  501.                 string key = arguments.substr(j, i - j), value = arguments.substr(i + 1);
  502.                 j = i + 1;
  503.                 if((i = arguments.find("&", j)) != string::npos) {
  504.                         value = arguments.substr(j, i - j);
  505.                         j = i + 1;
  506.                 }
  507.                 for(idx = 0; idx < value.size(); ++idx) {
  508.                         if((value.size() > (idx + 2)) && (value[idx] == '%') && isxdigit(value[idx + 1]) && isxdigit(value[idx + 2])) {
  509.                                 value[idx] = Util::fromHexEscape(value.substr(idx + 1, 2));
  510.                                 value.erase(idx + 1, 2);
  511.                         } else if(value[idx] == '+')
  512.                                 value[idx] = ' ';
  513.                 }
  514.                 args[key] = value;
  515.         }
  516.         return args;
  517. }
  518.  
  519. int WebServerSocket::run() {
  520.         string requete;
  521.         int compteur = 0;
  522.         while(true) {
  523.                 if(++compteur > 10000)
  524.                         break;
  525.                 u_long restants;
  526.                 if(::ioctlsocket(sock, FIONREAD, &restants) == SOCKET_ERROR)
  527.                         continue;
  528.                 if(restants > 0) {
  529.                         char* buffeur = new char[restants + 1];
  530.                         int recus = ::recv(sock, buffeur, restants, 0);
  531.                         if((recus != SOCKET_ERROR) && (recus > 0))
  532.                                 requete.append(buffeur, recus);
  533.                         delete[] buffeur;
  534.                         continue;
  535.                 }
  536.                 if(requete.empty())
  537.                         continue;
  538.                 string::size_type fin = requete.find("\r\n");
  539.                 if(fin == string::npos)
  540.                         continue;
  541.                 string a_envoyer;
  542.                 StringList champs = StringTokenizer(requete.substr(0, fin), ' ').getTokens();
  543.                 if(champs.size() == 3) {
  544.                         if((champs[2] == "HTTP/1.0") || (champs[2] == "HTTP/1.1")) {
  545.                                 bool par_POST = (champs[0] == "POST");
  546.                                 if(par_POST) {
  547.                                         string::size_type debut = requete.find("Content-Length: ");
  548.                                         if(debut == string::npos) {
  549.                                                 if(requete.find("\r\n\r\n") != string::npos)
  550.                                                         a_envoyer = erreur("411 Length Required");
  551.                                                 else
  552.                                                         continue;
  553.                                         } else {
  554.                                                 debut += 16;
  555.                                                 fin = requete.find("\r\n", debut);
  556.                                                 if(fin == string::npos)
  557.                                                         continue;
  558.                                                 if(fin == debut)
  559.                                                         a_envoyer = erreur("400 Bad Request");
  560.                                                 else {
  561.                                                         int64_t content_length = Util::toInt64(requete.substr(debut, fin - debut));
  562.                                                         if(content_length < 0)
  563.                                                                 a_envoyer = erreur("400 Bad Request");
  564.                                                         else {
  565.                                                                 debut = requete.find("\r\n\r\n");
  566.                                                                 if((debut == string::npos) || ((requete.size() - debut - 4) != content_length))
  567.                                                                         continue;
  568.                                                         }
  569.                                                 }
  570.                                         }
  571.                                 }
  572.                                 if((par_POST && a_envoyer.empty()) || (champs[0] == "GET")) {
  573.                                         if(champs[1].empty())
  574.                                                 a_envoyer = erreur("400 Bad Request");
  575.                                         else {
  576.                                                 string IP = Util::toString(from.sin_addr.S_un.S_un_b.s_b1) + '.' + Util::toString(from.sin_addr.S_un.S_un_b.s_b2) + '.' + Util::toString(from.sin_addr.S_un.S_un_b.s_b3) + '.' + Util::toString(from.sin_addr.S_un.S_un_b.s_b4);
  577.  
  578.                                                 if(BOOLSETTING(LOG_WEBSERVER) && (Util::stricmp(champs[1].c_str(), "/hub_.htm") != 0) && (Util::stricmp(champs[1].c_str(), "/chat.htm") != 0))
  579.                                                         LOGDT("Contrôle de ZouDC par le web", IP + " : " + champs[1]);
  580.  
  581.                                                 bool mauvais_identifiants = false;
  582.  
  583.                                                 string::size_type start = par_POST ? requete.rfind("\r\n") : champs[1].find("?");
  584.                                                 if(start != string::npos) {
  585.                                                         StringMap m = getArgs(par_POST ? requete.substr(start + 2) : champs[1].substr(start + 1));
  586.  
  587.                                                         if(par_POST && (!m["login"].empty())) {
  588.                                                                 if((m["login"] == SETTING(WEBSERVER_LOGIN)) && (m["passe"] == SETTING(WEBSERVER_PASSE)))
  589.                                                                         WebServerManager::getInstance()->setLogin_IP(IP);
  590.                                                                 else
  591.                                                                         mauvais_identifiants = true;
  592.                                                         }
  593.  
  594.                                                         if(WebServerManager::getInstance()->getLogin_IP() == IP) {
  595.                                                                 if(!m["deconnexion"].empty())
  596.                                                                         WebServerManager::getInstance()->setLogin_IP("");
  597.  
  598.                                                                 if(!m["recherche"].empty())
  599.                                                                         WebServerManager::getInstance()->search(m["recherche"], Util::toInt(m["type"]));
  600.                                                                 if(!m["stop"].empty())
  601.                                                                         WebServerManager::getInstance()->reset();
  602.                                                                 if(!m["fichier"].empty())
  603.                                                                         QueueManager::getInstance()->add(m["fichier"], Util::toInt64(m["taille"]), m["tth"]);
  604.  
  605.                                                                 if(!m["hub"].empty())
  606.                                                                         WebServerManager::getInstance()->setHub(Util::toInt(m["hub"]));
  607.                                                                 if(!m["message"].empty()) {
  608.                                                                         string hub_courant = WebServerManager::getInstance()->hub_courant();
  609.                                                                         if(!hub_courant.empty())
  610.                                                                                 WebServerManager::getInstance()->fire(WebServerListener::MESSAGE_HUB, hub_courant, m["message"]);
  611.                                                                 }
  612.  
  613.                                                                 if(!m["options"].empty()) {
  614.                                                                         SettingsManager::getInstance()->set(SettingsManager::DISCONNECTING_ENABLE, !m["deconnexion_lents"].empty());
  615.                                                                         SettingsManager::getInstance()->set(SettingsManager::THROTTLE_ENABLE, !m["limiter"].empty());
  616.                                                                         WebServerManager::getInstance()->fire(WebServerListener::LIMITATION, !m["limiter"].empty());
  617.                                                                 }
  618.                                                         }
  619.                                                 }
  620.  
  621.                                                 a_envoyer = (WebServerManager::getInstance()->getLogin_IP() == IP) ? WebServerManager::getInstance()->getPage(par_POST ? champs[1] : champs[1].substr(0, start)) : WebServerManager::getInstance()->getLoginPage(mauvais_identifiants);
  622.                                         }
  623.                                 } else
  624.                                         a_envoyer = erreur("501 Not Implemented");
  625.                         } else
  626.                                 a_envoyer = erreur("505 Version not supported");
  627.                 } else
  628.                         a_envoyer = erreur("400 Bad Request");
  629.                 if(!a_envoyer.empty())
  630.                         ::send(sock, a_envoyer.c_str(), a_envoyer.size(), 0);
  631.                 break;
  632.         }
  633.         ::closesocket(sock);
  634.         delete this;
  635.         return 0;
  636. }
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645. webservermanager.h:
  646.  
  647.  
  648.  
  649. #ifndef ZOUDC_CLIENT_WEBSERVERMANAGER_H
  650. #define ZOUDC_CLIENT_WEBSERVERMANAGER_H
  651.  
  652. #pragma once
  653.  
  654. #include "ServerSocket.h"
  655. #include "SettingsManager.h"
  656. #include "SearchManager.h"
  657.  
  658. class WebServerListener {
  659. public:
  660.         enum Types {
  661.                 SETUP,
  662.                 CHAT_WEB,
  663.                 MESSAGE_HUB,
  664.                 LIMITATION,
  665.                 ARRET
  666.         };
  667.  
  668.         virtual void onAction(Types) throw() { }
  669.         virtual void onAction(Types, const string&) throw() { }
  670.         virtual void onAction(Types, const string&, const string&) throw() { }
  671.         virtual void onAction(Types, bool) throw() { }
  672.         virtual void onAction(Types, int) throw() { }
  673. };
  674.  
  675. class WebServerManager : public Singleton<WebServerManager>, public ServerSocketListener, public Speaker<WebServerListener>, private SettingsManagerListener, private SearchManagerListener
  676. {
  677. private:
  678.         friend Singleton<WebServerManager>;
  679.  
  680.         WebServerManager();
  681.         ~WebServerManager();
  682.  
  683. public:
  684.         void Restart();
  685.  
  686.         string getLoginPage(bool mauvais_identifiants);
  687.         string getPage(const string& file);
  688.  
  689.         void search(string search_str, int search_type);
  690.         void reset();
  691.  
  692.         ServerSocket& getServerSocket() { return socket; }
  693.  
  694.         void setHub(int hub_) { hub = hub_; }
  695.         string hub_courant() { return ((hub >= 0) && (hub < (int)hubs.size())) ? hubs[hub] : ""; }
  696.         void setChat(const string& chat_) { chat = chat_; }
  697.         void setUsers(const string& users_) { users = users_; }
  698.  
  699.         GETSET(string, login_IP, Login_IP);
  700.  
  701. private:
  702.         ServerSocket socket;
  703.  
  704.         string html_header1, html_header2, html_footer;
  705.  
  706.         StringList hubs;
  707.         int hub;
  708.         string chat, users;
  709.  
  710.         bool started, sended_search;
  711.         string results;
  712.  
  713.         int row; // Counter to permit FireFox correct item clicks
  714.  
  715.         CriticalSection cs;
  716.  
  717.         void Start();
  718.         void Stop();
  719.  
  720.         string getDLQueue();
  721.         string getFinished(bool uploads);
  722.         string getSearch();
  723.         string fichier_HTML(const string& chemin);
  724.  
  725.         // ServerSocketListener
  726.         virtual void onAction(ServerSocketListener::Types type) throw();
  727.  
  728.         // SettingsManagerListener
  729.         virtual void onAction(SettingsManagerListener::Types type, SimpleXML* /*xml*/) throw();
  730.  
  731.         // SearchManagerListener
  732.         virtual void onAction(SearchManagerListener::Types type, SearchResult* sr) throw();
  733. };
  734.  
  735. class WebServerSocket : public Thread {
  736. public:
  737.         void accept(ServerSocket* s);
  738.  
  739.         inline string erreur(const string& contenu);
  740.         StringMap getArgs(const string& arguments);
  741.  
  742.         virtual int run();
  743.  
  744. private:
  745.         sockaddr_in from;
  746.         SOCKET sock;
  747. };
  748.  
  749. #endif
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top