elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  [DELPHI] DownLoadFile con WinSock
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [DELPHI] DownLoadFile con WinSock  (Leído 2,089 veces)
Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
[DELPHI] DownLoadFile con WinSock
« en: 4 Octubre 2010, 15:54 pm »

En una tarde de aburrimiento, se me ocurrió hacer una función para descargar archivos de un servidor web utilizando Sockets.
Es una función alternativa a la API URLDownLoadToFile o a la API de WinInet.

Código
  1. uses SysUtils, Classes, Windows, Forms, WinSock;
  2.  
  3. {Función: GetDomainName
  4. Ejemplo: Si le pasas "http://foro.elhacker.net/post.html;board=18.0"
  5. como parámetro te devuelve "foro.elhacker.net"}
  6. function GetDomainName(const URL: AnsiString): AnsiString;
  7. var
  8. P1: integer;
  9. begin
  10.   P1:= Pos('http://', LowerCase(URL));
  11.   if P1 > 0 then
  12.    begin
  13.      result:= Copy(lowercase(URL), P1 + 7, Length(URL) - P1 - 6);
  14.      P1:= Pos('/', result);
  15.      if P1 > 0 then
  16.        result:= Copy(result, 0, P1 - 1);
  17.    end else
  18.      begin
  19.        P1:= Pos('/', URL);
  20.        if P1 > 0 then
  21.          result:= Copy(Lowercase(URL), 0, P1 - 1)
  22.        else result:= LowerCase(URL);
  23.      end;
  24. end;
  25.  
  26. {Función: GetFileWeb
  27. Ejemplo: Si le pasas "http://foro.elhacker.net/post.html;board=18.0"
  28. como parámetro te devuelve "post.html;board=18.0"}
  29. function GetFileWeb(const URL: AnsiString): AnsiString;
  30. var
  31. P1: integer;
  32. begin
  33.   P1:= Pos('http://', LowerCase(URL));
  34.   if P1 > 0 then
  35.    begin
  36.      result:= Copy(lowercase(URL), P1 + 7, Length(URL) - P1 - 6);
  37.      P1:= Pos('/', result);
  38.      if P1 > 0 then
  39.        result:= Copy(result, P1, Length(result) - P1 + 1);
  40.    end else
  41.      begin
  42.        P1:= Pos('/', URL);
  43.        if P1 > 0 then
  44.          result:= Copy(LowerCase(URL), P1, Length(URL) - P1 + 1)
  45.        else result:= LowerCase(URL);
  46.      end;
  47. end;
  48.  
  49. {Función: CleanHTTP
  50. Esta función se encarga de eliminiar las líneas de control
  51. que emplea el protocolo HTTP. El archivo comienza despues de #13#10#13#10.
  52.  
  53. Un ejemplo de las líneas que vamos a quitar con esta función:
  54.  
  55. HTTP/1.0 200 OK
  56. Date: Sat, 07 Aug 2010 23:25:05 GMT
  57. Expires: -1
  58. Cache-Control: private, max-age=0
  59. Content-Type: text/html; charset=ISO-8859-1
  60. Set-Cookie: PREF=ID=45985543825451c0:TM=1281223505:LM=1281223505:S=kPYwkz3GOI3idLv6; expires=Mon, 06-Aug-2012 23:25:05 GMT; path=/; domain=.google.es
  61. Set-Cookie: NID=37=rPl51eNebbKvxz3Abvlpje8AT-qMszIbpmDR-zJJjYlwRie55cmev5KE45t4kBPVmhsHPpWUqBwzwqI4rsndihEbd0OtrMJfMohVYI0lfxJ3U1uchrbJMA4SUVh2-uNz; expires=Sun, 06-Feb-2011 23:25:05 GMT; path=/; domain=.google.es; HttpOnly
  62. Server: gws
  63. X-XSS-Protection: 1; mode=block
  64. }
  65. procedure CleanHttp(var Mem: TMemoryStream);
  66. var
  67. i: integer;
  68. Separator: array [0..3] of AnsiChar;
  69. Mem2: TMemoryStream;
  70. begin
  71.  if Assigned(Mem) then
  72.    begin
  73.      for i := 0 to Mem.Size - 1 do
  74.        begin
  75.          Mem.Seek(i, 0);
  76.          Mem.Read(Separator, 4);
  77.          if (Separator[0] = #13) and (Separator[1] = #10) and (Separator[2] = #13)
  78.              and (Separator[3] = #10) then
  79.                begin
  80.                  Mem2:= TMemoryStream.Create;
  81.                  Mem.Seek(i + 4, 0);
  82.                  Mem2.CopyFrom(Mem, Mem.Size - I - 4);
  83.                  Mem:= Mem2;
  84.                  break;
  85.                end;
  86.        end;
  87.    end;
  88. end;
  89.  
  90.  
  91. {Función DownLoadFile
  92. URL: La dirección del archivo que vas a descargar.
  93. FileName: La ruta donde vas a guardar el archivo
  94. ProcessMessages: Por defecto está a True, hace que no se bloquee
  95. la aplicación con el bucle. Puedes cambiar su valor a False o eliminar la línea
  96. "if ProcessMessages then Application.ProcessMessages;" y los uses "Forms" si vas a
  97. trabajar en modo consola
  98.  
  99. Devuelve True si tiene éxito}
  100. function DownLoadFile(const URL: AnsiString; FileName: String; ProcessMessages: boolean = true): boolean;
  101. var
  102. WSA: TWSAData;
  103. Sock: TSocket;
  104. Hostent: PHostent;
  105. Ip: ^Integer;
  106. ReturnCode, i: integer;
  107. RHost: sockaddr_in;
  108. Http: AnsiString;
  109. szBuffer: array [0..1023] of AnsiChar;
  110. Stream: TMemoryStream;
  111. begin
  112. result:= false;
  113.  If WSAStartup(MakeWord(2,2), WSA) = 0 then
  114.    begin
  115.      Sock:= SOCKET(AF_INET, SOCK_STREAM, 0);
  116.      if Sock <> INVALID_SOCKET then
  117.          Hostent:= GetHostByName(PAnsiChar(GetDomainName(URL)));
  118.          if Hostent <> nil then
  119.            begin
  120.              Ip:= @Hostent.h_addr_list^[0];
  121.              RHost.sin_family:= AF_INET;
  122.              RHost.sin_port:= htons(80);
  123.              RHost.sin_addr.S_addr:= ip^;
  124.              if Connect(Sock, RHost, Sizeof(RHost)) = 0 then
  125.                begin
  126.                  Http:= 'GET ' + GetFileWeb(URL) + '   HTTP/1.0'#13#10 +
  127.                  'Host: ' + GetDomainName(URL) +  #13#10#13#10;
  128.                  send(Sock, Pointer(Http)^, Length(Http), 0);
  129.  
  130.                  try
  131.                  Stream:= TMemoryStream.Create;
  132.                    repeat
  133.                      if ProcessMessages then Application.ProcessMessages;
  134.                      FillChar(szBuffer, SizeOf(szBuffer), 0);
  135.                      ReturnCode:= recv(Sock, szBuffer, sizeof(szBuffer), 0);
  136.                      if ReturnCode > 0 then
  137.                        Stream.Write(szBuffer, ReturnCode);
  138.                    until ReturnCode <= 0;
  139.                  CleanHttp(Stream);
  140.                  if Stream.Size > 0 then
  141.                     begin
  142.                        result:= true;
  143.                        Stream.SaveToFile(FileName);
  144.                     end;
  145.                  finally
  146.                    Stream.Free;
  147.                  end;
  148.  
  149.                  ShutDown(Sock, SD_BOTH);
  150.                  CloseSocket(Sock);
  151.                end;
  152.            end;
  153.    end;
  154.  WSACleanUp;
  155. end;
  156.  

Un ejemplo de uso:

Código
  1. DownLoadFile('http://www.google.es', 'C:\google.html');
  2.  

Saludos.


« Última modificación: 4 Octubre 2010, 15:58 pm por Khronos14 » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Progresos de la descarga en VB con My.Computer.Network.DownloadFile
.NET (C#, VB.NET, ASP)
lord_Sirikon 4 5,171 Último mensaje 27 Diciembre 2010, 01:16 am
por Keyen Night
DownloadFile [Delphi]
Programación General
Khronos14 0 3,288 Último mensaje 24 Enero 2011, 00:01 am
por Khronos14
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines