miércoles, 10 de agosto de 2011

Nueva casa

Este es el último post en este lugar, a partir de ahora me mudo a un hosting propio sobre una plataforma .net, la nueva dirección del blog es esta.

Todo lo que está acá quedará y lo iré llevando a la nueva casa, gracias Blogger por estos años de darme espacio y gracias a todos los que siguen este blog. Nos vemos en la nueva casa.

Saludos, Leonardo.

domingo, 24 de julio de 2011

VAN sobre conceptos HTTP y Fiddler web debugger

El pasado sábado 23 de Julio tuve nuevamente el gusto de dar una VAN para la comunidad de Alt.Net hispano, la misma se trató sobre HTTP y Fiddler.

Conceptos básicos de HTTP

En la VAN hablé las cosas que yo creo indispensables que hay que conocer sobre HTTP si nos dedicamos al desarrollo web, su naturaleza, su principales características y limitaciones.

Paralelamante al desarrollo de los temas fui mostrando Fiddler y cómo se puede usar como herramienta para visualizar HTTP, manipularlo y demás.

Fiddler

Finalmente fui mostrando las bondades de esta herramienta y cómo nos puede ayudar de inspeccionar y simular situaciones, cambiar datos, filtrar, hicimos scripts y hasta un plug-in con C#.

Muchas gracias

No tengo más que agradecer a los patrocinadores por los proveer todo lo necesario para la realización de las reuniones y por los regalos que siempre se sortean al final, no quiero dejar de nombrar a Jorge Gamba, el motor de esta comunidad, la pasé muy bien dando la VAN a pesar que siempre algún ejemplo no funciona :-)

El material

Dejo la presentación que utilicé durante la VAN “HTTP las ruedas de la web”, pronto estará la grabación disponible en el sitio de Alt.Net hispano.

El video

Ya está el video disponible

Unable to display content. Adobe Flash is required.

Hasta la próxima, Leonardo.

sábado, 23 de abril de 2011

HTTP un estado aparente, cookies y caché

En el post anterior dije medio al pasar que HTTP no tiene estado, esto quiere decir que cada transacción es única, no sigue una secuencia y no hay relación entre ellas, esto es a nivel protocolo, o sea que HTTP no provee mecanismos para mantener la sesión “out-of-the-box”, si bien en la web que conocemos podemos entrar a Facebook, ingresar nuestros datos y seguir “logeados”, una clara demostración de que Facebook mantiene el “estado” porque recuerda que ya nos “loegamos” (estoy muy comillero).

Qué son las cookies o sea las galletitas

Técnicamente una cookie es un fragmento de información que se almacena del lado del cliente. Dentro de los muchos headers (encabezados) que podemos ver en una respuesta HTTP hay uno de ellos que sirven para controlar las cookies, la cosa es asi:

  • Escenario A:
    • El servidor indica el cliente que debe guardar una cookie con un nombre y valor determinado.
    • El cliente la guarda localmente (de manera segura).
    • Con cada nueva petición HTTP el mismo host el cliente envía esa cookie ignorando para qué la necesita el servidor.
  • Escenario B:
    • Desde javascript se genera un cookie (lado del cliente).
    • La información se guarda localmente.
    • Sólamante es visible desde el ámbito que se creó la cookie (idealmente).
    • El servidor desconoce todo esto.

Para mantener el estado usamos cookies

Vamos a concentarnos en el escenario A que es el que permite el funcionamiento del estado sobre HTTP, para eso un dibujito:

image

Sencillo, en cierto momento que hacemos una petición HTTP al servidor nos response con el header set-cookie, el navegador guarda localmente el nombre y valor de esa cookie y lo envía simpre en cada nueva petición al servidor.

Ejemplo real

Vamos a ver con Fiddler qué pasa con las cookies cuando entramos a un sitio cualquiera. Vamor a www.bing.com

image

simplemente escribimos la dirección en la barra del navegador (Firefox en este caso) y vemos que se generan 15 peticiones….vamos a analizarlo.

En la primera petición nos responde 200 OK y ocho headers set-cookie, quién sabe para qué, pero Bing los usa para algo, en el contenido del primer mensaje está el HTML de la página solicitada. Nuestro navegador va a recordar todas estas cookies y enviarlas con cada petición nueva al host.

Vamos a analizar la segunda petición:

image

Y como era de esperar el navegador envía todas las mismas ocho cookies que le indicó el servidor en la respuesta anterior.

Por qué se generaron quince peticiones si hicimos nada más que una?

La respuesta es simple, el HTML de Bing hace referencia a muchos otros recursos también localizados en internet, por ejemplo las imágenes, los archivos de script, las hojas de estilo, etc. el navegador genera todas estas peticiones a medida que analiza el HTML y determina que necesitas los recursos.

Cuando las cosas se “Cachean”

Vamos a ver qué pasa si repetimos la petición original:

image

Si presionamos F5 y recargamos la misma págna vemos en Fiddler que muchos recursos tiene un ícono con forma de disco, esto quiere decir que el navegador los recuperó del disco local y no los volvió a pedir para optimizar tiempos de respuesta, a esto se le llama caché. O sea el navegador recuerda que ya pedimos ese recurso (por la URL) y lo trae del disco para que sea más rápido, esto pasa mucho con imágenes pero puede pasar con todo, si hacemos Ctrl + F5 obligamos a Firefox a que pida todo de nuevo ignorando el caché.

Podemos desde el servidor obligar a que siempre se pida el recurso sin usar el cache?

Sí, podemos, desde el servidor agregamos el header Cache-Control, por ejemplo con el modificador max-age podemos indicar cuál es el máximo tiempo en segundos que el navegador debe mantener un recurso, en el caso de Bing este header estaba presente en la página por defecto, es por ese que el navegador volvió a pedir el recurso y no lo trajo del cache como los siguientes.

image

El estado y las cookies

Todo esto era para explicar cómo se puede mantener el estado sobre HTTP, el funcionamiento más simple es utilizar una cookies para que el navegador la envíe siempre y entonces identificamos que se trata del mismo cliente, sería así:

  • El cliente se conecta
  • El cliente se logea correctamente
  • El servidor le dice que guarde la cookie “session_id” con un valor generado único para ese cliente
  • El navegador guarda la cookie con dicho valor y la envía con cada petición
  • El servidor revisa siempre el valor de esa cookie e identifica el cliente que se acaba de logear

Es un mecanismo sencillo, pero efectivo, vamos a verlo en funcionamiento.

Un ejemplo sencillo de ver es el modo en que ASP.NET mantiene la sesión, la cookie que usa se llama….asp.net_session y se ve más o menos así:

image

Si las cookies son tan importantes para la sesión, cómo las borro?

No se borran, se hacen expirar, se agrega detrás de la información de la cookie la expiración, la forma más simple es poner una fecha en el pasado para que el navegador detecte que le llegó la hora y la borre. Esto se logra agregando detrás del nombre y valor de la cookies el atributo expires, por ejemplo:

Set-Cookie: lastlogin=1254773024; expires=Mon, 02-Nov-2009 20:12:04 GMT

Entonces cuando un sitio nos da la opción de mantenernos logeados para siempre en parte hace que esa (o esas) cookies que nos identifican no expiren nunca.

Modificando el web server para comprobar el uso de las cookies

Vamos a agregar una pequeña lógica para probar que el navegador va a recibir la orden de guardar una cookies y después va a enviarla siempre, finalmente vamos a forzarlo a hacerla expirar y no enviarla más, el código modificado queda así:

image

Simple, en la primera petición se hace set-cookie (con la instrucción de ASP.NET Cookies.Add) y en la tercera obligamos a que la borre, indicando para esa cookie una fecha de expiración en el pasado. Probemos la primera petición y vemos qué dice Fiddler.

image

Joya, vemos que nuestro servidor envía el header esperado, vamos a hacer una petición a otra página en el mismo sitio para comprobar si el navegador envía la cookie.

image

Adicionalmente envíamos la indicación para que expire la cookie, entonces en la siguiente petición no debería ser envíada, vamos a ver….

image

Notable, funcionó, con esto comprobamos el funcionamiento de las cookies y el comportamiento del navegador.

Hasta la próxima.

sábado, 16 de abril de 2011

Introducción a HTTP, las ruedas de la web

Voy a contar un poco de qué se trata HTTP, el protocolo que da vida a la web.

HTTP es un protocolo. Técnicamente es un protocolo de aplicación (según el modelo OSI) pero en web se utiliza como transporte, es decir para transportar lo que realmente nos importa: el contenido, el HTML, XML, PDF, Zip, etc.

 

Algunas características de HTTP

  • A cada comunicación se la llama transacción HTTP.
  • Todas las transacciones comienzan del lado del cliente (en nuestro caso un navegador WEB).
  • Es, básicamente, texto.
  • Tiene dos secciones: una encabezado y un cuerpo.
  • Se basa en verbos, que indican qué tipo de operación se desea realizar con la petición.
  • Los verbos más comunes son: GET, POST, DELETE, HEAD, PUT.
  • Las repuestas tiene un código de estado (STATUS CODE) qué nos indica qué pasó con nuestro request.
  • Es un protocolo sin estado, es decir, no existe secuencialidad entre transacciones.

 

Anatomía de una petición HTTP

GET http://www.bing.com HTTP/1.1

Esta es la petición más básica que podemos hacer para solicitar un recurso (digo recurso porque no sólo pedimos páginas sino imágenes, script, fuentes, etc), vamos a analizarla.

  • Utiliza el verbo GET, es que vamos a utilizar en general para solicitar un recurso.
  • http://www.bing.com es el nombre del recurso que queremos recuperar, se utiliza el protocolo URL para esto, el nombre del recuros tiene que ser único.
  • Por último la versión del protocolo

ok, esto está muy bien, pero no nos quedemos con mis dichos, vamos a verificarlo.

 

Armando nuestra primer petición HTTP a mano

Vamos a hacer el papel de navegador Web, para eso vamos a ejecutar el Fiddler e ir a la ventana que dice "Request Builder", dentro de ella a la opción "Raw" (que quiere decir "a lo macho") y escribimos exáctamente el request que acabamos a analizar, pero no nos olvidemos de hacer dos veces ENTER o sea, dejar una línea en blanco (por definición antes del cuerpo hay que dejarla) .

image

Hacemos "execute" y..mágia (ignoremos el cartel que pone Fiddler sobre violación de protocolo por falta del header “host” por el momento). Bing nos responde!

image

En la columna de la derecha vemos las transacciones y en la izquierda seleccionado “Insepections” y luego “Raw” podemos ver arriba el requerimiento que armamos y debajo la respuesta, vamos a analizar lo más importante (por ahora) de la respuesta.

 

Analizando la respuesta

De todo lo que vamos a ver en la respuesta en este caso nos vamos a concentrar en lo que nos dicen los siguientes datos:

HTTP /1.1 200 OK
Content-Type: text/html

estos son los datos más importantes (de momento) dentro de una respuesta.

HTTP /1.1 la versión del protocolo

200 OK el código de estado y la descripción, en este caso 200 significa que la petición fue exitosa

Content-Type: text/html el tipo de contenido, ya que HTTP transporta texto necesitamos sabes la naturaleza de los datos para saber cómo interpretarlos, por ejemplo si el contenido fuese una imagen JPG el encabezado sería

Content-Type: image/jpg

a la codificación que se utiliza en el encabezado Content-Type se la conoce como MIME type, hay uno para cada tipo de contenido, notemos que el navegador se va a basar en él para saber qué hacer con el contenido (la extensión del recurso se ignora), en caso de ser un contenido que puede manipular (por ejemplo text/html) lo hará, sino buscará un programa relacionado para hacerlo, por ejemplo con el MIME Type application/ms-word el navegador sabe que tiene tiene que llamar al MSWord.

Lo que viene después de todos los encabezados y luego de una linea en blanco es la página de Bing, o sea el contenido, en definitiva el recurso que estámos pidiendo.

 

Armando nuestro propio Web server

Vamos a demostar lo mismo que antes pero jugando el papel de Web server, es decir, desde el navegador vamos a pedir un recurso a un web server hecho por nosotros, manos a la obra.

image

Haciendo abuso de mis conocimiento de programación hice un web server en 30 líneas que además de despachar archivos nos indica un error 404 si no encuentra algo, vamos a probarlo.

image

Mágia, de más está decir que tengo un archivo “default.htm” en el directorio “C:\temp\pruebasVS2010\minweb\minweb\files” con ese increíble contenido, pero no seamos confiados, vamos a ver si funciona cuando no existe el recurso

image

Increíble no? no nos muestra el mensaje que pusimos porque por defecto IE muestra una mensaje “amigable”, probemos con Firefox

image

Notable, ahora vamos a demostrar que no importa la extension sino que estos navegadores al no enviar nosotros el encabezado “Content-Type” por defecto interpretan HTML, vamos a forzarlos a que llame al lector de PDF configurado en nuestro sistema.

 

Forzando al navegador a llamar al lectro de PDF

El Content-Type lo vamos a ponder como “application/octet-stream” para indicar que es un archivos binario, y vamos a agregar un header con el nombre del archivo destino para que el sistema operativo llame al lector de PDF configurado.

image

Hecho esto, no queda más que probarlo, y….

image

 

El POST y el GET

Ok, hasta ahora usamos el verbo GET para recuperar contenido, esto está muy bien, pero qué pasa si necesitamos pasar parámetros al servidor para recuperar el contenido, por ejemplo queremos recuperar información de un usuario pero necesitamos indicar de qué usuario, entonces usamos lo que se conoce como “Query String” que no es más que agregar los parámetros al final de la dirección URL y es parte del estándar, sería algo así:

http://localhost/detalleUsuario.aspx?id=1

Donde el “Query string” es todo lo que está después del signo de interrogación, y tiene la forma “nombre=valor” en este caso “id=1”.

Esto está muy bien, entonces por qué si queremos ingresar nuestro usuarios y contraseña por qué no enviarlos como parte del query string? hay varias respuestas para esta pregunta

  • El largo máximo de la URL total, si bien HTTP no especifica un largo máximo hay varios límites, tal vez lo más importante sea que IE6 limita a 2086 el largo, algunos servidores a 256…en definitiva no vale la pena arriesgarse a superar 256.
  • Hacerlo por GET implica que la URL + los parámetros van a ser visibles en la barra de navegador.
  • Se puede guardar en favoritos si es una dirección.
  • Sintácticamente para enviar datos se tiene que usar POST y no GET

Si bien alguna de estas desventajas pueden ser ventajas dependiendo de lo que querramos hacer, por ejemplo si tenemos un sitio de ventas por internet es interesante que una búsqueda se pueda ver en la barra de naveagación para poder compartirla, por ejemplo los buscadores usan formularios con el verbo GET para que podamos guardar la búsqueda.

image

Hay un lugar en donde podemos enviar toda la información que querramos y además no es visible para el usuario (no se ve en la barra de navegación) y es mediante el verbo POST ya que los datos los podemos poner en el cuerpo del mensaje (si ponemos información en el cuerpo y usamos GET el servidor lo va a ignorar).

 

“Posteando” datos

Sí, la expresión “voy a postear” viene del verbo POST de HTTP, para postear simplemente hay que cambiar el verbo a POST en el paquete HTTP, el resto es igual, incluso podemos seguir usando query string, desde HTML es necesario utilizar un elemento Form (formulario) para hacer POST, si bien, podemos cambiarlo para que el formulario envíe usando GET (que es el método por defecto de los formularios).

Vamos a hacer un formulario HTML y ver con Fiddler por dónde van los datos

image

image

Presionamos “enviar datos” vamos al Fiddler y vemos que los datos del formulario están en el cuerpo del mensaje, los nombres de los elementos se toman de cada atributo “name” de cada elemento dentro del formulario.

image

Por supuesto que nuestro web server devuelve error 404 porque no existe el recurso “destino.htm”

Leyendo datos de POST desde el web server

Modificamos levemente el código de nuestro web server para leer datos del POST

image

ejecutamos otra vez default.htm con el formulario y listo, tenemos los datos en la consola!

image

De esta manera verificamos que los datos vienen en el cuerpo del mensaje cuando usamos el verbo HTTP POST.

Es todo por esta vez. En la próximos post vamos a ver cómo se hace para mantener el estado sobre un protocolo sin estado, qué podemos hacer con los códigos de estado y otras cosas locas, nos leemos.

martes, 5 de abril de 2011

SharpTestEx extensiones para hacer las pruebas unitarias más alegres

 

Cuando hacemos mucha prueba unitaria (Unit Test) nos encontramos a menudo con tareas similares como evaluar si un número está dentro de un rango, si una colección contiene cierta cantidad de ítems, y cosas así para las cuales nuestro amado .NET Framework no está dotado de funciones ya listas para usar “out of the box” sino más bien tenemos que hacer algunos “Helpers” y cosas así para poder probar más felizmente.

SharpTestEx

El amigo Fabio Maulo en el tiempo que le queda siendo el project leader de NHibernate, manteniendo su propio framework para mapeos de NHibernate, ConfORM, trabajar y otras cosas, se hizo un rato y se escribió un conjunto de métodos de extensión para ampliar las funcionalidades del Framework. :)

Básicamente son métodos de extensión que extienden la clase object, con lo cual con agregar la referencia a la única DLL de SharpTestEx ya contamos con toda su potencia, que nos pemite hacer cosas como esta:

Sintáxis fluyente y auto-descriptiva

[TestMethod]
public void TestMethod1()
{
    var texto = "mi vieja mula ya no es lo que era";

    texto.Should().Contain("mula");
}

Notemos que el objeto texto (que no es más que un string) ahora tiene un método Should() que indica que debería cumplir concierta condición, en este caso se leería

texto debería contener “mula”

bien descriptivo, con esta sintáxis ya está listo el test, si la condición no se cumple SharpTestEx lanza una bonita excepción que además nos dice exáctamente qué pasó, mágico.

Potencia por todos lados

SharpTestEx tiene un arsenal de métodos que nos facilitan la vida cada día, Fabio es un tipo que programa mucho y sabe mucho qué necesita un programador a la hora de probar. Sino miren las estadísticas de Fabio en Ohloh.

public void TestMethod2()
{
    var valorBoleano = false;

    valorBoleano.Should().Be.False();
}

Otro ejemplo de la rica sintáxis, lo interesante de que el código sea quien describe lo que va a pasar en lugar de agregar un pila de comentarios es que cuando cambiemos el código para que se comporte de otra manera ya tenemos la auto-documentación actualizada, por lo menos en mi experiencia los comentarios si son muchos suelen quedar obsoletos, pero es una opinión personal.

public void TestMethod()
{
    var valorNumerico = 110;
    valorNumerico.Should().Be.GreaterThanOrEqualTo(100);
}

Otro ejemplo muy claro, el método GreaterThanOrEqualTo nos soluciona unos cuantos problemas si  quisiéramos hacerlo a mano.

public void TestMethod()
{
    var listaEnteros = new[] { 1, 2, 3 };

    listaEnteros.Should()
        .Not.Be.Null()
        .And.Not.Be.Empty()
        .And.Not.Have.SameSequenceAs(new[] { 3, 2, 1 })
        .And.Have.UniqueValues();

    listaEnteros.Should().Contain(2).And.Not.Contain(4);

    listaEnteros.Should().Contain(3).And.Not.Have.Count.LessThan(2);
}

Este ejemplo copiado del sitio de Codeplex nos muestra la versatilidad para verificar IEnumerables<T> (colecciones) y que además podemos encadenar validaciones, más que mágico!

Detalles finales

Lo único que me queda decir es que sin duda SharpTestEx es una herramienta que siempre nos va a facilitar las cosas, un detalle es que hay un assembly (DLL) según el framework de Unit Testing que usemos, por ejemplo yo usé MSTest el que viene integrado dentro de Visual Studio y agregué el using al principio de los test para “ver” los métodos de extensión.

using SharpTestsEx;

Nada más, nos vemos la próxima.

martes, 4 de enero de 2011

Año nuevo, objetivos nuevos

Comienza un nuevo año y con él vienen las declaraciones de deseos y objetivos, y bueno, acá van los mios:

Nuevo hospedaje para el blog

Muchas veces me preguntaron por qué no pongo Add-Algo en el sitio para ganar un pesos y la respuesta es “porque no es la idea” además todos sabemos que si yo gano $1 Google gana $2, entonces esa reflexión se extiende a “no quiero regalarle plata a Google”, tanto es así que voy a migar este blog en algún momento del año a otra plataforma y otro hosting, posiblemente uno de pago y sobre WordPress.

Escribir un Libro sobre programación usando SCRUM

Muchas veces me llegaron consultas para que recomiende libros sobre programación en .Net y mi respuesta siempre fue la misma “no sé, la verdad es que no conozco ninguno recomendable” pero no me quedé nunca conforme con la respuesta, por lo tanto voy a tomar el toro por las astas y hacerlo yo, como declaración dejo lo único que por ahora tengo claro sobre el libro:

  • Será en Castellano
  • Será público
  • Será sobre .Net
  • Será sobre C#
  • Comenzará desde POO, incluyendo conceptos de clases, objetos, interfaces, polimorfísmo, etc.
  • No tocará temas sobre Winforms
  • Habrá conceptos web de base, http, html, xml, etc. siempre es mejor comprender lo que pasa
  • Se hablará de herramientas como Reflector, Fiddler y otras.
  • Hablará de patrones que yo uso, y no de cosas demasíado poco comunes y que confunden más de lo que aclaran.
  • Se tocará mucho el temas de test de unidad
  • Se hablará de mocking y moq.
  • Se hablará sobre legibildiad de código, comentarios, etc.
  • Se hablará de frameworks como MVC
  • Se hablará de Javascript
  • Se hablará de jQuery

Y mucho más, es ambicioso, pero como si fuera poco lo pienso desarrollar usando SCRUM, de la siguiente manera:

La lista anterior sería un backlog del producto, la visión es la siguiente: “Escribir un libro de programación en .net que toque los temas básicos que muchos libros dan por obvios y abarque los conceptos y herramientas de todos los días”.

El modelo de desarrollo será Scrum con sprint mensuales, por supuesto, el resultado de cada sprint es un entregable.

En fin, es una primera aproximación, me falta definir la fecha de inicio, voy a ir refinando el backlog el cual pronto publicaré de modo público.

Saludos, Leonardo.

domingo, 17 de octubre de 2010

El pajarraco Scrumero

Introducción

CIMG0667

El miércoles trece de octubre pasado en el marco de la materia “Arquitectura Web” que tengo el gusto de dictar en la universidad CAECE vivimos una experiencia muy gratificante.

Como parte de una humilde evangelización de metodología ágiles al principio de la cursada se dicta una clase introductoria a SCRUM, mi idea siempre fue hacerlo más práctico entonces envié una pregunta sobre cómo podría hacer una práctica grupal de introducción a la lista de ágiles, como era de esperar recibí muchísimas sugerencias pero además recibí un mail privado de Ingrid Astiz ofreciéndose a venir ella personalmente a hacer el juego del pajarraco obra del gran Alan Cyment.

Después de coordinar unas semanas llegó el día y recibimos a Ingrid en el aula.

CIMG0666 CIMG0668

La dinámica del juego

Se armaron cinco grupos de alumnos que con una caja de RASTIS cada uno.

Se organizaron planning meetings de 5’, sprints de 10’, reviews de 2’ y retrospectivas de 2’, este ciclo se repitió 3 veces, todos los alumnos participaron con mucho entusiasmo de la actividad y esto quedó reflejado cuando después de terminado el ejercicio hicimos entre todos una retrospectiva sobre la actividad donde surgieron preguntas sobre metodologías ágiles y grupos de trabajo, esta retrospectiva duró más de una hora.

CIMG0671 CIMG0669

La actividad ayudó mucho a la integración y a la comprensión de la metodología y demuestra que no sólo se puede usar una metodología ágil para desarrollar software, durante la actividad salieron a la superficie los mismos errores y soluciones que en un proyecto real, por supuesto a partir de ahora lo vamos a practicar en cada cursada.

Aspectos sobresalientes:

  • La autogestión de los equipos, sprint tras sprint se iban encontrando los roles.
  • El surgimiento de líderes naturales, que van apareciendo según la situación.
  • Preguntar, dejar de lado supuestos y repreguntar.
  • Retrospectiva, parar la pelota y pensar qué de hizo mal y qué se puede mejorar.
  • Le estimación, todos los equipos fueron encontrando su propio ritmo de trabajo después de cada sprint.
  • La sinergia que surgió naturalmente cuando todos siente el objetivo como propio y se reconocen como iguales.
  • La integración del grupo.
  • El diseño emergente, la comprensión del producto incremental.

CIMG0687 CIMG0688 CIMG0676

Agradezco infinitamente a Ingrid por su voluntad y generosidad, a Marcela y Vero por ayudarnos, hasta la próxima.

todos