hacking session - los problemas de Windows Live Writer con WordPress

Live Writer es una de las herramientas por excelencia para los blogueros más avanzados.

Por mucho tiempo fue mi herramienta infaltable hasta que un día… no se que paso, ni como ni donde ni porqué…
pero lo cierto es que dejo de funcionar.

Lo acepto, me dio pereza ponerme a revisar el tema, así que busque en foros , blogs, amigos etc. sin éxito y comencé a escribir de nuevo en el blog de notas y luego desde Visual Studio… probé otros blog writers, sin quedar satisfecho.

Hasta que en un día me harté, no de usar Visual Studio, desde luego, pero si de no habe resuelto el problema.

Respire, mire a mis adentros y me dije, es hora de utilizar mis super poderes de hacker y lo solucioné.

Esta es la historia.

El Error

Cada vez que trataba de hacer algo con mi blog desde Live Writer me salía este error

live writer error word press

Así que decidí volver a inscribir el blog en Live Writer con tan mala suerte que sucedió exactamente lo mismo y ya nunca más funcionó.

Diagnóstico

El log de Windows Live Writer

Como pueden ver el mensaje de error sirve para poco y nada.

Error al intentar conectar con tu servicio de blog:
Respuesta de servidor no válida  
La respuesta al método blogger.getUsersBlogs recibida desde el servidor de blogs no era válida:
        Invalid response document returned from XmlRpc server Intenta solucionar el problema y, a continuación, inténtalo de nuevo.

Me pregunto que $#%#$ es blogger.getUsersBlogs y que tiene que ver con WordPress :S

Así que era el momento de buscar logs.

El log de Live Writer en Windows está en %localappdata%\Windows Live Writer allí esta el archivo "Windows Live Writer.log" el cual podemos revisar.

log de Windows Live Writer

Lo primero que notamos es que vuelve a aparecer el tema de XmlRpc lo cual aún no nos dice nada, pero algo si es muy importante: "La respuesta del servidor no es válida" aunque hasta el momento eso tampoco nos sirve de nada.

Este es uno de esos momentos en que te das por vencido esperando que alguna vez WordPress o Live Writer corrijan un bug en su código… si algún día.

Salvo que uses tus super poderes de developer.

Buscando en internet encontré muchos problemas diferentes de Live Writer los cuales para solucionarlos hay que revisar el archivo xmlrpc.php de WordPress, sin embargo para no comer entero busqué de donde salía ese archivo.

Lo usual es que podemos cambiar el inicio de Live Writer para que el log sea más detallado, eso se hace llamando al ejecutable de Live Writer así

WindowsLiveWriter.exe /verbose  

Una vez hecho de esa manera, debes replicar el error y de nuevo revisar el log el cual ahora es más detallado, en mi caso encontré esto (recuerden fue en mi blog anterior que estaba en wordpress/php):

Live writer detailed log

La palabra clave aquí es Request y la URL de dicho Request … así llegamos al archivo xmlrpc.php de WordPress.

http://juank.black-byte.com/wordpress/xmlrpc.php

Con esta información podemos sospechar que ese Request esta devolviendo una respuesta incorrecta.

Al revisar el archivo xmlrpc.php de WordPress me pregunté

¿Cómo es que de la noche a la mañana ahí hay algo mal en ese archivo si yo nunca le he hecho nada?

Gran pregunta, yo no les había hecho nada pero tal vez si nu tercero y no estoy hablando de un humano....

Sospeché de los plugin, por lo cual desactive todos ellos y taraaaaaaaaaaaaaaaan: no paso nada, el error persistia. #Fail

Revise el código meticulosamente, pero no encontré nada extraño.

Es necesario pensar como advanced developer!

Revisando el request

Al ingresar http://juank.black-byte.com/wordpress/xmlrpc.php por el explorador web, obtengo la respuesta

XML-RPC server accepts POST requests only.  

Así que tenia que hacer un Request vía POST y de seguro comenzar a obtener tanta información como pudiera de su respuesta.

Decidí hacerlo con Feedler la cual tiene un nombre bastante self explained: "Feedler Web Debugging Proxy".

Lo pueden obtener acá: http://www.fiddler2.com/fiddler2/

No entrare en detalles de como hace fiddler para funcionar, pero el que lo desee puede investigarlo.

Así que uso fiddler para hacer un Request a http://juank.black-byte.com/wordpress/xmlrpc.php .

Voy a la pestaña "Request Builder" donde configuro la URL y el método del Request (POST):

Fiddler request builder

Le doy execute e inmediatamente obtengo esto:

Fiddler http protocol violation

Content-Length mismatch: Response Header indicated 386 bytes, but server sent 389 bytes.  

Bingo!! Wait!, mmmm no tan rápido.

en Fiddler doy doble clic sobre el Request fallido, recién hecho, para examinar sus detalles, estos detalles de la respuesta salen a la derecha en la parte inferior, aparentemente no dice nada del otro mundo pero entonces me voy a la pestaña Raw para ver la respuesta sin procesar, tal como es enviada por el servidor.

Fiddler request details

Tampoco veo nada anómalo, entro en depresión :'(

De repente veo la pestaña HexView la cual es aún más Raw (jajaja), ahora si estamos hablando el mismo idioma... hacker nativo: bytes.

Comparando la vista Raw con la Hexa me doy cuenta que puedo diferenciar fácilmente el header Response de su contenido, sumado a que en la vista Hexa Fiddler me pone el header de color verde como se ve aquí:

Fiddler Raw view Versus Hexa view

De repente, comienzo a ver los bytes traspasar por mi cuerpo y lo veo allí.

Me senti como, mmm recuerdean esto?

Neo, only human

Neo: Hiya, fellas.
Agent Johnson: It’s him.
Agent Thompson: The anomaly.
Agent Jackson: Do we proceed?
Agent Johnson: Yes…
Agent Thompson: …he is still…
Agent Jackson: …only human.
...kicks, punches
Neo: Upgraded!

Qué se supone que son estos garabatos?



Estos 3 caracteres  son los 3 primeros caracteres que aparecen después de los header.

Desconozco los detalles de longitud de los headers, pero el error anterior era claro: "en el header se indican 386 bytes, pero el servidor envió 389 bytes".

La diferencia según el mensaje son 3 bytes y casualmente la anomalía es de 3 bytes.

Te tengo!

Como muchos de ustedes pueden saber y sino de una vez les cuento PHP tiene la particularidad de que si se incluyen líneas en blanco antes o después de los tag <?php … ?> se pueden generar resultados inesperados…
lo se, apesta, nunca me ha gustado aunque se pueden hacer grandes cosas con el...

Procedí, entonces a revisar el archivo xmlrpc.php para eliminar dichos espacios o líneas en blanco, pero para mi sorpresa no había ninguno.

Como es de suponerse las funcionalidades de ese archivo son llamadas desde otros archivos así que por descarte escogí los archivos de WordPress que yo si había modificado:

los de el tema actual del blog, los revise uno por uno y encontré varios con líneas en blanco al inicio o al final… o en ambos casos.

Procedí a probar Live Writer… no había funcionado.

Nuevamente me quede sin opciones.
No había podido solucionar el problema. #EPICFAIL de nuevo. :'(

Tocó debugguear! algo así como
hacker developer mode

Solución … a medias pero solución

Estaba seguro que el problema estaba en los 3 bytes, eso era un hecho, para descartar fui a xmlrpc.php y verificando sus referencias llegué a class-wp-xmlrpc-server.php y a class-IXR.php

Para mi alegre sorpresa encontré que class-wp-xmlrpc-server.php esta repleto de invocaciones a métodos llamados getUsersBlogs (recuerden que esto apareció al principio) y que casualmente cuando se llama a wp_getUsersBlog aparece esto

function wp_getUsersBlogs( $args )
{
   global $current_site;
   // If this isn't on WPMU then just use blogger_getUsersBlogs
   if ( !is_multisite() )
   {
      array_unshift( $args, 1 );
      return $this->blogger_getUsersBlogs( $args );
   }
}

Muy probablemente en la línea del return es dónde se está generando el mensaje de error.

Continúe con mi búsqueda revisando en donde se escribían los headers, exactamente el header que reporta la longitud erronea en el Response, pero no lo encontré, por lo cual supuse que era una funcionalidad heredada, es decir en una clase base probablmente escrita en otro archivo..

Verificando el código línea a línea, busque el origen de cada método invocado y así llegué al archivo class-IXR.php, allí estaba:

function output($xml)

{
   $xml = '<?xml version="1.0"?>'."\n".$xml;
   $length = strlen($xml);

   header('Connection: close');
   header('Content-Length: '.$length);

   header('Content-Type: text/xml');
   header('Date: '.date('r'));
   echo $xml;
   exit;
}

Lo revise meticulosamente y en apariencia no había nada que hiciera que el header "Content-Length" reportara un tamaño incorrecto.

Así que nada más por descartar en la parte donde se llena ese header le coloqué + 3 bytes.

header('Content-Length: '.$length) + 3;  

Ejecuté Live Writer y FUNCIONO!!

Ok, pero esta no es una solución decente, porque si me volvía a pasar que debería hacer?

modificar todas las veces este fuente y forzar que el conteo sea el correcto.

Eso no es nada profesional
y por demás…
dónde se genera la anomalía?

Soy demasiado sicorígido para quedarme con esa pregunta abierta.

Hasta acá no tenia idea de que más hacer y ya se había hecho bastante.

Pero bueno, podemos ser hacker super saiyayin nivel 3.

Buscando la anomalía, desde sus raíces – BOM .

Los bytes anómalos son EF BB BF respectivamente: 

Inicie mi búsqueda por internet con los caracteres anómalos y aunque habían algunas pistas no me llevaba a nada concreto, así que busque por los valores hexa y el primer artículo que salió era de Wikipedia:

Resulta que exactamente estos tres caracteres (BOM) son una marca de bytes utilizada en archivos de texto de manera opcional para indicar que codificación trae el archivo, si lo trae el archivo es un archivo codificado en UTF-8 sin lugar a duda… pero BOM.

Esos caracteres BOM pudieron haber sido agregados a cualquier archivo de php dentro de mi WordPress, de hecho mi problema original era con 6 caracteres y no con 3 como lo he explicado para simplificar un poco el problema, lo cual me hacia pensar que como mínimo habían dos archivos con ese problema.

El problema con BOM es que muchos editores no muestran esos caracteres porque precisamente saben que son BOM y que no se muestran sino que se usan como guía para saber que tipo de codificación tiene el archivo. Así que no es cuestión de abrir los archivos y editarlos.

Estas imagen muestran como se ve un archivo con BOM en un editor de texto y como se ve en un editor binario:

Text editor

BOM is not seen in a text editor

Binary editor

BOM seen in a binary editor

Potencialmente cualquier archivo .php en mi WordPress podría tener ese problema pero revisar 1000 archivos en modo binario desde Visual Studio para remover 3 bytes en cada uno podría ser dispendioso, más aún cuando no en todos debería quitar esos 3 bytes sino solo en los que tuviesen BOM.

Deshice los cambios que sumaban 3 bytes en el header.
De nuevo hacer un programa por mi cuenta era el plan D.

Buscando por Internet Llegué a esta herramienta gratuita

Debo admitir…
es un enrredo, internamente muy bueno pero tiene una UI de la vieja guardia.

Les diré como usarlo para este problema puntual. Lo primero es que baje mi sitio de WordPress a carpeta local.

  • Abrimos Replace Pioner
  • Vamos a Tools> Batch Runner
  • Como no sabemos cuantos archivos de nuestra instalación de WordPress tienen ese problema usamos la opción Search Files
  • Filtramos todos los archivos .php del directorio y subdirectorios de WordPress

Replace Pioner

  • Clic en Search y listo tenemos listados todos los archivos .php
  • Cerramos el dialogo
  • En la parte inferior de Batch Runner tenemos el botón "Fast Replace" lo presionamos.
  • En el dialogo que se abre seleccionamos el template de "binary file — remove utf-8 BOM"
  • Presionamos Add
  • Seguidamente Start

Remove BOM using replace Pioner

Tomará unos segundos, luego podemos ver el log de los cambios realizados, eso nos permitirá saber que archivos eran los culpables.

Una vez finalice el proceso copiamos los archivos de nuevo a nuestro web server, vamos a Windows Live Writer y BINGO!!

Ahora si todo funcionando y de la manera más profesional posible.

Como prevenir verse afectado por temas de BOM?

En algún lugar de la web encontré algo ingenioso.

Si bien puedes ser prevenido y siempre desde tu editor darle "guardar como" y seleccionar todo excepto UTF-8, un truco es que al menos en los comentarios incluyan una letra que no sea de UTF-8 *por ejemplo la *'ñ' con esto automáticamente el editor no hará uso del BOM ni nada similar pues no puede mostrar ese caracter en UTF-8.

Estoy seguro que este artículo les habrá encantado.

Byte!

Espero sus comentarios y no duden en compartirlo ;)

Comparte este artículo

comments powered by Disqus