Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 12 de diciembre de 2017
Seguro que los que os movéis en el mundo del desarrollo web os habéis encontrado alguna vez ante un problema de scripts en un sitio web que sólo ocurre en el entorno de producción. Si habéis subido sólo el archivo minimizado, sin mapas ni nada parecido, intentar depurarlo es una pesadilla y seguro que os gustaría poder hacer pruebas en producción usando vuestro fuente original, sin tener que que hacer cambios que puedan afectar a otros visitantes.

O también se os habrá dado el caso de que necesitéis hacer cambios en un script y os da miedillo subirlo directamente a producción sin haberlo probado antes suficientemente en el entorno real. Esto es un tema especialmente peliagudo si estáis desarrollando una plataforma SaaS en la que cientos de clientes usen en sus páginas web una referencia a vuestro script y cualquier cambio en el mismo puede traer consecuencias graves para el servicio.

Por ejemplo, imaginad que prestamos un servicio similar a Google Analytics, y todos nuestros clientes tienen una referencia en sus páginas a nuestro archivo "analytics.js" para trackear sus visitas. ¿Cómo podríamos introducir cambios en dicho archivo de script para hacer pruebas en sitios donde nos interese, sin que afectara al resto de clientes ni a los visitantes de sus páginas?

A priori no parece haber una respuesta sencilla, pero sí que la hay. Sólo necesitamos Fiddler y tres minutos de nuestro tiempo para conseguirlo :)

Fiddler, un proxy programable

FiddlerEstaréis de acuerdo en que Fiddler es una de esas herramientas que obligatoriamente debemos tener en nuestra mochila los desarrolladores web. Además de permitirnos trazar peticiones posicionándose como proxy del sistema, que quizás sea su uso más común, ofrece utilidades para componer peticiones o hacer pruebas de rendimiento que nos pueden venir de perlas en muchos escenarios.

Pero sin duda, lo más interesante para el caso que nos ocupa es que como proxy se trata de una herramienta muy flexible. Podemos ampliar sus funcionalidades a través de extensiones, así como introducir pequeños scripts escritos en FiddlerScript (en la práctica, C#) para manipular las comunicaciones que se producen entre cliente y servidor. Es decir, el proxy pasaría de ser un elemento puramente pasivo, que lo único que hace es ver pasar las peticiones y las respuestas, a tener un papel totalmente activo en las mismas pudiendo examinarlas y modificarlas cuando sea conveniente.

Probablemente ya veréis por dónde va la cosa para solucionar el problema que enunciábamos al principio: crearemos un archivo JS con los cambios que queremos probar en producción, lo subiremos a nuestro servidor, e introduciremos código en el proxy que modifique las sesiones de forma que todas las solicitudes dirigidas al script original sean transformadas en peticiones hacia la nueva versión:

Proxy Fiddler modificando las peticiones

Dado que Fiddler está en nuestra máquina local, estos cambios sólo se producirán cuando estemos navegando desde ella, por lo que la nueva versión del script sólo será aplicada en nuestro equipo. Podremos hacer todas las pruebas que queramos, y sin molestar a nuestros clientes ni a sus visitantes con experimentos.

Y conseguirlo es bien sencillo. Simplemente debemos abrir el editor de scripts de Fiddler seleccionando la opción del menú Rules>Customize rules, o mediante el atajo Ctrl+R:

Editor de scripts de Fiddler abierto
A continuación, debemos buscar en el código fuente la función OnBeforeRequest(). Se trata de un evento interno que es ejecutado cuando Fiddler ha capturado una petición y justo antes de reenviarla al exterior, por lo que es el punto ideal donde introducir cambios como el siguiente:
static function OnBeforeRequest(oSession: Session) {

    if (oSession.PathAndQuery=="/analytics.js") {
      oSession.PathAndQuery="/analytics-fixed.js";
    }

    ... // More code
}
Observad que, dado podemos retocar con toda libertad la ruta del recurso solicitado en la petición, estamos haciendo que cuando el proxy de Fiddler reciba una petición hacia un recurso llamado "analytics.js", la reenviará al host original como si se tratara de una petición hacia "analytics-fixed.js".

Otro escenario que podemos resolver de la misma forma es la depuración de fuentes sin minimizar. Imaginad que tenemos en producción un archivo de scripts minimizado, llamado "myscript.min.js", fijaos lo sencillo que resulta reemplazarlo por el archivo fuente original para facilitarnos la depuración desde el equipo local:
if (oSession.PathAndQuery=="/myscripts.min.js") {
  oSession.PathAndQuery="/myscripts.js";
}
De la misma forma que modificamos la ruta del recursos podríamos introducir cualquier tipo de modificación en la petición saliente: añadir o eliminar encabezados, modificar host o puerto de destino, hacer sustituciones en el cuerpo, etc. El siguiente código, por ejemplo, muestra cómo hacer que todas las peticiones dirigidas hacia el host "cdn.mysite.com" se transformen en peticiones hacia "test-cdn.mysite.com":
if (oSession.HostnameIs("cdn.mysite.com")) {
  oSession.hostname="test-cdn.mysite.com";
}
Y, por supuesto, podemos hacer lo mismo con las respuestas. La única diferencia es que el evento que tendremos que modificar será OnBeforeResponse(), pero en él tendremos acceso a la información que el host original ha enviado de vuelta, y podremos modificarla a nuestro antojo.

Por ejemplo, mediante el siguiente código reemplazamos el texto "hi" por "hello" en todas las respuestas de tipo "text/html" en el servidor "www.mysite.com":
if (oSession.HostnameIs("www.mysite.com") 
    && oSession.oResponse.headers.ExistsAndContains("Content-Type","text/html")){
  oSession.utilDecodeResponse();
  oSession.utilReplaceInResponse('hi','hello');
}
Como veréis, esta utilidad de Fiddler da bastante juego; la sustitución de archivos Javascript es sólo una pequeña utilidad inmediata, pero puede usarse para muchísimas más cosas. Podríamos probar con facilidad nuevos CSS, temas, imágenes o cualquier tipo de recurso, sustituir el host original por un host alternativo (por ejemplo para pruebas en escenarios multi-tenant), reemplazar porciones de la respuesta, hacer fakes de APIs externas, etc. Sólo es cuestión de echarle imaginación cuando estemos ante escenarios en los que nos vendría bien hacer algunas trampillas al intercambiar información con el servidor :)

Os recomiendo echarle un vistazo a la propia documentación que viene en el interior del script, y a las ayudas ofrecidas, pues el editor incluye algo de intellisense, y una breve referencia de objetos, métodos y propiedades disponibles. También os recomiendo visitar este enlace, donde se muestran bastantes ejemplos concretos de las cosas que podemos conseguir con FiddlerScript.

¡Espero que os sea de utilidad!

Publicado en Variable not found.

3 Comentarios:

Apertil dijo...

Éxito completo en la oficina!!!

José María Aguilar dijo...

:DDD

Me alegro mucho!

Eduard dijo...

Es impresionante... llevo usando el Fiddler unos cuantos años y nunca se me había pasado por la cabeza que puede hacer esto. Casi un regalo de navidad :P ¡Gracias!

Felices fiestas.