topical media & game development

talk show tell print

server-proxy-class.php



  <?php
  
  
sourceforge.net/projects/poxy

/* // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // ----------------------------------------------------------------- // Class: PHProxy // Author: ultimategamer00 (Abdullah A.) // Last Modified: 6:28 PM 6/22/2004 */

util(s)


  
  function __stripslashes(str)
  {
      return get_magic_quotes_gpc() ? stripslashes(str) : str;
  }
  
  if (!function_exists('str_rot13'))
  {
      function str_rot13(str)
      {
          static alpha = array('abcdefghijklmnopqrstuvexyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM');
          return strtr(str, alpha[0], alpha[1]);
      }
  }
  
  

class


  
  class PHProxy
  {
      var allowed_hosts = array();
      var version;
      var script_url;
      var url;
      var url_segments;
      var flags = array('include_form' => 0, 'remove_scripts' => 1, 'accept_cookies' => 1, 'show_images' => 1, 'show_referer' => 0);
      var socket;
      var content_type;
      var request_headers;
      var post_body;
      var response_headers;
      var response_body;
  
  

constructor


  
      function PHProxy(flags = 'previous')
      {
          this->version = '0.2';
          this->script_url = 'http' 
                            . (isset(_SERVER['HTTPS']) && _SERVER['HTTPS'] == 'on' ? 's' : '')
                            . "://{_SERVER['HTTP_HOST']}{_SERVER['PHP_SELF']}";
          this->set_flags(flags);
      }
  
  

transfer(s)


  
      function start_transfer(url)
      {
          this->set_url(url);
          this->open_socket();
          this->set_request_headers();
          this->set_response();
  
          if (this->follow_location() === false)
          {
              if (this->flags['accept_cookies'] == 1)
              {
                  this->set_cookies();
              }
              this->set_content_type();
          }
          else
          {
              this->start_transfer(this->url);
          }
      }
  
  

socket


  
      function open_socket()
      {
          this->socket = @fsockopen(this->url_segments['host'], this->url_segments['port'], &errno, &errstr, 5);
  
          if (this->socket === false)
          {
              this->trigger_error("errstr (<b>URL:</b> {this->url_segments['host']})");
          }
      }
  
  

response


  
      function set_response()
      {
          fwrite(this->socket, this->request_headers);
          response = '';
  
          do
          {
              data = fread(this->socket, 8192);
              response .= data;
          }   
          while (strlen(data) != 0);
  
          fclose(this->socket);
          preg_match("#(.*?)\r\n\r\n(.*)#s", response, matches);
  
          this->response_headers = matches[1];
          this->response_body    = matches[2];
      }
  
  

content type


  
      function set_content_type()
      {
          preg_match("#content-type:([^\r\n]*)#i", this->response_headers, matches);
  
          if (trim(matches[1]) != '')
          {
              content_type_array = explode(';', matches[1]);
              this->content_type = strtolower(trim(content_type_array[0]));
          }
      }
  
  

url(s)


  
      function set_url(url)
      {
           this->url = this->decode_url(url);
  
           if (strpos(this->url, '://') === false)
           {
               this->url = '' . this->url;
           }
  
          url_segments = @parse_url(this->url);
          
          if (!empty(url_segments))
          {
              url_segments['port']     = isset(url_segments['port']) ? url_segments['port'] : 80;
              url_segments['path']     = isset(url_segments['path']) ? url_segments['path'] : '/';
              url_segments['dir']      = substr(url_segments['path'], 0, strrpos(url_segments['path'], '/'));
              url_segments['base']     = url_segments['scheme'] . '://' . url_segments['host'] . url_segments['dir'];
              url_segments['prev_dir'] = url_segments['path'] != '/' ? substr(url_segments['base'], 0, strrpos(url_segments['base'], '/')+1) : url_segments['base'] . '/';
  
              this->url_segments = url_segments;
  
              /*
                   URL: username:password@www.example.com:80/dir/dir/page.php?foo=bar&foo2=bar2#bookmark
                   scheme   // http
                   host     // www.example.com
                   port     // 80
                   user     // username
                   pass     // password
                   path     // /dir/dir/page.php
                   query    // ? 'foo=bar&foo2=bar2'
                   fragment // # 'bookmark'
  
                   dir      // /dir/dir
                   base     // www.example.com/dir/dir
                   prev_dir // www.example.com/dir/
               */
  
               if (!empty(this->allowed_hosts) && !in_array(this->url_segments['host'], this->allowed_hosts))
               {
                   this->trigger_error('You are only allowed to browse these websites: ' . implode(', ', this->allowed_hosts));
               }
           }
           else
           {
               this->trigger_error('Please supply a valid URL');
           }
      }
  
  

de/en-code


  
      function encode_url(url)
      {
          url =  str_rot13(urlencode(preg_replace('#^([\w+.-]+)://#i', "$1/", url)));
          return url;
      }
  
      function decode_url(url)
      {
          url = preg_replace('#^([\w+.-]+)/#i', "$1://", urldecode(str_rot13(url)));
          return url;
      }
  
  

modify


  
      function modify_urls()
      {
          preg_match_all("#\s(href|src|action|codebase|url)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", this->response_body, matches, PREG_SET_ORDER);
  
          foreach (matches as match)
          {
              uri = trim(match[3]);
              fragment = (hash_pos = strpos(uri, '#') !== false) ? '#' . substr(uri, hash_pos) : ''; 
  
              if (!preg_match('#^[\w+.-]+://#i', uri))
              {
                  switch (substr(uri, 0, 1))
                  {
                      case '/':
                          uri = this->url_segments['scheme'] . '://' . this->url_segments['host'] . uri;
                          break;
                      case '#':
                          continue 2;
                      default:
                          uri = this->url_segments['base'] . '/' . uri;
                          break;
                  }
              }
  
              uri     = this->encode_url(uri);
              replace = ' ' . match[1] . '=' . match[2] . this->script_url . '?url=' . uri . fragment . match[4] . match[5];
  
              this->response_body = str_replace(match[0], replace, this->response_body);
          }
      }
  
  

flag(s)


  
      function set_flags(flags)
      {
          if (is_numeric(flags))
          {
              setcookie('flags', flags, time()+(4*7*24*60*60), '', _SERVER['HTTP_HOST']); 
              this->flags['include_form']   = flags{0} == 1 ? 1 : 0;
              this->flags['remove_scripts'] = flags{1} == 1 ? 1 : 0;
              this->flags['accept_cookies'] = flags{2} == 1 ? 1 : 0;
              this->flags['show_images']    = flags{3} == 1 ? 1 : 0;
              this->flags['show_referer']   = flags{4} == 1 ? 1 : 0;
          }
          else if (isset(_COOKIE['flags']))
          {
              this->set_flags(_COOKIE['flags']);
          }
      }
  
  

header


  
      function set_request_headers()
      {
          headers  = "{_SERVER['REQUEST_METHOD']} {this->url_segments['path']}" . (isset(this->url_segments['query']) ? "?{this->url_segments['query']}" : '') . " HTTP/1.0\r\n";
          headers .= "Host: {this->url_segments['host']}:{this->url_segments['port']}\r\n";
          headers .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
          headers .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1\r\n";
          headers .= "Connection: close\r\n";
  
          if (this->flags['show_referer'] == 1)
          {
              headers .= "Referer: {this->url_segments['base']}\r\n";
          }
  
          cookies  = this->get_cookies();
          headers .= cookies != '' ? "Cookie: cookies\r\n" : '';
  
          if (_SERVER['REQUEST_METHOD'] == 'POST')
          {
              this->set_post_body(_POST);
  
              headers .= "Content-Type: application/x-www-form-urlencoded\r\n";
              headers .= "Content-Length: " . strlen(this->post_body) . "\r\n\r\n";
              headers .= this->post_body;
          }
  
          headers .= "\r\n";
  
          this->request_headers = headers;
      }
  
  

body


  
      function set_post_body(array, parent_key = null)
      {
          foreach (array as key => value)
          {
              if (is_array(value))
              {
                  this->set_post_body(value, isset(parent_key) ? sprintf('\%s[\%s]', parent_key, urlencode(key)) : urlencode(key));
              }
              else
              {
                  this->post_body .= this->post_body != '' ? '&' : '';
                  key = isset(parent_key) ? sprintf('\%s[\%s]', parent_key, urlencode(key)) : urlencode(key);
                  this->post_body .= key . '=' . urlencode(__stripslashes(value));
              }
          }
       }
  
  

location(s)


  
      function follow_location()
      {
          if (preg_match("#(location|uri):([^\r\n]*)#i", this->response_headers, matches))
          {
              uri = this->decode_url(trim(matches[2]));
  
              if (!preg_match('#^[\w+.-]+://#i', uri))
              {
                  if (substr(uri, 0, 1) == '/')
                  {
                      uri = this->url_segments['scheme'] . '://' . this->url_segments['host'] . uri;
                  }
                  else
                  {
                      uri = this->url_segments['prefix'] . '/' . uri;
                  }
              }
  
              this->url = uri;
              return true;
          }
          return false;
      }
  
  

set cookie(s)


  
      function set_cookies()
      {
          if (preg_match_all("#set-cookie:([^\r\n]*)#i", this->response_headers, matches))
          {
              foreach (matches[1] as match)
              {
                  preg_match('#^\s*([^=;,\s]*)=?([^;,\s]*)#', match, cookie)  ? list(, name, value) = cookie : null;
                  preg_match('#;\s*expires\s*=([^;]*)#i', match, cookie)      ? list(, expires)      = cookie : null;
                  preg_match('#;\s*path\s*=\s*([^;,\s]*)#i', match, cookie)   ? list(, path)         = cookie : null;
                  preg_match('#;\s*domain\s*=\s*([^;,\s]*)#i', match, cookie) ? list(, domain)       = cookie : null;
                  preg_match('#;\s*(secure\b)#i', match, cookie)              ? list(, secure)       = cookie : null;
  
                  expires = isset(expires) ? strtotime(expires) : 0;
                  path    = isset(path)    ? path : this->url_segments['dir'];
                  domain  = isset(domain)  ? domain : this->url_segments['host'];
                  domain  = rtrim(domain, '.');
                  
                  if (!preg_match("#domain#i", this->url_segments['host']))
                  {
                      continue;
                  }
                  if (preg_match('#\.(com|edu|net|org|gov|mil|int|aero|biz|coop|info|museum|name|pro)#i', domain))
                  {
                      if (substr_count(domain, '.') < 2)
                      {
                          continue;
                      }
                  }
                  else if (substr_count(domain, '.') < 3) 
                  {
                      continue;
                  }
                  setcookie(urlencode("PHProxy;name;domain;path"), value, expires, '', _SERVER['HTTP_HOST']);
              }
          }
      }
  
  

get cookie(s)


  
      function get_cookies(restrict = true)
      {
          if (!empty(_COOKIE))
          {
              cookies = '';
  
              foreach (_COOKIE as cookie_name => cookie_value)
              {
                  cookie_args = explode(';', urldecode(cookie_name));
  
                  if (cookie_args[0] != 'PHProxy')
                  {
                      continue;
                  }
  
                  if (restrict)
                  {
                      list(, name, domain, path) = cookie_args;
                      domain = str_replace('_', '.', domain);
  
                      if (preg_match("#domain#i", this->url_segments['host']) && preg_match("#^path#i", this->url_segments['path']))
                      {
                          cookies .= cookies != '' ? '; ' : '';
                          cookies .= "name=cookie_value";
                      }
                  }
                  else
                  {
                      array_shift(cookie_args);
                      cookie_args[1] = str_replace('_', '.', cookie_args[1]);
                      cookie_args[] = cookie_value;
                      cookies[] = cookie_args;
                  }
              }
              return cookies;
          }
      }
  
  

delete cookie(s)


  
      function delete_cookies(hash)
      {
          cookies = this->get_cookies(false);
  
          foreach (cookies as args)
          {
              if (hash == 'all' || hash == md5(args[0].args[1].args[2].args[3]))
              {
                  setcookie(urlencode("PHProxy;args[0];args[1];args[2]"), '', 1);
              }
          }
      }
  
  

response


  
      function return_response(send_headers = true)
      {
          if (strpos(this->content_type, 'text/html') !== false || strpos(this->content_type, 'xhtml') !== false)
          {
              if (this->flags['remove_scripts'] == 1)
              {
                  this->remove_scripts();
              }
              if (this->flags['show_images'] == 0)
              {
                  this->remove_images();
              }
  
              this->modify_urls();
  
              if (this->flags['include_form'] == 1)
              {
                  this->include_form();
              }
          }
          headers   = explode("\r\n", trim(this->response_headers));
          headers[] = 'Content-Disposition: '. (strpos(this->content_type, 'octet_stream') ? 'attachment' : 'inline') .'; filename='. substr(this->url_segments['path'], strrpos(this->url_segments['path'], '/')+1);
          headers[] = 'Content-Length: '. strlen(this->response_body); 
  
          if (send_headers)
          {
              foreach (headers as header)
              {
                  header(header);
              }
          }
  
          return this->response_body;
      }
  
  

script(s)?


  
      function remove_scripts()
      {
          this->response_body = preg_replace('#<script[^>]*?>.*?</script>#si', '', this->response_body); // Remove any scripts enclosed between <script />
          this->response_body = preg_replace("#\s*(\bon\w+)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", "$5", this->response_body); // Remove javascript event handlers
          this->response_body = preg_replace('#<noscript>(.*?)</noscript>#si', "$1", this->response_body); //expose any html between <noscript />
  
      }
  
  

image(s)?


  
      function remove_images()
      {
          this->response_body = preg_replace('#<(img|image)[^>]*?>#si', '', this->response_body);
      }
  
  

form?


  
      function include_form()
      {
          ob_start();
          include_once 'url_form.inc';
          form_html = ob_get_contents();
          ob_end_clean();
          this->response_body = preg_replace("#\<body(.*?)\>#si", "$0\nform_html", this->response_body, 1);
      }
  
  

error(s)


  
      function trigger_error(error)
      {
          header("Location: this->script_url?error=error");
          exit; 
      }
  
  

option(s)


  
      function options_list(tabulate = false, comments_on = false)
      {
          output   = '';
          comments = array();
          comments['include_form']   = 'Includes a mini URL-form on every HTML page';
          comments['remove_scripts'] = 'Remove all sorts of client-side scripting';
          comments['accept_cookies'] = 'Accept HTTP cookies';
          comments['show_images']    = 'Show images';
          comments['show_referer']   = 'Show referring website in HTTP headers';
  
          foreach (this->flags as flag_code => flag_status)
          {
              interface = array(ucwords(str_replace('_', ' ', flag_code)),
                                 ' <input type="checkbox" name="ops[]"'
                                 . (flag_status == 1 ? ' checked="checked"' : '') . ' /> '
                                 );
              tabulate ? null : interface = array_reverse(interface);
              
  
              output .= (tabulate    ? '<tr><td class="option">'  : '') 
                       . interface[0]
                       . (tabulate    ? '</td><td class="option">' : '') 
                       . interface[1]
                       . (comments_on ? comments[flag_code]      : '') 
                       . (tabulate    ? '</td></tr>'               : '');
          }
  
          return output;
      }
  
  }
  
  ?>
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.