Hola comunidad, hoy les comparto mi clase con el cual podran descargar archivos desde C++.
Primero un poco de teoria:
El proceso que realiza un programa normal como un navegador web (
firefox,
chrome,
etc...) para descargar un archivo es el siguiente:
- Envia un paquete con la ruta del archivo deseado en cuestion
- Recibe la respuesta del servidor el cual contiene la informacion del archivo, como el tamaño y tipo de archivo entre otra informacion
- Continua leyendo del socket hasta que no se encuentren mas bytes para leer o logre el tamaño del archivo
El paquete enviando por el navegador puede ser parecido a este:
GET /descargas/archivos/archivo.zip HTTP/1.1
Host: www.website.com
User-Agent: Juanker v2
La primera linea contiene el comando
GET(
https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods (https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods)), usado para obtener datos del recurso especificado, en este caso:
/descargas/archivos/archivo.zip Seguido de
HTTP/1.1 que es la version de
HTTP a usar en la comunicacion. Luego cada dato enviado al servidor va en este formato:
Campo : ValorEl campo
Host lleva el nombre de dominio al cual se desea enviar la peticion. Este campo es muy util en servidores que almacenan multiples dominios, logrando asi identificar a cual
dominio virtual(
https://en.wikipedia.org/wiki/Virtual_hosting (https://en.wikipedia.org/wiki/Virtual_hosting)) pertenece la peticion enviada por el navegador.
Y el campo
User-Agent, aloja el nombre del navegador y otra informacion del mismo, ejemplo:
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0Despues de enviar el paquete recibiria una respuesta parecida a esta:
HTTP/1.1 200 OK
Date: Sat, 09 Dec 2025 03:10:00 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 80160806
Content-Type: application/zip
Siendo la primer linea:
HTTP/1.1 200 OK
El codigo de respuesta de la ultima peticion, en este caso
200, significa que la peticion fue aceptada, he aqui una lista de los codigos que puede retornar un servidor http https://en.wikipedia.org/wiki/List_of_HTTP_status_codes (https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). Los siguientes campos muestran informacion del sevidor como:
Fecha
Date: Sat, 09 Dec 2025 03:10:00 GMT
Version de servidor
Server: Apache/2.4.29 (Ubuntu)
Tambien informacion del recurso solicitado
/descargas/archivos/archivo.zipTamaño en bytes
Content-Length: 80160806
Tipo de recurso
Content-Type: application/zip
A esta respuesta del servidor se le conoce como
Cabecera o
Headers, seguido de esta informacion sigue el contenido del archivo solicitado en cuestion. Un ejemplo sencillo seria solicitar un archivo de texto plano
/descargas/archivos/archivo.txt, se recibe una respuesta como esta:
HTTP/1.1 200 OK
Date: Sat, 09 Dec 2025 03:10:00 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 86
Content-type: text/plain
Este es un archivo de texto
que contiene varias lineas
informacion y mas information
Nota que esta vez el campo
Content-type cambio a
text/plain ya que este es el tipo de archivo que se ha solicitado. Extensiones MIME https://tools.ietf.org/html/rfc2046 (https://tools.ietf.org/html/rfc2046)
Para armar el paquete usando codigo se podria realizar asi:
char Packet[] = "GET /descargas/archivos/archivo.zip HTTP/1.1\r\n"\
"Host: www.website.com\r\n"\
"User-Agent: Juanker v2\r\n\r\n";
El
\r\n al final de cada linea(a excepcion de la ultima que contiene
\r\n\r\n) es requerido en cada paquete
HTTP que se envia o recibe usando este protocolo.
\r (
Carriage Return), es un control de caracter usado para resetear la posicion del dispositivo al inicio de la linea de texto,
\n (
New Line), es un caracter usado para indicar el final de la linea actual e iniciar una nueva. El contenido del archivo que hemos solicitado al sevidor viene seguido de los ultimos 4 caracteres (
\r \n \r \n).
Resumiendo, el navegador envia la peticion y recibe la respuesta con los datos del archivo solicitado y empieza a escribir al archivo todo lo que reciba despues de (
\r \n \r \n).
El proyecto https://github.com/d3adlym1nd/Http-Download (https://github.com/d3adlym1nd/Http-Download)
Como usarlo?
//Se crea el objeto
Downloader down;
//Llamada a la funcion Download con la url como parametro
if(down.Download("http://www.website.com/ruta/al/fichero.rar"){
std::cout<<"Descarga satisfactoria\n";
}
La clase
Downloader realiza toda la "magia", se crea un nuevo objeto y se llama la funcion Download que recibe como parametro la url del archivo a descargar, el puerto puede ir junto con la url
http://www.website.com:8888, tambien sigue redirecciones y hace uso de
openssl para realizar descargas de servidores que utilizen
SSL, sigo mejorandola y cualquier comentario es bien apreciado.
Tambien trae una barra de carga ;D.