Wednesday, July 9, 2014

SQUID / No se puede acceder a Interjet

Antecedentes

Uno de los usuarios argumentó que no podía acceder a la pagina de Interjet. Este usuario utilizaba una pagina de convenio, la cual, al ingresar un código correctamente, redirecciona a una sección dentro de http://www.interjet.com.mx la cual todos los vuelos incluyen cierto  porcentaje de descuento.

Introducción

Ingresando al sitio de convenio con proxy, al rediccionar a Interjet, este manda a un sitio de nombre:
  • http://200.57.159.179/SorryPage/
El famoso "SorryPage" redirecciona a una pequeña sección de búsqueda de vuelos pero sin descuento.

Y cabe señalar que ingresando directamente al sitio de interjet con proxy redirecciona a esta misma sección de "SorryPage".

Por otro lado, ingresando al sitio de convenio sin proxy, este redirecciona correctamente a la sección de buscar vuelos con descuento, dentro del sitio web de Interjet.

Solución

Al ingresar a http://ww.interjet.com.mx, se puede apreciar que detecta el lenguaje del "User-Agent" (navegador) para desplegar sitio en el idioma y el país de compra. Lo cual no se me hace correcto, ya que es de lo más normal utilizar el navegador en otro idioma (sobre todo en Ingles).
Para esto, los programadores de Interjet hacen uso del request header "HTTP_ACCEPT_LANGUAGE".

Esto me hizo pensar en que estarían utilizando algún request header para filtrar el acceso.

Para saber que "request headers" manda SQUID, podemos utilizar un pequeño script de PHP el cual lea todos estos valores accediendo a el sin proxy y con proxy.

El sencillo script de PHP se muestra como:

// Leemos todos las variables del servidor
foreach ($_SERVER as $name => $value){ 
  if (substr($name, 0, 5) == 'HTTP_') 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
  }
// Imprimimos los resultados
var_dump($headers); 

El resultado de este script entrando desde Chrome sin proxy es:

array(8) {
  ["Accept"]=>
  string(74) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
  ["Accept-Encoding"]=>
  string(17) "gzip,deflate,sdch"
  ["Accept-Language"]=>
  string(45) "es-419,es;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2"
  ["Cache-Control"]=>
  string(9) "max-age=0"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Cookie"]=>
  string(58) "PHPSESSID=776d3499930de3eea3027f76d3bee0ba; __atuvc=2%7C25"
  ["Host"]=>
  string(16) "paralizabal.com"
  ["User-Agent"]=>
  string(109) "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"
}

Y el resultado del mismo script desde Chrome pero con proxy es:

array(10) {
  ["Accept"]=>
  string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
  ["Accept-Encoding"]=>
  string(21) "identity,gzip,deflate"
  ["Accept-Language"]=>
  string(59) "es-MX,es-ES;q=0.8,es-AR;q=0.7,es;q=0.5,en-US;q=0.3,en;q=0.2"
  ["Cache-Control"]=>
  string(14) "max-age=259200"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Cookie"]=>
  string(172) "_ga=GA1.3.1925363739.1393444304; __utma=88164442.1925363739.1393444304.1399225959.1399482628.2; __utmz=88164442.1399225959.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)"
  ["Host"]=>
  string(16) "paralizabal.com"
  ["User-Agent"]=>
  string(72) "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0"
  ["X-Forwarded-For"]=>
  string(7) "192.168.1.100"
}

Con esto podemos apreciar que la diferencia es el encabezado "X-Forwarded-For", el cual indica la IP original del cliente conectado a un servidor web mediante un HTTP-Proxy o Load balancer, estándar sugerido, precisamente, por los desarrolladores de SQUID.

 Así que la solución final es deshabilidar este encabezado en SQUID, de forma muy sencilla, agregamos en el archivo squid.conf la siguiente línea:

forwarded_for on

Reiniciamos SQUID y listo!, podemos entrar al sitio principal de http://ww.interjet.com.mx.

Friday, July 4, 2014

Dado un string, analizarlo y convertirlo a palindrome en caso que sea posible

Antecedentes

En una entrevista de trabajo me pidieron realizar la siguiente actividad: "Desarrollar una función la cual recibirá un string, analizarlo y tratar de convertirlo a palindrome". No precisamente el string estará en el mismo orden, por ejemplo, la función puede recibir ->  SSUUG la cual en su versión palindrome sería SUGUS.

Introducción

El error que cometí fue el estar pensando en el detalle de las posibles combinaciones, en mi mente estaba:

Posibilidades de crear una palabra palindrome dependiendo su longitud

2 -> 2
3 -> 2-1
4 -> 4, 2-2
5 -> 2-2-1
6 -> 6, 4-2, 2-2-2
7 -> 6-1, 4-2-1, 2-2-2-1
8 -> 8, 6-2, 4-4, 4-2-2, 2-2-2-2
9 -> 8-1, 6-2-1, 4-4-1, 4-2-2-1, 2-2-2-2-1
10 -> 10, 8-2, 6-4, 4-4-2, 4-2-2-2-2, 2-2-2-2-2

Por lo que después de haber creado la función en base a la lógica más complicada, pensé en lo que el entrevistador me dijo al final: "Solo puede haber un fallo".

En efecto, las letras se deben presentar en pares y si se tiene 2 letras individuales diferentes, no es posible convertirla a palindrome.

Solución

La solución queda detallada de la siguiente forma:

1.- Crear un array con las letras únicas y las veces en que se repite (desde aquí se puede hacer la validación de palindrome pero yo decidí hacerlo en el paso #2).
2.- Imprimir las palabras del array en forma palindrome.

El código en javascript se ve así:




Y aquí un pequeño demo: