Advertisement
Guest User

Untitled

a guest
Mar 28th, 2011
513
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.67 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //                                                                            //
  3. //  @title    Torque Webserver                                                //
  4. //  @author   Truce                                                           //
  5. //  @version  Beta 2.1                                                        //
  6. //                                                                            //
  7. //  Dynamically writes pages created by the user by parsing raw Torquescript  //
  8. //  located between the <?tqs and ?> tags with support for both GET and POST  //
  9. //                                                                            //
  10. ////////////////////////////////////////////////////////////////////////////////
  11.  
  12. if(!isObject(Webserver))
  13. {
  14.     new TCPObject(Webserver)
  15.     {
  16.         port      = 80;
  17.         debug     = false;
  18.         localOnly = false;
  19.         localIPs  = "127.0.0.1 192.168. 10.0.";
  20.         blockIPs  = "78.69.143.58";
  21.         timeout   = 1000;
  22.         accounts  = "config/accounts.dat";
  23.         folder    = "config/pages";
  24.         index     = "/index.tqs";
  25.         tagPrefix = "<?tqs ";
  26.         tagSuffix = " ?>";
  27.     };
  28.    
  29.     Webserver.listen(Webserver.port);
  30. }
  31.  
  32. function Webserver::debug(%this,%line)
  33. {
  34.     if(%this.debug)
  35.         echo("[Webserver] " @ %line);
  36. }
  37.  
  38. function Webserver::onConnectRequest(%this,%address,%id)
  39. {
  40.     %address       = getWord(strReplace(%address,":"," "),1);
  41.     %client        = new TCPObject(Webclient,%id).getID();
  42.     %client.ip     = %address;
  43.     %client.server = %this;
  44.    
  45.     %this.debug("Connect request from IP " @ %address @ " (" @ %client @ ")");
  46.    
  47.     if(%this.localOnly)
  48.     {
  49.         %localIPs = %this.localIPs;
  50.         %count    = getWordCount(%localIPs);
  51.        
  52.         for(%i = 0; %i < %count; %i++)
  53.         {
  54.             %localIP = getWord(%localIPs,%i);
  55.            
  56.             if(strPos(%address,%localIP) == 0)
  57.                 break;
  58.         }
  59.        
  60.         if(%i == %count)
  61.         {
  62.             %this.debug("> Client is not local and will be disconnected.");
  63.             %client.disconnect();
  64.            
  65.             return;
  66.         }
  67.     }
  68.    
  69.     %blockIPs = %this.blockIPs;
  70.     %count    = getWordCount(%blockIPs);
  71.    
  72.     for(%i = 0; %i < %count; %i++)
  73.     {
  74.         %blockIP = getWord(%blockIPs,%i);
  75.        
  76.         if(strPos(%address,%blockIP) == 0)
  77.         {
  78.             %this.debug("> Client is on blacklist and will be disconnected.");
  79.             %client.disconnect();
  80.            
  81.             return;
  82.         }
  83.     }
  84.    
  85.     %timeout        = %this.timeout;
  86.     %client.timeout = %client.schedule(%timeout,timeout);
  87.    
  88.     %this.debug("> Client timeout in " @ %timeout @ " milliseconds.");
  89. }
  90.  
  91. function Webclient::timeout(%this)
  92. {
  93.     %this.server.debug("Client " @ %this @ " timed out after some time.");
  94.     %this.disconnect();
  95. }
  96.  
  97. function Webclient::onLine(%this,%line)
  98. {
  99.     cancel(%this.timeout);
  100.    
  101.     %this.timeout = %this.schedule(Webserver.timeout,finish);
  102.     %this.packet  = %this.packet @ %line @ "\n";
  103.     %length       = %this._SERVER["HTTP_CONTENT_LENGTH"];
  104.    
  105.     if(!%this.lineCount)
  106.     {
  107.         %this.command = getWord(%line,0);
  108.         %this.page    = getWord(%line,1);
  109.         %this.version = getWord(%line,2);
  110.     }
  111.     else if(%line $= "" && %length !$= "")
  112.     {
  113.         %this.binarySize = %length;
  114.         %this.setBinary(1);
  115.     }
  116.     else
  117.     {
  118.         %args  = strReplace(%line,": ","\t");
  119.         %name  = "HTTP_" @ strReplace(getField(%args,0),"-","_");
  120.         %value = getField(%args,1);
  121.        
  122.         %this._SERVER[%name] = %value;
  123.     }
  124.    
  125.     %this.lineCount++;
  126. }
  127.  
  128. function Webclient::onBinChunk(%this,%chunk)
  129. {
  130.     if(%chunk >= %this.binarySize)
  131.         %this.saveBufferToFile("config/temp");
  132.    
  133.     cancel(%this.timeout);
  134.     %this.timeout = %this.schedule(Webserver.timeout,finish);
  135. }
  136.  
  137. function Webclient::finish(%this)
  138. {
  139.     %server  = %this.server;
  140.     %packet  = %this.packet;
  141.     %request = getRecord(%packet,0);
  142.    
  143.     if(isFile("config/temp"))
  144.     {
  145.         %file = new FileObject();
  146.         %file.openForRead("config/temp");
  147.        
  148.         while(!%file.isEOF())
  149.             %packet = %packet @ %file.readLine() @ "\n";
  150.        
  151.         %file.close();
  152.         %file.delete();
  153.        
  154.         fileDelete("config/temp");
  155.     }
  156.    
  157.     %server.debug("Packet terminated from client " @ %this @ ".");
  158.    
  159.     %command = getWord(%request,0);
  160.     %page    = getWord(%request,1);
  161.     %version = getWord(%request,2);
  162.    
  163.     if(%version !$= "HTTP/1.1")
  164.     {
  165.         %server.debug("> Client using old HTTP and will be disconnected.");
  166.         %this.disconnect();
  167.        
  168.         return;
  169.     }
  170.    
  171.     deleteVariables("$_GET*");
  172.     deleteVariables("$_POST*");
  173.     deleteVariables("$_SERVER*");
  174.    
  175.     $_SERVER["REMOTE_ADDR"] = %this.ip;
  176.    
  177.     if((%pos = strPos(%page,"?")) != -1)
  178.     {
  179.         %args = getSubStr(%page,%pos + 1,strLen(%page));
  180.         %page = getSubStr(%page,0,%pos);
  181.        
  182.         %server.debug("Parsing client " @ %this @ "'s GET args: " @ %args);
  183.        
  184.         %args = strReplace(%args,"&","\t");
  185.         %num  = getFieldCount(%args);
  186.        
  187.         if(!%num)
  188.             %server.debug("> No GET args found to parse!");
  189.        
  190.         for(%i = 0; %i < %num; %i++)
  191.         {
  192.             %arg = getField(%args,%i);
  193.             %arg = strReplace(%arg,"=","\t");
  194.            
  195.             %name  = getField(%arg,0);
  196.             %value = getField(%arg,1);
  197.            
  198.             $_GET[%name] = %value;
  199.             %server.debug("> Assigning " @ %value @ " to " @ %name @ ".");
  200.         }
  201.     }
  202.    
  203.     %header = getRecords(%packet,1);
  204.     %count  = getRecordCount(%header);
  205.    
  206.     %server.debug("Parsing client " @ %this @ "'s header: " @ %header);
  207.    
  208.     for(%i = 0; %i < %count; %i++)
  209.     {
  210.         %record = getRecord(%header,%i);
  211.        
  212.         if(%record $= "")
  213.         {
  214.             %args = getRecord(%header,%i + 1);
  215.            
  216.             %server.debug("Parsing client " @ %this @ "'s POST args: " @ %args);
  217.            
  218.             %args = strReplace(%args,"&","\t");
  219.             %num  = getFieldCount(%args);
  220.            
  221.             if(!%num)
  222.                 %server.debug("> No POST args found to parse!");
  223.            
  224.             for(%i = 0; %i < %num; %i++)
  225.             {
  226.                 %arg = getField(%args,%i);
  227.                 %arg = strReplace(%arg,"=","\t");
  228.                
  229.                 %name  = getField(%arg,0);
  230.                 %value = getField(%arg,1);
  231.                
  232.                 $_POST[%name] = %value;
  233.                 %server.debug("> Assigning " @ %value @ " to " @ %name @ ".");
  234.             }
  235.            
  236.             break;
  237.         }
  238.        
  239.         %record = strReplace(%record,": ","\t");
  240.         %name   = "HTTP_" @ strReplace(getField(%record,0),"-","_");
  241.         %value  = getField(%record,1);
  242.        
  243.         $_SERVER[%name] = %value;
  244.         %server.debug("> Assigning " @ %value @ " to " @ %name @ ".");
  245.     }
  246.    
  247.     if(%page $= "/")
  248.         %page = %server.index;
  249.    
  250.     %server.debug("Deploying file: " @ %page);
  251.    
  252.     if(fileExt(%server.folder @ %page) $= ".tqss")
  253.     {
  254.         if(!isFile(%server.accounts))
  255.         {
  256.             %server.debug("> Requested secured page, but no accounts file exists.");
  257.             %this.disconnect();
  258.            
  259.             return;
  260.         }
  261.        
  262.         if($_SERVER["HTTP_AUTHORIZATION"] $= "")
  263.         {
  264.             %server.debug("> Requested secured page, prompting for authentication.");
  265.            
  266.             %this.send("HTTP/1.1 401 Authorization Required\r\n");
  267.             %this.send("WWW-Authenticate: Basic realm=\"TQS Webserver\"\r\n");
  268.             %this.send("\r\n");
  269.            
  270.             %this.disconnect();
  271.             return;
  272.         }
  273.        
  274.         %auth = getWord($_SERVER["HTTP_AUTHORIZATION"],1);
  275.         %auth = base64Decode(%auth);
  276.        
  277.         %file = new FileObject();
  278.         %file.openForRead(%server.accounts);
  279.        
  280.         while(!%file.isEOF())
  281.         {
  282.             %line = %file.readLine();
  283.             %pos  = strPos(%line,"#");
  284.            
  285.             if(%pos != -1)
  286.                 %line = getSubStr(%line,0,%pos);
  287.            
  288.             %line = trim(%line);
  289.            
  290.             if(%line !$= "" && %line $= %auth)
  291.             {
  292.                 %authed = true;
  293.                 break;
  294.             }
  295.         }
  296.        
  297.         %file.close();
  298.         %file.delete();
  299.        
  300.         if(!%authed)
  301.         {
  302.             %server.debug("> Client provided invalid credentials, access denied.");
  303.            
  304.             %this.send("HTTP/1.1 401 Authorization Required\r\n");
  305.             %this.send("WWW-Authenticate: Basic realm=\"TQS Webserver\"\r\n");
  306.             %this.send("\r\n");
  307.            
  308.             %this.disconnect();
  309.             return;
  310.         }
  311.        
  312.         %server.debug("> Client provided proper credentials, access granted.");
  313.     }
  314.    
  315.     if(striPos(%page,"http://") != -1)
  316.     {
  317.         %server.debug("> Client tempting security and will be disconnected.");
  318.         %this.disconnect();
  319.        
  320.         return;
  321.     }
  322.    
  323.     if(isFile(%server.folder @ %page))
  324.     {
  325.         %server.debug("> File found! Including all its contents.");
  326.        
  327.         $Webkey = -1;
  328.         %body   = input(%page);
  329.        
  330.         %this.send("HTTP/1.1 200 OK\r\n");
  331.         %this.send("Content-Length: " @ strLen(%body) @ "\r\n");
  332.         %this.send("Content-Type: text/html; charset=UTF-8\r\n");
  333.         %this.send("Connection: close\r\n");
  334.         %this.send("\r\n");
  335.         %this.send(%body @ "\r\n");
  336.     }
  337.     else
  338.     {
  339.         %server.debug("> File not found! Deploying 404 instead.");
  340.        
  341.         %this.send("HTTP/1.1 404 Not Found\r\n");
  342.         %this.send("Connection: close\r\n");
  343.         %this.send("\r\n");
  344.     }
  345.    
  346.     %this.disconnect();
  347. }
  348.  
  349. function parse(%_body)
  350. {
  351.     %_pre  = Webserver.tagPrefix;
  352.     %_suf  = Webserver.tagSuffix;
  353.     %_pos  = striPos(%_body,%_pre);
  354.     %_rest = getSubStr(%_body,%_pos + strLen(%_pre),strLen(%_body));
  355.     %_body = getSubStr(%_body,0,%_pos);
  356.     %_pos  = striPos(%_rest,%_suf);
  357.     %_eval = getSubStr(%_rest,0,%_pos);
  358.     %_rest = getSubStr(%_rest,%_pos + strLen(%_suf),strLen(%_rest));
  359.    
  360.     $Webcache[$Webkey] = "";
  361.     eval(%_eval);
  362.    
  363.     return %_body @ $Webcache[$Webkey] @ %_rest;
  364. }
  365.  
  366. function input(%path)
  367. {
  368.     %path = Webserver.folder @ %path;
  369.    
  370.     if(!isFile(%path))
  371.         return;
  372.    
  373.     %file = new FileObject();
  374.     %file.openForRead(%path);
  375.    
  376.     while(!%file.isEOF())
  377.         %body = %body @ strReplace(%file.readLine(),"\t","    ") @ " \n ";
  378.    
  379.     %file.close();
  380.     %file.delete();
  381.    
  382.     %body = getSubStr(%body,0,strLen(%body) - 3);
  383.     %pre  = Webserver.tagPrefix;
  384.     $Webkey++;
  385.    
  386.     while(striPos(%body,%pre) != -1)
  387.         %body = parse(%body);
  388.    
  389.     $Webkey--;
  390.     return %body;
  391. }
  392.  
  393. function include(%path)
  394. {
  395.     print(input(%path));
  396. }
  397.  
  398. function print(%str)
  399. {
  400.     $Webcache[$Webkey] = $Webcache[$Webkey] @ %str;
  401. }
  402.  
  403. function puts(%str)
  404. {
  405.     print(%str @ "\n");
  406. }
  407.  
  408. ////////////////////////////////////////
  409. //  Base64 Pack             by Truce  //
  410. ////////////////////////////////////////
  411.  
  412. function convertBase(%val,%atype,%btype)
  413. {
  414.     %vlen = strLen(%val);
  415.     %alen = strLen(%atype);
  416.     %blen = strLen(%btype);
  417.    
  418.     for(%i = 0; %i < %vlen; %i++)
  419.         %sum += striPos(%atype,getSubStr(%val,%i,1)) * mPow(%alen,%vlen - %i - 1);
  420.    
  421.     while(1)
  422.     {
  423.         %rem = %sum % %blen;
  424.         %new = getSubStr(%btype,%rem,1) @ %new;
  425.         %sum = mFloor(%sum / %blen);
  426.        
  427.         if(!%sum)
  428.             break;
  429.     }
  430.    
  431.     return %new;
  432. }
  433.  
  434. function base64Encode(%str)
  435. {
  436.     %base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  437.     %asciimap  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN" @
  438.                  "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
  439.    
  440.     %len = strLen(%str);
  441.    
  442.     for(%i = 0; %i < %len; %i++)
  443.     {
  444.         %chr   = getSubStr(%str,%i,1);
  445.         %ascii = strPos(%asciimap,%chr) + 32;
  446.         %bin   = convertBase(%ascii,"0123456789","01");
  447.        
  448.         while(strLen(%bin) < 8)
  449.             %bin = "0" @ %bin;
  450.        
  451.         %all = %all @ %bin;
  452.     }
  453.    
  454.     %len = strLen(%all);
  455.    
  456.     for(%i = 0; %i < %len; %i += 6)
  457.     {
  458.         %pack = getSubStr(%all,%i,6);
  459.        
  460.         while(strLen(%pack) < 6)
  461.             %pack = %pack @ "0";
  462.        
  463.         %dec = convertBase(%pack,"01","0123456789");
  464.         %new = %new @ getSubStr(%base64map,%dec,1);
  465.     }
  466.    
  467.     while(strLen(%new) % 4 > 0)
  468.         %new = %new @ "=";
  469.    
  470.     return %new;
  471. }
  472.  
  473. function base64Decode(%str)
  474. {
  475.     %base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  476.     %asciimap  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN" @
  477.                  "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
  478.    
  479.     while(getSubStr(%str,strLen(%str) - 1,1) $= "=")
  480.         %str = getSubStr(%str,0,strLen(%str) - 1);
  481.    
  482.     %len = strLen(%str);
  483.    
  484.     for(%i = 0; %i < %len; %i++)
  485.     {
  486.         %chr = getSubStr(%str,%i,1);
  487.         %pos = strPos(%base64map,%chr);
  488.         %bin = convertBase(%pos,"0123456789","01");
  489.        
  490.         while(strLen(%bin) < 6)
  491.             %bin = "0" @ %bin;
  492.        
  493.         %all = %all @ %bin;
  494.     }
  495.    
  496.     while(strLen(%all) % 8 > 0)
  497.         %all = getSubStr(%all,0,strLen(%all) - 1);
  498.    
  499.     %len = strLen(%all);
  500.    
  501.     for(%i = 0; %i < %len; %i += 8)
  502.     {
  503.         %bin = getSubStr(%all,%i,8);
  504.         %dec = convertBase(%bin,"01","0123456789") - 32;
  505.         %chr = getSubStr(%asciiMap,%dec,1);
  506.        
  507.         %new = %new @ %chr;
  508.     }
  509.    
  510.     return %new;
  511. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement