Protocolo HTTP
Hypertext Transfer Protocol o HTTP (en español protocolo de transferencia de hipertexto) es el protocolo de comunicación que permite las transferencias de información en la WWW. Se trata de un protocolo de capa 7 de aplicación.

En arduino con la librería ethernet solo trabajamos con la capa de aplicación, todas las otras capas de la pila TCP/IP ya están implementadas por Hardware, ya sea con la ethernet shield o el módulo WiFi correspondiente. Aunque si queremos realizar algunas funciones de capas inferiores, podemos hacerlo con los comandos adecuados comunicándonos con el chip ethernet o wifi via SPI.
Veamos algunos protocolos de la capa de aplicación que serán los que tengamos que implementar en nuestro arduino directamente o usando la librería adecuada:
- HTTP: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- HTTPS: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol_Secure
- SMTP: http://es.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
- Telnet: http://es.wikipedia.org/wiki/Telnet
HTTP es un protocolo muy importante puesto que es el que se va a usar para comunicar Arduino con cualquier elemento de la WWW o de una intranet. En el IoT es uno de los protocolos más usados y sobre todo si queremos obtener o mandar datos a servidores o usar las APIs que nos ofrecen algunos servicios para obtención de información, por ejemplo, para obtener el tiempo meteorológico de la AEMET https://opendata.aemet.es/centrodedescargas/inicio y con esos datos que Arduino actúe de una forma u otra.
Hypertext Transfer Protocol o HTTP (en español protocolo de transferencia de hipertexto) es el protocolo usado en cada transacción de la World Wide Web. HTTP fue desarrollado por el World Wide Web Consortium y la Internet Engineering Task Force.
HTTP define la sintaxis y la semántica que utilizan los elementos de software de la arquitectura web (clientes, servidores, proxies) para comunicarse. Es un protocolo orientado a transacciones y sigue el esquema petición-respuesta entre un cliente y un servidor. Al cliente que efectúa la petición (un navegador web) se lo conoce como «user agent» (agente del usuario). A la información transmitida se la llama recurso y se la identifica mediante un localizador uniforme de recursos (URL).
HTTP es un protocolo sin estado, es decir, que no guarda ninguna información sobre conexiones anteriores. El desarrollo de aplicaciones web necesita frecuentemente mantener estado. Para esto se usan las cookies, que es información que un servidor puede almacenar en el sistema cliente. Esto le permite a las aplicaciones web instituir la noción de «sesión», y también permite rastrear usuarios ya que las cookies pueden guardarse en el cliente por tiempo indeterminado.
Una transacción HTTP está formada por un encabezado seguido, opcionalmente, por una línea en blanco y algún dato. El encabezado especificará cosas como la acción requerida del servidor, o el tipo de dato retornado, o el código de estado. El uso de campos de encabezados enviados en las transacciones HTTP le dan gran flexibilidad al protocolo. Estos campos permiten que se envíe información descriptiva en la transacción, permitiendo así la autenticación, cifrado e identificación de usuario. Ejemplos de encabezados: HTTP_ACCEPT y HTTP_USER_AGENT.

Más información sobre HTTP:
- HTTP: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- Versiones HTTP: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Versiones
- Ejemplo de dialogo HTTP: https://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Ejemplo_de_di.C3.A1logo_HTTP
- Métodos de petición: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol#M.C3.A9todos_de_petici.C3.B3n
- Códigos de respuesta: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol#C.C3.B3digos_de_respuesta
- Novedades de HTTP/1.1: http://www.apacheweek.com/features/http11
- HTTP/2: https://es.wikipedia.org/wiki/HTTP/2
Para intercambio de archivos por HTTP usamos MIME: http://es.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions
Líneas de encabezado o headers, son muy importantes y dan información adicional de la conexión y el comportamiento puede cambiar en función de ellas:
- http://trevinca.ei.uvigo.es/~txapi/espanol/proyecto/superior/memoria/node51.html
- http://powercps.readthedocs.io/zh_CN/latest/sdk/http-headers.en/

Interesante HTTP quick guide: https://www.tutorialspoint.com/http/http_quick_guide.htm
Métodos de Petición HTTP
Lo más importante para comunicar arduino por HTTP con otros dispositivos, ya sean servidores, ordenadores, otros Arduinos, etc… es conocer los métodos GET y POST del protocolo HTTP. HTTP define 8 métodos que indica la acción que desea que se efectúe sobre el recurso identificado. Lo que este recurso representa, si los datos pre-existentes o datos que se generan de forma dinámica, depende de la aplicación del servidor. A menudo, el recurso corresponde a un archivo o la salida de un ejecutable que residen en el servidor.
GET
GET: Pide una representación del recurso especificado. Por seguridad no debería ser usado por aplicaciones que causen efectos ya que transmite información a través de la URI agregando parámetros a la URL. La petición puede ser simple, es decir en una línea o compuesta de la manera que muestra el ejemplo.
Ejemplo simple:
GET /images/logo.png HTTP/1.1 obtiene un recurso llamado logo.png
Ejemplo con parámetros:
GET /index.php?page=main&lang=es HTTP/1.1
POST
POST: Envía los datos para que sean procesados por el recurso identificado. Los datos se incluirán en el cuerpo de la petición. Esto puede resultar en la creación de un nuevo recurso o de las actualizaciones de los recursos existentes o ambas cosas.
Los otros métodos de HTTP:

Más información:
- http://www.w3schools.com/tags/ref_httpmethods.asp
- http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- http://en.wikipedia.org/wiki/POST_(HTTP)
Entender los métodos get y post:
Un explicación muy buena de HTTP también se puede encontrar en: http://www.ntu.edu.sg/home/ehchua/programming/webprogramming/HTTP_Basics.html
HTTP request
Un cliente HTTP debe formar una petición HTTP (request) al servidor de una forma determinada para que sea entendida por el servidor. Cuando Arduino trabaja como cliente hay que programar esta petición correctamente, sino el servidor nos mandará un mensaje de error.
Formación de un HTTP request, esta petición habrá que programar en Arduino:
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
- https://tools.ietf.org/html/rfc2616#section-9.5

Trama en HTTP, fijaros en el uso de cr (retorno de carro – carriage return – ASCII 13) y lf (line feed – nueva linea – ASCII 10): http://www1.ju.edu.jo/ecourse/abusufah/cpe532_Spr06/notes/BookOnLine/HTTP%20Request%20Message.htm
HTTP/1.1 se definió en el estándar RFC2616,que es la más usada actualmente. En junio de 2014 RFC2616 se retiró y HTTP/1.1 se redefinió en RFCs 7230, 7231, 7232, 7233, 7234, and 7235, HTTP/2 está en proceso de definición.
- https://tools.ietf.org/html/rfc2616 (ver página 35)
- https://tools.ietf.org/html/rfc7230 (ver página 19)
Y cuando usar GET o POST?: http://www.w3.org/2001/tag/doc/whenToUseGet.html#checklist
HTTP response
Después de recibir e interpretar el servidor un HTTP request, el servidor debe responder con un mensaje de respuesta:
- http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol#C.C3.B3digos_de_respuesta
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Para cumplir con el protocolo HTTP, arduino debe implementar estas respuestas cuando lo uso como servidor web, como devolución a un request mandado por un cliente como puede ser un browser o navegador. De esta forma puedo implementar en Arduino una web embebida.
Por lo tanto Arduino podemos programarlo para comportarse como cliente, como servidor o como ambos.
Veamos esto gráficamente:

Ejercicio: Ver las tramas HTTP con las funciones de depuración del navegador y también con wireshark, un web sniffer on-line y algún plugin para el navegador.
- WireShark: https://www.wireshark.org/
- Chrome plugin Sniffer: http://5ms.ru/sniffer/
- on-line: http://web-sniffer.me/
Listado de web sniffers: http://scraping.pro/web-sniffers-review/
Servidor Web Embebido en Arduino
Para poder implementar un servidor web embebido en un Arduino e interactuar con él, se debe programar los mensajes http en Arduino para responder al navegador de forma adecuada.
La secuencia que se produce en una web embebida para encender y apagar un led es:
- El navegador manda un http request GET a la IP de Arduino cuando pongo su IP en el navegador. p.e. http://192.168.1.15
- Arduino recibe la petición que comienza por «GET / HTTP/1.1»
- Arduino devuelve el http response con «HTTP/1.0 200K» y luego la web con el código html, haciendo print sobre el cliente ethernet y cierra la comunicación.
- El navegador recibe el http respnse y muestra la web, en este caso un botón.
- Al pulsar el botón en el navegador, el código HTML ya está configurado para mandar una petición POST.
- Arduino recibe la petición que comienza por «POST / HTTP/1.1” y enciende o apaga el led según corresponda.
- Luego Arduino muestra la web con el estado del led actualizado.
Ver este proceso con wireshark o con las herramienta de desarrollador del navegador pulsando F12.
Ver sketch en: https://github.com/jecrespo/aprendiendoarduino-Curso_Arduino_2017/tree/master/Ejercicio40-Boton_Mejorado_DHCP
Diagrama de flujo:
Más información:
Programa botón para diferentes Arduino. Comparar:
- Ethernet: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio27-Boton_Mejorado2_DHCP
- UNO Wifi: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio27-Boton_Mejorado_UNO_WIFI
- Wifi: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio27-Boton_Mejorado_WIFI
Librerías HTTP
Libreria Webduino
Webduino es una librería muy popular que nos permite implementar un servidor web en nuestro Arduino.
La web del creador: https://code.google.com/p/webduino/
El reference de la librería: https://code.google.com/p/webduino/wiki/Documentation
Repositorio de la librería: https://github.com/sirleech/Webduino
Snippet Webduino en el playground: http://playground.arduino.cc/Main/WebduinoFileServer
Para Shields con Microchip ENC28J60 no es válida esta librería puesto que necesita SW adicional para implementar la pila TCP/IP.
Una presentación que explica como funciona: https://docs.google.com/presentation/d/1QUG4XJTK3jKtU-eYUfM1DvUdRaKBrp__LEwZQfz9s6E/edit#slide=id.i0
Hilo de soporte de la librería: http://forum.arduino.cc/index.php/topic,37851.0.html
Ejercicio 29-Webduino Entender cómo funciona la librería y ver el ejemplo webdemo
Luego hacer la aplicación web buzzer.
Streaming: http://arduiniana.org/libraries/streaming/
Class Templates: http://www.cprogramming.com/tutorial/templates.html
Solución en https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio29-Webduino
Otras Librerías
Otras librerías para implementar un servidor web en Arduino:
- uHTTP
- Otro web server: http://playground.arduino.cc/Code/WebServer2
Y una librería para implementar un cliente HTTP:
Librería http client: https://github.com/amcewen/HttpClient