Archivo de la categoría ‘PHP’

Modificar el tiempo de vida de una sesión en php

Martes, 8 de Junio de 2010

Las sesiones en php tienen múltiples usos, el más habitual, el de mantener activo un usuario logueado. En la mayoría de configuraciones de php el SID se propaga mediante cookies, por lo que para modificar el tiempo de vida de una sesión debe usarse la directiva session.cookie_lifetime.

Por ejemplo, para setear sesiones de dos minutos:

ini_set(”session.cookie_lifetime”,120);  //El tiempo viene dado en segundos

Además, será necesario combinarlo con el valor gc_maxlifetime para que el recolector de basura de php no elimine la cookie antes de su expiración.

Siguiendo el ejemplo de los dos minutos, deberíamos inicar lo siguiente:

ini_set(”session.gc_maxlifetime”, 120);

Por último, recordar que estos parámetros deben cambiarse antes de la instrucción session_start(); que es la que nos seteará la cookie en el caso de que ésta no estuviera ya en servidor.

Importante: Es posible que intentéis modificar este tiempo y os de la sensación de que no funciona. Hay que tener en cuenta que es posible que hayáis modificado el código pero vuestro equipo siga teniendo una cookie activa, por lo que hasta que no caduque la anterior no se os guardará la nueva con el tiempo de vida actualizado. Lo mejor para hacer pruebas es disponer de una herramienta como web developer toolbar que os permitirá controlar las cookies, pudiendo eliminar la antigua y comprobar que el código funciona correctamente.

Problema strtoupper con acentos

Viernes, 4 de Diciembre de 2009

Si en PHP queremos pasar un String con acentos, diéresi o diferentes letras de codificación UTF-8 a mayúsculas, directamente no podemos utilizar

PHP:
  1. $var = strtoupper($valor);

ya que transformará a mayúsculas únicamente las letras del abecedario simple (sin contar ñ ni ç).

La forma correcta de cubrir todos los casos es:

PHP:
  1. $var =   mb_strtoupper($valor,'utf-8');

Aprender hacer expresiones regulares para quitar los tags de un texto en php

Jueves, 19 de Noviembre de 2009

Para eliminar los tags de un texto, ya sea en php o javascript o cualquier otro lenguaje, vamos a utiizar expresiones regulares.

la ideal para tags es:  .<[^>]+>.

Para aprender a como funcionan las expresiones regulares, podemos utilizar un simuladro muy bueno, que nos permite probar "in the fly", en tiempo real. Si la expressión regular es válida o hace lo que queremos.

Para ello te deja poner un texto donde reconocer y la expressión.

El sitio es:  regexpal.com

dedicado a luis.

allow memory en phpmyadmin al importar una BD

Martes, 27 de Octubre de 2009

Cuando importamos una base de datos grande y lo queremos hacer desde el PHPMYADMIN, puede ser que nos de un error de que no tiene memoria suficiente.

Para solucionarlo, si tenemos acceso al servidor. Podemos incrementar la memoria máxima de ejecución y el tiempo de ejecucución de los escripts php en generar desde el php.ini (el fichero de configuración de php)

Si el servidor está montado sobre un S.O. Linux, el ejemplo en concreto es sobre ubuntu

la ruta del fichero será /etc/php5/apache2/php.ini

Dentro del fichero buscar "Resource Limits":

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

max_execution_time = 60 ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request data
;max_input_nesting_level = 64 ; Maximum input variable nesting level
;memory_limit = 16M      ; Maximum amount of memory a script may consume (16MB) ; Por defecto
memory_limit = 128M ; Maximum amount of memory a script may consume (16MB)

Ahí dentro, modificar las lineas en negrita (memory_limit y max_execution_time ) por los valores acordes a la importación que vaya hacer y la memoria disponible en el servidor.

despues reiniciar el apache para que surja efecto:

sudo /etc/init.d/apache2 restart

Una vez importada la bd es recomendabe volver a dejar el fichero como estaba.

Imprimir directo desde ms-dos. Tickets desde php bajo Windows

Jueves, 10 de Septiembre de 2009

Hace tiempo solventamos la impresión desde php a impresora de tickets bajo Linux mediante este método

Ahora tenemos la problemática de hacer lo mismo desde Windows. Existe la extensión printer pero nos interesa reutilizar la mayor parte del código, en este caso el cuerpo del ticket, para que las versiones bajo Windows y Linux difieran el mínimo posible.

Bien, siguiendo el mismo método necesitamos imprimir un fichero previamente generado desde php directamente desde consola (en este caso mediante comandos ms-dos). Ms-dos y las impresoras usb no se llevan bien, así que toca hacer un pequeño "apaño". Mapear el puerto LPT1 a un puerto de impresión de red con nuestra impresora previamente compartida en red. Estos son los pasos:

1) Nos asegurarnos de tener, al menos, una interfaz de red. En caso de no tener ninguna podemos añadir un adaptador ficticio, como "Adaptador de bucle invertido de Microsoft" y asignarle una IP.

2) Compartimos la impresora (que por cierto, debe ser sólo texto) en red. Recordamos el nombre que le asignamos como recurso compartido.

3) Mapeamos el puerto desde ms-dos con el siguiente comando: NET USE LPT1: \\[nombre_en_red_de_la_maquina]\[nombre_impresora] /PERSISTENT:YES

4) Ahora desde php ya podemos imprimir el fichero que queramos con: shell_exec('type nombre_fichero>lpt1');

Con un pequeño if que detecte el sistema operativo en que está instalado php podemos tener un sistema de impresión de tickets multiplataforma. Eso si, con nuestra intervención para mapear el puerto.

Dar permisos de administrador en phpbb 3

Lunes, 11 de Mayo de 2009

La "nueva" versión del popular foro trae una revisión profunda del panel de aministración. Me he encontrado con una instalación sin permisos por defecto. Aquí un recordatorio para poder acceder a foros y administrarlos:

  • Después de crear un nuevo foro, se deben asignar permisos: ACP/Foros/Permisos de foros. En esta pantalla, lo más cómodo es añadir permisos de grupos
  • Dar permisos de moderador a un usuario: ACP/Usuarios y grupos/Administrar grupos. Clicar sobre "usuarios" en el grupo de Moderadores globales y añadir usuarios.

Usado en amicsdelsclassics.com.

Enviar cookies o variables post desde file_get_contents() php

Miércoles, 25 de Febrero de 2009

Queremos hacer una petición de una página web externa, a la que necesitamos pasarle unos parámetros post y además una cookie con información adicional como el id de session.

la forma facil es mediante la función de php:

PHP:
  1. file_get_contents('http://webexterna.com/fichero.php',false,$contexto);

En el último parámetro que es el contexto, se le puede enviar información adicional. como el tipo de peticion http ( GET o POST), el protocolo (http o https), variables post, un parámetro de cookies.

el ejemplo completo sería:

PHP:
  1. $opciones = array('http' =>
  2.     array(
  3.         'method'  => 'GET',
  4.         'header'  => 'Content-type: text/plain;charset=UTF-8\r\n'.
  5.         'Referer: http://www.webanterior\r\n'.
  6.         'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6\r\n'.
  7.         'Cookie: variableCookie1=valorCookie1; variablecookie2=valor2; variablecookie3=valor3; SESSIONID=TkddJlDQnk7vKKj7KvcKptGRJKgrhv4yKHZNTVdttdfqWKtG1LdT!;\r\n'
  8.     )
  9. );
  10.  
  11. $contexto  = stream_context_create($opciones); //crea el contexto para el stream
  12. $resultado = file_get_contents('http://www.webexterna.com/fichero.asp', false, $contexto);

Puedes ver mas opciones de como usar los contextos en php en: context php
ejemplo de la funcion stream_context_create en php

Otra manera sería usando una librería tipo curl, o una clase como Snoopy, una clase diseñada para enviar formularios post. Os la añado que cuesta de encontrar por google. tiene un nombre demasiado comun.

PHP:
  1. /*************************************************
  2. Snoopy - the PHP net client
  3. Author: Monte Ohrt <monte@ispi.net>
  4. Copyright (c): 1999-2000 ispi, all rights reserved
  5. Version: 1.01
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. You may contact the author of Snoopy by e-mail at:
  20. monte@ispi.net
  21. Or, write to:
  22. Monte Ohrt
  23. CTO, ispi
  24. 237 S. 70th suite 220
  25. Lincoln, NE 68510
  26. The latest version of Snoopy can be obtained from:
  27. http://snoopy.sourceforge.net/
  28. *************************************************/
  29.  
  30. class Snoopy
  31. {
  32.     /**** Public variables ****/
  33.    
  34.     /* user definable vars */
  35.  
  36.     var $host         =  "www.dominio.com";        // host name we are connecting to
  37.     var $port         =  80;               // port we are connecting to
  38.     var $proxy_host  =    "";     // proxy host to use
  39.     var $proxy_port  =    "";     // proxy port to use
  40.     var $proxy_user  =    "";     // proxy user to use
  41.     var $proxy_pass  =    "";     // proxy password to use
  42.    
  43.     var $agent      = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16"// agent we masquerade as
  44.     var $referer  =    "";     // referer info to pass
  45.     var $cookies        =   array();         // array of cookies to pass
  46.                                                 // $cookies["username"]="joe";
  47.     var $rawheaders    = array();   // array of raw headers to send
  48.                                                 // $rawheaders["Content-type"]="text/html";
  49.  
  50.     var $maxredirs    = 5;               // http redirection depth maximum. 0 = disallow
  51.     var $lastredirectaddr   =  "";            // contains address of last redirected address
  52.     var $offsiteok      =  true;    // allows redirection off-site
  53.     var $maxframes    = 0;               // frame content depth maximum. 0 = disallow
  54.     var $expandlinks    =   true;        // expand links to fully qualified URLs.
  55.                                                 // this only applies to fetchlinks()
  56.                                                 // submitlinks(), and submittext()
  57.     var $passcookies    =   true;        // pass set cookies back through redirects
  58.                                                 // NOTE: this currently does not respect
  59.                                                 // dates, domains or paths.
  60.    
  61.     var $user            =   "";                    // user for http authentication
  62.     var $pass            =   "";                    // password for http authentication
  63.    
  64.     // http accept types
  65.     var $accept   =    "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  66.    
  67.     var $results        =   "";                    // where the content is put
  68.        
  69.     var $error      = "";          // error messages sent here
  70.     var $response_code   =  "";               // response code returned from server
  71.     var $headers  =    array();            // headers returned from server sent here
  72.     var $maxlength      =  500000;            // max return data length (body)
  73.     var $read_timeout   =  0;                    // timeout on read operations, in seconds
  74.                                                 // supported only since PHP 4 Beta 4
  75.                                                 // set to 0 to disallow timeouts
  76.     var $timed_out    = false;            // if a read operation timed out
  77.     var $status      = 0;               // http request status
  78.  
  79.     var $temp_dir      =  "/tmp";            // temporary directory that the webserver
  80.                                                 // has permission to write to.
  81.                                                 // under Windows, this should be C:\temp
  82.  
  83.     var $curl_path      =  "/usr/local/bin/curl";
  84.                                                 // Snoopy will use cURL for fetching
  85.                                                 // SSL content if a full system path to
  86.                                                 // the cURL binary is supplied here.
  87.                                                 // set to false if you do not have
  88.                                                 // cURL installed. See http://curl.haxx.se
  89.                                                 // for details on installing cURL.
  90.                                                 // Snoopy does *not* use the cURL
  91.                                                 // library functions built into php,
  92.                                                 // as these functions are not stable
  93.                                                 // as of this Snoopy release.
  94.    
  95.     /**** Private variables ****/   
  96.    
  97.     var $_maxlinelen =    4096;            // max line length (headers)
  98.    
  99.     var $_httpmethod    =   "GET";    // default http request method
  100.     var $_httpversion   =  "HTTP/1.0";         // default http request version
  101.     var $_submit_method =    "POST";    // default submit method
  102.     var $_submit_type   =  'multipart/form-data'; //"application/x-www-form-urlencoded"; // default submit type
  103.     var $_mime_boundary =   "application/octet-stream";          // MIME boundary for multipart/form-data submit type
  104.     var $_redirectaddr  = false;            // will be set if page fetched is a redirect
  105.     var $_redirectdepth =    0;          // increments on an http redirect
  106.     var $_frameurls  =    array();         // frame src urls
  107.     var $_framedepth    =   0;     // increments on frame depth
  108.    
  109.     var $_isproxy      =  false;                // set if using a proxy server
  110.     var $_fp_timeout    =   30;                    // timeout for socket connection
  111.  
  112. /*======================================================================*\
  113.     Function:   fetch
  114.     Purpose:    fetch the contents of a web page
  115.                 (and possibly other protocols in the
  116.                 future like ftp, nntp, gopher, etc.)
  117.     Input:    $URI  the location of the page to fetch
  118.     Output:  $this->results   the output text from the fetch
  119. \*======================================================================*/
  120.  
  121.     function fetch($URI)
  122.     {
  123.    
  124.         //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
  125.         $URI_PARTS = parse_url($URI);
  126.         if (!empty($URI_PARTS["user"]))
  127.             $this->user = $URI_PARTS["user"];
  128.         if (!empty($URI_PARTS["pass"]))
  129.             $this->pass = $URI_PARTS["pass"];
  130.         if (empty($URI_PARTS["query"]))
  131.             $URI_PARTS["query"] = '';
  132.         if (empty($URI_PARTS["path"]))
  133.             $URI_PARTS["path"] = '';
  134.                
  135.         switch(strtolower($URI_PARTS["scheme"]))
  136.         {
  137.             case "http":
  138.                 $this->host = $URI_PARTS["host"];
  139.                 if(!empty($URI_PARTS["port"]))
  140.                     $this->port = $URI_PARTS["port"];
  141.                 if($this->_connect($fp))
  142.                 {
  143.                     if($this->_isproxy)
  144.                     {
  145.                         // using proxy, send entire URI
  146.                         $this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
  147.                     }
  148.                     else
  149.                     {
  150.                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  151.                         // no proxy, send only the path
  152.                         $this->_httprequest($path, $fp, $URI, $this->_httpmethod);
  153.                     }
  154.                    
  155.                     $this->_disconnect($fp);
  156.  
  157.                     if($this->_redirectaddr)
  158.                     {
  159.                         /* url was redirected, check if we've hit the max depth */
  160.                         if($this->maxredirs> $this->_redirectdepth)
  161.                         {
  162.                             // only follow redirect if it's on this site, or offsiteok is true
  163.                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  164.                             {
  165.                                 /* follow the redirect */
  166.                                 $this->_redirectdepth++;
  167.                                 $this->lastredirectaddr=$this->_redirectaddr;
  168.                                 $this->fetch($this->_redirectaddr);
  169.                             }
  170.                         }
  171.                     }
  172.  
  173.                     if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  174.                     {
  175.                         $frameurls = $this->_frameurls;
  176.                         $this->_frameurls = array();
  177.                        
  178.                         while(list(,$frameurl) = each($frameurls))
  179.                         {
  180.                             if($this->_framedepth <$this->maxframes)
  181.                             {
  182.                                 $this->fetch($frameurl);
  183.                                 $this->_framedepth++;
  184.                             }
  185.                             else
  186.                                 break;
  187.                         }
  188.                     }               
  189.                 }
  190.                 else
  191.                 {
  192.                     return false;
  193.                 }
  194.                 return true;                   
  195.                 break;
  196.             case "https":
  197.                 if(!$this->curl_path)
  198.                     return false;
  199.                 if(function_exists("is_executable"))
  200.                     if (!is_executable($this->curl_path))
  201.                         return false;
  202.                 $this->host = $URI_PARTS["host"];
  203.                 if(!empty($URI_PARTS["port"]))
  204.                     $this->port = $URI_PARTS["port"];
  205.                 if($this->_isproxy)
  206.                 {
  207.                     // using proxy, send entire URI
  208.                     $this->_httpsrequest($URI,$URI,$this->_httpmethod);
  209.                 }
  210.                 else
  211.                 {
  212.                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  213.                     // no proxy, send only the path
  214.                     $this->_httpsrequest($path, $URI, $this->_httpmethod);
  215.                 }
  216.  
  217.                 if($this->_redirectaddr)
  218.                 {
  219.                     /* url was redirected, check if we've hit the max depth */
  220.                     if($this->maxredirs> $this->_redirectdepth)
  221.                     {
  222.                         // only follow redirect if it's on this site, or offsiteok is true
  223.                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  224.                         {
  225.                             /* follow the redirect */
  226.                             $this->_redirectdepth++;
  227.                             $this->lastredirectaddr=$this->_redirectaddr;
  228.                             $this->fetch($this->_redirectaddr);
  229.                         }
  230.                     }
  231.                 }
  232.  
  233.                 if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  234.                 {
  235.                     $frameurls = $this->_frameurls;
  236.                     $this->_frameurls = array();
  237.  
  238.                     while(list(,$frameurl) = each($frameurls))
  239.                     {
  240.                         if($this->_framedepth <$this->maxframes)
  241.                         {
  242.                             $this->fetch($frameurl);
  243.                             $this->_framedepth++;
  244.                         }
  245.                         else
  246.                             break;
  247.                     }
  248.                 }               
  249.                 return true;                   
  250.                 break;
  251.             default:
  252.                 // not a valid protocol
  253.                 $this->error    =   'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
  254.                 return false;
  255.                 break;
  256.         }      
  257.         return true;
  258.     }
  259.  
  260. /*======================================================================*\
  261.     Function:   submit
  262.     Purpose:    submit an http form
  263.     Input:    $URI  the location to post the data
  264.                 $formvars   the formvars to use.
  265.                     format: $formvars["var"] = "val";
  266.                 $formfiles  an array of files to submit
  267.                     format: $formfiles["var"] = "/dir/filename.ext";
  268.     Output:  $this->results   the text output from the post
  269. \*======================================================================*/
  270.  
  271.     function submit($URI, $formvars="", $formfiles="")
  272.     {
  273.         unset($postdata);
  274. /*    Añadir cookies manualmente
  275.         $this->cookies["PHPSESSID"]='755a7835f6c772e36dc5c3d50d7c142c';
  276.         $this->cookies["autentificado"]='si';
  277.         $this->cookies["correo"]='tucorreo@gmail.com';
  278.         $this->cookies["id"]='2233';
  279.         $this->cookies["usuario"]='';
  280.     */ 
  281.        
  282.         $postdata = $this->_prepare_post_body($formvars, $formfiles);
  283.            
  284.         $URI_PARTS = parse_url($URI);
  285.         if (!empty($URI_PARTS["user"]))
  286.             $this->user = $URI_PARTS["user"];
  287.         if (!empty($URI_PARTS["pass"]))
  288.             $this->pass = $URI_PARTS["pass"];
  289.         if (empty($URI_PARTS["query"]))
  290.             $URI_PARTS["query"] = '';
  291.         if (empty($URI_PARTS["path"]))
  292.             $URI_PARTS["path"] = '';
  293.  
  294.         switch(strtolower($URI_PARTS["scheme"]))
  295.         {
  296.             case "http":
  297.                 $this->host = $URI_PARTS["host"];
  298.                 if(!empty($URI_PARTS["port"]))
  299.                     $this->port = $URI_PARTS["port"];
  300.                 if($this->_connect($fp))
  301.                 {
  302.                     if($this->_isproxy)
  303.                     {
  304.                         // using proxy, send entire URI
  305.                         $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata);
  306.                     }
  307.                     else
  308.                     {
  309.                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  310.                         // no proxy, send only the path
  311.                         $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  312.                     }
  313.                    
  314.                     $this->_disconnect($fp);
  315.  
  316.                     if($this->_redirectaddr)
  317.                     {
  318.                         /* url was redirected, check if we've hit the max depth */
  319.                         if($this->maxredirs> $this->_redirectdepth)
  320.                         {                  
  321.                             if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
  322.                                 $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);      
  323.                            
  324.                             // only follow redirect if it's on this site, or offsiteok is true
  325.                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  326.                             {
  327.                                 /* follow the redirect */
  328.                                 $this->_redirectdepth++;
  329.                                 $this->lastredirectaddr=$this->_redirectaddr;
  330.                                 if( strpos( $this->_redirectaddr, "?" )> 0 )
  331.                                     $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
  332.                                 else
  333.                                     $this->submit($this->_redirectaddr,$formvars, $formfiles);
  334.                             }
  335.                         }
  336.                     }
  337.  
  338.                     if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  339.                     {
  340.                         $frameurls = $this->_frameurls;
  341.                         $this->_frameurls = array();
  342.                        
  343.                         while(list(,$frameurl) = each($frameurls))
  344.                         {                                          
  345.                             if($this->_framedepth <$this->maxframes)
  346.                             {
  347.                                 $this->fetch($frameurl);
  348.                                 $this->_framedepth++;
  349.                             }
  350.                             else
  351.                                 break;
  352.                         }
  353.                     }               
  354.                    
  355.                 }
  356.                 else
  357.                 {
  358.                     return false;
  359.                 }
  360.                 return true;                   
  361.                 break;
  362.             case "https":
  363.                 if(!$this->curl_path)
  364.                     return false;
  365.                 if(function_exists("is_executable"))
  366.                     if (!is_executable($this->curl_path))
  367.                         return false;
  368.                 $this->host = $URI_PARTS["host"];
  369.                 if(!empty($URI_PARTS["port"]))
  370.                     $this->port = $URI_PARTS["port"];
  371.                 if($this->_isproxy)
  372.                 {
  373.                     // using proxy, send entire URI
  374.                     $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  375.                 }
  376.                 else
  377.                 {
  378.                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  379.                     // no proxy, send only the path
  380.                     $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  381.                 }
  382.  
  383.                 if($this->_redirectaddr)
  384.                 {
  385.                     /* url was redirected, check if we've hit the max depth */
  386.                     if($this->maxredirs> $this->_redirectdepth)
  387.                     {                  
  388.                         if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
  389.                             $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);      
  390.  
  391.                         // only follow redirect if it's on this site, or offsiteok is true
  392.                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  393.                         {
  394.                             /* follow the redirect */
  395.                             $this->_redirectdepth++;
  396.                             $this->lastredirectaddr=$this->_redirectaddr;
  397.                             if( strpos( $this->_redirectaddr, "?" )> 0 )
  398.                                 $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
  399.                             else
  400.                                 $this->submit($this->_redirectaddr,$formvars, $formfiles);
  401.                         }
  402.                     }
  403.                 }
  404.  
  405.                 if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  406.                 {
  407.                     $frameurls = $this->_frameurls;
  408.                     $this->_frameurls = array();
  409.  
  410.                     while(list(,$frameurl) = each($frameurls))
  411.                     {                                          
  412.                         if($this->_framedepth <$this->maxframes)
  413.                         {
  414.                             $this->fetch($frameurl);
  415.                             $this->_framedepth++;
  416.                         }
  417.                         else
  418.                             break;
  419.                     }
  420.                 }               
  421.                 return true;                   
  422.                 break;
  423.                
  424.             default:
  425.                 // not a valid protocol
  426.                 $this->error    =   'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
  427.                 return false;
  428.                 break;
  429.         }      
  430.         return true;
  431.     }
  432.  
  433. /*======================================================================*\
  434.     Function:   fetchlinks
  435.     Purpose:    fetch the links from a web page
  436.     Input:    $URI  where you are fetching from
  437.     Output:  $this->results   an array of the URLs
  438. \*======================================================================*/
  439.  
  440.     function fetchlinks($URI)
  441.     {
  442.         if ($this->fetch($URI))
  443.         {         
  444.             if($this->lastredirectaddr)
  445.                 $URI = $this->lastredirectaddr;
  446.             if(is_array($this->results))
  447.             {
  448.                 for($x=0;$x<count($this->results);$x++)
  449.                     $this->results[$x] = $this->_striplinks($this->results[$x]);
  450.             }
  451.             else
  452.                 $this->results = $this->_striplinks($this->results);
  453.  
  454.             if($this->expandlinks)
  455.                 $this->results = $this->_expandlinks($this->results, $URI);
  456.             return true;
  457.         }
  458.         else
  459.             return false;
  460.     }
  461.  
  462. /*======================================================================*\
  463.     Function:   fetchform
  464.     Purpose:    fetch the form elements from a web page
  465.     Input:    $URI  where you are fetching from
  466.     Output:  $this->results   the resulting html form
  467. \*======================================================================*/
  468.  
  469.     function fetchform($URI)
  470.     {
  471.        
  472.         if ($this->fetch($URI))
  473.         {         
  474.  
  475.             if(is_array($this->results))
  476.             {
  477.                 for($x=0;$x<count($this->results);$x++)
  478.                     $this->results[$x] = $this->_stripform($this->results[$x]);
  479.             }
  480.             else
  481.                 $this->results = $this->_stripform($this->results);
  482.            
  483.             return true;
  484.         }
  485.         else
  486.             return false;
  487.     }
  488.    
  489.    
  490. /*======================================================================*\
  491.     Function:   fetchtext
  492.     Purpose:    fetch the text from a web page, stripping the links
  493.     Input:    $URI  where you are fetching from
  494.     Output:  $this->results   the text from the web page
  495. \*======================================================================*/
  496.  
  497.     function fetchtext($URI)
  498.     {
  499.         if($this->fetch($URI))
  500.         {         
  501.             if(is_array($this->results))
  502.             {
  503.                 for($x=0;$x<count($this->results);$x++)
  504.                     $this->results[$x] = $this->_striptext($this->results[$x]);
  505.             }
  506.             else
  507.                 $this->results = $this->_striptext($this->results);
  508.             return true;
  509.         }
  510.         else
  511.             return false;
  512.     }
  513.  
  514. /*======================================================================*\
  515.     Function:   submitlinks
  516.     Purpose:    grab links from a form submission
  517.     Input:    $URI  where you are submitting from
  518.     Output:  $this->results   an array of the links from the post
  519. \*======================================================================*/
  520.  
  521.     function submitlinks($URI, $formvars="", $formfiles="")
  522.     {
  523.         if($this->submit($URI,$formvars, $formfiles))
  524.         {         
  525.             if($this->lastredirectaddr)
  526.                 $URI = $this->lastredirectaddr;
  527.             if(is_array($this->results))
  528.             {
  529.                 for($x=0;$x<count($this->results);$x++)
  530.                 {
  531.                     $this->results[$x] = $this->_striplinks($this->results[$x]);
  532.                     if($this->expandlinks)
  533.                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
  534.                 }
  535.             }
  536.             else
  537.             {
  538.                 $this->results = $this->_striplinks($this->results);
  539.                 if($this->expandlinks)
  540.                     $this->results = $this->_expandlinks($this->results,$URI);
  541.             }
  542.             return true;
  543.         }
  544.         else
  545.             return false;
  546.     }
  547.  
  548. /*======================================================================*\
  549.     Function:   submittext
  550.     Purpose:    grab text from a form submission
  551.     Input:    $URI  where you are submitting from
  552.     Output:  $this->results   the text from the web page
  553. \*======================================================================*/
  554.  
  555.     function submittext($URI, $formvars = "", $formfiles = "")
  556.     {
  557.         if($this->submit($URI,$formvars, $formfiles))
  558.         {         
  559.             if($this->lastredirectaddr)
  560.                 $URI = $this->lastredirectaddr;
  561.             if(is_array($this->results))
  562.             {
  563.                 for($x=0;$x<count($this->results);$x++)
  564.                 {
  565.                     $this->results[$x] = $this->_striptext($this->results[$x]);
  566.                     if($this->expandlinks)
  567.                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
  568.                 }
  569.             }
  570.             else
  571.             {
  572.                 $this->results = $this->_striptext($this->results);
  573.                 if($this->expandlinks)
  574.                     $this->results = $this->_expandlinks($this->results,$URI);
  575.             }
  576.             return true;
  577.         }
  578.         else
  579.             return false;
  580.     }
  581.  
  582.    
  583.  
  584. /*======================================================================*\
  585.     Function:   set_submit_multipart
  586.     Purpose:    Set the form submission content type to
  587.                 multipart/form-data
  588. \*======================================================================*/
  589.     function set_submit_multipart()
  590.     {
  591.         $this->_submit_type = "multipart/form-data";
  592.     }
  593.  
  594.    
  595. /*======================================================================*\
  596.     Function:   set_submit_normal
  597.     Purpose:    Set the form submission content type to
  598.                 application/x-www-form-urlencoded
  599. \*======================================================================*/
  600.     function set_submit_normal()
  601.     {
  602.         $this->_submit_type = "application/x-www-form-urlencoded";
  603.     }
  604.  
  605.    
  606.    
  607.  
  608. /*======================================================================*\
  609.     Private functions
  610. \*======================================================================*/
  611.    
  612.    
  613. /*======================================================================*\
  614.     Function:   _striplinks
  615.     Purpose:    strip the hyperlinks from an html document
  616.     Input:    $document document to strip.
  617.     Output:  $match      an array of the links
  618. \*======================================================================*/
  619.  
  620.     function _striplinks($document)
  621.     {   
  622.         preg_match_all("'<\s*a\s.*?href\s*=\s*      # find <a href=
  623.                         ([\"\'])?               # find single or double quote
  624.                         (?(1) (.*?)\\1 | ([^\s\>]+))        # if quote found, match up to next matching
  625.                                                     # quote, otherwise match up to next space
  626.                         'isx",$document,$links);
  627.                        
  628.  
  629.         // catenate the non-empty matches from the conditional subpattern
  630.  
  631.         while(list($key,$val) = each($links[2]))
  632.         {
  633.             if(!empty($val))
  634.                 $match[] = $val;
  635.         }            
  636.        
  637.         while(list($key,$val) = each($links[3]))
  638.         {
  639.             if(!empty($val))
  640.                 $match[] = $val;
  641.         }      
  642.        
  643.         // return the links
  644.         return $match;
  645.     }
  646.  
  647. /*======================================================================*\
  648.     Function:   _stripform
  649.     Purpose:    strip the form elements from an html document
  650.     Input:    $document document to strip.
  651.     Output:  $match      an array of the links
  652. \*======================================================================*/
  653.  
  654.     function _stripform($document)
  655.     {   
  656.         preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
  657.        
  658.         // catenate the matches
  659.         $match = implode("\r\n",$elements[0]);
  660.                
  661.         // return the links
  662.         return $match;
  663.     }
  664.  
  665.    
  666.    
  667. /*======================================================================*\
  668.     Function:   _striptext
  669.     Purpose:    strip the text from an html document
  670.     Input:    $document document to strip.
  671.     Output:  $text        the resulting text
  672. \*======================================================================*/
  673.  
  674.     function _striptext($document)
  675.     {
  676.        
  677.         // I didn't use preg eval (//e) since that is only available in PHP 4.0.
  678.         // so, list your entities one by one here. I included some of the
  679.         // more common ones.
  680.                                
  681.         $search = array("'<script[^>]*?>.*?</script>'si",   // strip out javascript
  682.                         "'<[\/\!]*?[^<>]*?>'si",            // strip out html tags
  683.                         "'([\r\n])[\s]+'",          // strip out white space
  684.                         "'&(quot|#34|#034|#x22);'i",        // replace html entities
  685.                         "'&(amp|#38|#038|#x26);'i",   // added hexadecimal values
  686.                         "'&(lt|#60|#060|#x3c);'i",
  687.                         "'&(gt|#62|#062|#x3e);'i",
  688.                         "'&(nbsp|#160|#xa0);'i",
  689.                         "'&(iexcl|#161);'i",
  690.                         "'&(cent|#162);'i",
  691.                         "'&(pound|#163);'i",
  692.                         "'&(copy|#169);'i",
  693.                         "'&(reg|#174);'i",
  694.                         "'&(deg|#176);'i",
  695.                         "'&(#39|#039|#x27);'",
  696.                         "'&(euro|#8364);'i",                // europe
  697.                         "'&a(uml|UML);'",               // german
  698.                         "'&o(uml|UML);'",
  699.                         "'&u(uml|UML);'",
  700.                         "'&A(uml|UML);'",
  701.                         "'&O(uml|UML);'",
  702.                         "'&U(uml|UML);'",
  703.                         "'&szlig;'i",
  704.                         );
  705.         $replace = array(   "",
  706.                             "",
  707.                             "\\1",
  708.                             "\"",
  709.                             "&",
  710.                             "<",
  711.                             ">",
  712.                             " ",
  713.                             chr(161),
  714.                             chr(162),
  715.                             chr(163),
  716.                             chr(169),
  717.                             chr(174),
  718.                             chr(176),
  719.                             chr(39),
  720.                             chr(128),
  721.                             "?",
  722.                             "?",
  723.                             "?",
  724.                             "?",
  725.                             "?",
  726.                             "?",
  727.                             "?",
  728.                         );
  729.                    
  730.         $text = preg_replace($search,$replace,$document);
  731.                                
  732.         return $text;
  733.     }
  734.  
  735. /*======================================================================*\
  736.     Function:   _expandlinks
  737.     Purpose:    expand each link into a fully qualified URL
  738.     Input:    $links            the links to qualify
  739.                 $URI            the full URI to get the base from
  740.     Output:  $expandedLinks   the expanded links
  741. \*======================================================================*/
  742.  
  743.     function _expandlinks($links,$URI)
  744.     {
  745.        
  746.         preg_match("/^[^\?]+/",$URI,$match);
  747.  
  748.         $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]);
  749.         $match = preg_replace("|/$|","",$match);
  750.         $match_part = parse_url($match);
  751.         $match_root =
  752.         $match_part["scheme"]."://".$match_part["host"];
  753.                
  754.         $search = array(    "|^http://".preg_quote($this->host)."|i",
  755.                             "|^(\/)|i",
  756.                             "|^(?!http://)(?!mailto:)|i",
  757.                             "|/\./|",
  758.                             "|/[^\/]+/\.\./|"
  759.                         );
  760.                        
  761.         $replace = array(   "",
  762.                             $match_root."/",
  763.                             $match."/",
  764.                             "/",
  765.                             "/"
  766.                         );     
  767.                
  768.         $expandedLinks = preg_replace($search,$replace,$links);
  769.  
  770.         return $expandedLinks;
  771.     }
  772.  
  773. /*======================================================================*\
  774.     Function:   _httprequest
  775.     Purpose:    go get the http data from the server
  776.     Input:    $url    the url to fetch
  777.                 $fp   the current open file pointer
  778.                 $URI        the full URI
  779.                 $body      body contents to send if any (POST)
  780.     Output:  
  781. \*======================================================================*/
  782.    
  783.     function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
  784.     {
  785.         $cookie_headers = '';
  786.         if($this->passcookies && $this->_redirectaddr)
  787.             $this->setcookies();
  788.            
  789.         $URI_PARTS = parse_url($URI);
  790.         if(empty($url))
  791.             $url = "/";
  792.         $headers = $http_method." ".$url." ".$this->_httpversion."\r\n";       
  793.         if(!empty($this->agent))
  794.             $headers .= "User-Agent: ".$this->agent."\r\n";
  795.         if(!empty($this->host) && !isset($this->rawheaders['Host'])) {
  796.             $headers .= "Host: ".$this->host;
  797.             if(!empty($this->port))
  798.                 $headers .= ":".$this->port;
  799.             $headers .= "\r\n";
  800.         }
  801.         if(!empty($this->accept))
  802.             $headers .= "Accept: ".$this->accept."\r\n";
  803.         if(!empty($this->referer))
  804.             $headers .= "Referer: ".$this->referer."\r\n";
  805.         if(!empty($this->cookies))
  806.         {         
  807.             if(!is_array($this->cookies))
  808.                 $this->cookies = (array)$this->cookies;
  809.    
  810.             reset($this->cookies);
  811.             if ( count($this->cookies)> 0 ) {
  812.                 $cookie_headers .= 'Cookie: ';
  813.                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
  814.                 $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
  815.                 }
  816.                 $headers .= substr($cookie_headers,0,-2) . "\r\n";
  817.             }
  818.         }
  819.         if(!empty($this->rawheaders))
  820.         {
  821.             if(!is_array($this->rawheaders))
  822.                 $this->rawheaders = (array)$this->rawheaders;
  823.             while(list($headerKey,$headerVal) = each($this->rawheaders))
  824.                 $headers .= $headerKey.": ".$headerVal."\r\n";
  825.         }
  826.         if(!empty($content_type)) {
  827.             $headers .= "Content-type: $content_type";
  828.             if ($content_type == "multipart/form-data")
  829.                 $headers .= "; boundary=".$this->_mime_boundary;
  830.             $headers .= "\r\n";
  831.         }
  832.         if(!empty($body))   
  833.             $headers .= "Content-length: ".strlen($body)."\r\n";
  834.         if(!empty($this->user) || !empty($this->pass)) 
  835.             $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n";
  836.        
  837.         //add proxy auth headers
  838.         if(!empty($this->proxy_user))   
  839.             $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n";
  840.  
  841.  
  842.         $headers .= "\r\n";
  843.        
  844.         // set the read timeout if needed
  845.         if ($this->read_timeout> 0)
  846.             socket_set_timeout($fp, $this->read_timeout);
  847.         $this->timed_out = false;
  848.        
  849.         fwrite($fp,$headers.$body,strlen($headers.$body));
  850.        
  851.         $this->_redirectaddr = false;
  852.         unset($this->headers);
  853.                        
  854.         while($currentHeader = fgets($fp,$this->_maxlinelen))
  855.         {
  856.             if ($this->read_timeout> 0 && $this->_check_timeout($fp))
  857.             {
  858.                 $this->status=-100;
  859.                 return false;
  860.             }
  861.                
  862.             if($currentHeader == "\r\n")
  863.                 break;
  864.                        
  865.             // if a header begins with Location: or URI:, set the redirect
  866.             if(preg_match("/^(Location:|URI:)/i",$currentHeader))
  867.             {
  868.                 // get URL portion of the redirect
  869.                 preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches);
  870.                 // look for :// in the Location header to see if hostname is included
  871.                 if(!preg_match("|\:\/\/|",$matches[2]))
  872.                 {
  873.                     // no host in the path, so prepend
  874.                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
  875.                     // eliminate double slash
  876.                     if(!preg_match("|^/|",$matches[2]))
  877.                             $this->_redirectaddr .= "/".$matches[2];
  878.                     else
  879.                             $this->_redirectaddr .= $matches[2];
  880.                 }
  881.                 else
  882.                     $this->_redirectaddr = $matches[2];
  883.             }
  884.        
  885.             if(preg_match("|^HTTP/|",$currentHeader))
  886.             {
  887.                 if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
  888.                 {
  889.                     $this->status= $status[1];
  890.                 }            
  891.                 $this->response_code = $currentHeader;
  892.             }
  893.                
  894.             $this->headers[] = $currentHeader;
  895.         }
  896.  
  897.         $results = '';
  898.         do {
  899.             $_data = fread($fp, $this->maxlength);
  900.             if (strlen($_data) == 0) {
  901.                 break;
  902.             }
  903.             $results .= $_data;
  904.         } while(true);
  905.  
  906.         if ($this->read_timeout> 0 && $this->_check_timeout($fp))
  907.         {
  908.             $this->status=-100;
  909.             return false;
  910.         }
  911.        
  912.         // check if there is a a redirect meta tag
  913.        
  914.         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
  915.  
  916.         {
  917.             $this->_redirectaddr = $this->_expandlinks($match[1],$URI)
  918.         }
  919.  
  920.         // have we hit our frame depth and is there frame src to fetch?
  921.         if(($this->_framedepth <$this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
  922.         {
  923.             $this->results[] = $results;
  924.             for($x=0; $x<count($match[1]); $x++)
  925.                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
  926.         }
  927.         // have we already fetched framed content?
  928.         elseif(is_array($this->results))
  929.             $this->results[] = $results;
  930.         // no framed content
  931.         else
  932.             $this->results = $results;
  933.        
  934.         return true;
  935.     }
  936.  
  937. /*======================================================================*\
  938.     Function:   _httpsrequest
  939.     Purpose:    go get the https data from the server using curl
  940.     Input:    $url    the url to fetch
  941.                 $URI        the full URI
  942.                 $body      body contents to send if any (POST)
  943.     Output:  
  944. \*======================================================================*/
  945.    
  946.     function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
  947.     {
  948.         if($this->passcookies && $this->_redirectaddr)
  949.             $this->setcookies();
  950.  
  951.         $headers = array();  
  952.                    
  953.         $URI_PARTS = parse_url($URI);
  954.         if(empty($url))
  955.             $url = "/";
  956.         // GET ... header not needed for curl
  957.         //$headers[] = $http_method." ".$url." ".$this->_httpversion;      
  958.         if(!empty($this->agent))
  959.             $headers[] = "User-Agent: ".$this->agent;
  960.         if(!empty($this->host))
  961.             if(!empty($this->port))
  962.                 $headers[] = "Host: ".$this->host.":".$this->port;
  963.             else
  964.                 $headers[] = "Host: ".$this->host;
  965.         if(!empty($this->accept))
  966.             $headers[] = "Accept: ".$this->accept;
  967.         if(!empty($this->referer))
  968.             $headers[] = "Referer: ".$this->referer;
  969.         if(!empty($this->cookies))
  970.         {         
  971.             if(!is_array($this->cookies))
  972.                 $this->cookies = (array)$this->cookies;
  973.    
  974.             reset($this->cookies);
  975.             if ( count($this->cookies)> 0 ) {
  976.                 $cookie_str = 'Cookie: ';
  977.                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
  978.                 $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; ";
  979.                 }
  980.                 $headers[] = substr($cookie_str,0,-2);
  981.             }
  982.         }
  983.         if(!empty($this->rawheaders))
  984.         {
  985.             if(!is_array($this->rawheaders))
  986.                 $this->rawheaders = (array)$this->rawheaders;
  987.             while(list($headerKey,$headerVal) = each($this->rawheaders))
  988.                 $headers[] = $headerKey.": ".$headerVal;
  989.         }
  990.         if(!empty($content_type)) {
  991.             if ($content_type == "multipart/form-data")
  992.                 $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary;
  993.             else
  994.                 $headers[] = "Content-type: $content_type";
  995.         }
  996.         if(!empty($body))   
  997.             $headers[] = "Content-length: ".strlen($body);
  998.         if(!empty($this->user) || !empty($this->pass)) 
  999.             $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
  1000.            
  1001.         for($curr_header = 0; $curr_header <count($headers); $curr_header++) {
  1002.             $safer_header = strtr( $headers[$curr_header], "\"", " " );
  1003.             $cmdline_params .= " -H \"".$safer_header."\"";
  1004.         }
  1005.        
  1006.         if(!empty($body))
  1007.             $cmdline_params .= " -d \"$body\"";
  1008.        
  1009.         if($this->read_timeout> 0)
  1010.             $cmdline_params .= " -m ".$this->read_timeout;
  1011.        
  1012.         //$headerfile = tempnam($temp_dir, "sno");
  1013.         $headerfile = tempnam($this->temp_dir, "sno");
  1014.  
  1015.         $safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access
  1016.         exec($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\"",$results,$return);
  1017.        
  1018.         if($return)
  1019.         {
  1020.             $this->error = "Error: cURL could not retrieve the document, error $return.";
  1021.             return false;
  1022.         }
  1023.            
  1024.            
  1025.         $results = implode("\r\n",$results);
  1026.        
  1027.         $result_headers = file("$headerfile");
  1028.                        
  1029.         $this->_redirectaddr = false;
  1030.         unset($this->headers);
  1031.                        
  1032.         for($currentHeader = 0; $currentHeader <count($result_headers); $currentHeader++)
  1033.         {
  1034.            
  1035.             // if a header begins with Location: or URI:, set the redirect
  1036.             if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
  1037.             {
  1038.                 // get URL portion of the redirect
  1039.                 preg_match("/^(Location: |URI:)\s+(.*)/",chop($result_headers[$currentHeader]),$matches);
  1040.                 // look for :// in the Location header to see if hostname is included
  1041.                 if(!preg_match("|\:\/\/|",$matches[2]))
  1042.                 {
  1043.                     // no host in the path, so prepend
  1044.                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
  1045.                     // eliminate double slash
  1046.                     if(!preg_match("|^/|",$matches[2]))
  1047.                             $this->_redirectaddr .= "/".$matches[2];
  1048.                     else
  1049.                             $this->_redirectaddr .= $matches[2];
  1050.                 }
  1051.                 else
  1052.                     $this->_redirectaddr = $matches[2];
  1053.             }
  1054.        
  1055.             if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
  1056.                 $this->response_code = $result_headers[$currentHeader];
  1057.  
  1058.             $this->headers[] = $result_headers[$currentHeader];
  1059.         }
  1060.  
  1061.         // check if there is a a redirect meta tag
  1062.        
  1063.         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
  1064.         {
  1065.             $this->_redirectaddr = $this->_expandlinks($match[1],$URI)
  1066.         }
  1067.  
  1068.         // have we hit our frame depth and is there frame src to fetch?
  1069.         if(($this->_framedepth <$this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
  1070.         {
  1071.             $this->results[] = $results;
  1072.             for($x=0; $x<count($match[1]); $x++)
  1073.                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
  1074.         }
  1075.         // have we already fetched framed content?
  1076.         elseif(is_array($this->results))
  1077.             $this->results[] = $results;
  1078.         // no framed content
  1079.         else
  1080.             $this->results = $results;
  1081.  
  1082.         unlink("$headerfile");
  1083.        
  1084.         return true;
  1085.     }
  1086.  
  1087. /*======================================================================*\
  1088.     Function:   setcookies()
  1089.     Purpose:    set cookies for a redirection
  1090. \*======================================================================*/
  1091.    
  1092.     function setcookies()
  1093.     {
  1094.         for($x=0; $x<count($this->headers); $x++)
  1095.         {
  1096.         if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))
  1097.             $this->cookies[$match[1]] = urldecode($match[2]);
  1098.         }
  1099.     }
  1100.  
  1101.    
  1102. /*======================================================================*\
  1103.     Function:   _check_timeout
  1104.     Purpose:    checks whether timeout has occurred
  1105.     Input:    $fp   file pointer
  1106. \*======================================================================*/
  1107.  
  1108.     function _check_timeout($fp)
  1109.     {
  1110.         if ($this->read_timeout> 0) {
  1111.             $fp_status = socket_get_status($fp);
  1112.             if ($fp_status["timed_out"]) {
  1113.                 $this->timed_out = true;
  1114.                 return true;
  1115.             }
  1116.         }
  1117.         return false;
  1118.     }
  1119.  
  1120. /*======================================================================*\
  1121.     Function:   _connect
  1122.     Purpose:    make a socket connection
  1123.     Input:    $fp   file pointer
  1124. \*======================================================================*/
  1125.    
  1126.     function _connect(&$fp)
  1127.     {
  1128.         if(!empty($this->proxy_host) && !empty($this->proxy_port))
  1129.             {
  1130.                 $this->_isproxy = true;
  1131.                
  1132.                 $host = $this->proxy_host;
  1133.                 $port = $this->proxy_port;
  1134.             }
  1135.         else
  1136.         {
  1137.             $host = $this->host;
  1138.             $port = $this->port;
  1139.         }
  1140.    
  1141.         $this->status = 0;
  1142.        
  1143.         if($fp = fsockopen(
  1144.                     $host,
  1145.                     $port,
  1146.                     $errno,
  1147.                     $errstr,
  1148.                     $this->_fp_timeout
  1149.                     ))
  1150.         {
  1151.             // socket connection succeeded
  1152.  
  1153.             return true;
  1154.         }
  1155.         else
  1156.         {
  1157.             // socket connection failed
  1158.             $this->status = $errno;
  1159.             switch($errno)
  1160.             {
  1161.                 case -3:
  1162.                     $this->error="socket creation failed (-3)";
  1163.                 case -4:
  1164.                     $this->error="dns lookup failure (-4)";
  1165.                 case -5:
  1166.                     $this->error="connection refused or timed out (-5)";
  1167.                 default:
  1168.                     $this->error="connection failed (".$errno.")";
  1169.             }
  1170.             return false;
  1171.         }
  1172.     }
  1173. /*======================================================================*\
  1174.     Function:   _disconnect
  1175.     Purpose:    disconnect a socket connection
  1176.     Input:    $fp   file pointer
  1177. \*======================================================================*/
  1178.    
  1179.     function _disconnect($fp)
  1180.     {
  1181.         return(fclose($fp));
  1182.     }
  1183.  
  1184.    
  1185. /*======================================================================*\
  1186.     Function:   _prepare_post_body
  1187.     Purpose:    Prepare post body according to encoding type
  1188.     Input:    $formvars  - form variables
  1189.                 $formfiles - form upload files
  1190.     Output:  post body
  1191. \*======================================================================*/
  1192.    
  1193.     function _prepare_post_body($formvars, $formfiles)
  1194.     {
  1195.         settype($formvars, "array");
  1196.         settype($formfiles, "array");
  1197.         $postdata = '';
  1198.  
  1199.         if (count($formvars) == 0 && count($formfiles) == 0)
  1200.             return;
  1201.        
  1202.         switch ($this->_submit_type) {
  1203.             case "application/x-www-form-urlencoded":
  1204.                 reset($formvars);
  1205.                 while(list($key,$val) = each($formvars)) {
  1206.                     if (is_array($val) || is_object($val)) {
  1207.                         while (list($cur_key, $cur_val) = each($val)) {
  1208.                             $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
  1209.                         }
  1210.                     } else
  1211.                         $postdata .= urlencode($key)."=".