Underc0de

Programación General => C / C++ => Mensaje iniciado por: d3adly en Junio 05, 2020, 01:21:04 AM

Título: Descargar archivos usando C++
Publicado por: d3adly en Junio 05, 2020, 01:21:04 AM
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:

El paquete enviando por el navegador puede ser parecido a este:
Código (text) [Seleccionar]

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 : Valor
El 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.0

Despues de enviar el paquete recibiria una respuesta parecida a esta:
Código (text) [Seleccionar]

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:
Código (text) [Seleccionar]
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
Código (text) [Seleccionar]
Date: Sat, 09 Dec 2025 03:10:00 GMT
Version de servidor
Código (text) [Seleccionar]
Server: Apache/2.4.29 (Ubuntu)

Tambien informacion del recurso solicitado /descargas/archivos/archivo.zip
Tamaño en bytes
Código (text) [Seleccionar]
Content-Length: 80160806
Tipo de recurso
Código (text) [Seleccionar]
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:
Código (text) [Seleccionar]
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:
Código (cpp) [Seleccionar]

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?
Código (cpp) [Seleccionar]

//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.
Título: Re:Descargar archivos usando C++
Publicado por: Gabriela en Junio 05, 2020, 02:54:02 AM
Tu post:

Sencillo y muy claro de entender.
Idóneo para aprender, desde un marco teórico documentado, y con un código práctico, de fácil lectura.

Excelente aporte, como otros que nos has dejado.

Gabriela
Título: Re:Descargar archivos usando C++
Publicado por: d3adly en Junio 05, 2020, 03:00:30 AM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Sencillo y muy claro de entender.
Idóneo para aprender, desde un marco teórico documentado, y con el código práctico, de fácil lectura.

Gracias @Gabriela (https://underc0de.org/foro/index.php?action=profile;u=37488) esa era la idea.