Ver Mensaje Individual
  #4  
Antiguo 10-05-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Reputación: 24
seoane Va por buen camino
Entiendo que lo que quieres es mandar un archivo a un servidor web desde una aplicacion de delphi. Pero me surge la pregunta de quien sera el encargado de recibirlo, me explico, es muy sencillo mandar el contendio del archivo utilizando el metodo post, pero tal cual sin utilizar el formato que usan los navegadores para hacerlo ("multipart/form-data"), pero si del lado del servidor el encargado de recibir el archivo es un cgi creado por nosotros no deberia de haber problema para que entendiera lo que estamos mandando.

Pongamos un poco de codigo:
Código Delphi [-]
uses  WinInet;

function SubirArchivo(Servidor, Cgi, Archivo: string; Puerto: Word): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hReq: HINTERNET;
  Context: DWORD;
  Mem: TMemoryStream;
begin
  Context:= 0;
  Result := FALSE; 
  hNet := InternetOpen('Agente', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Servidor),Puerto,nil,nil,INTERNET_SERVICE_HTTP,0,Context);
    if (hCon <> nil) then
    begin
      hReq:= HttpOpenRequest(hCon,'POST',PChar(Cgi),nil,nil,nil,
        INTERNET_FLAG_RELOAD,Context);
      if (hReq <> nil) then
      begin
        Mem:= TMemoryStream.Create;
        try
          try
            Mem.LoadFromFile(Archivo);
            HttpSendRequest(hReq,nil,0,Mem.Memory,Mem.Size);
          except end;
        finally
          Mem.Free;
        end;
        InternetCloseHandle(hReq);
      end;
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;

El metodo que describo aqui arriba mandaria los datos tal cual, sin codificarlos ni tratarlos de ninguna manera. Asi que del lado del servidor deberiamos de tener un cgi que supiera como le estamos mandando los datos y que supìera interpretarlo.

Aqui te propongo una solucion, habria que modificarla un poco segun tus necesidades, pero te puede dar una idea. Es un cgi, lo he probado en un servidor apache y me funciona bien:

Código Delphi [-]
program Upload;

uses
  Windows,
  Sysutils;

function Decode(s: string): string;
var
  i: integer;
  Ch: integer;
begin
  result := '';
  i := 1;
  while i <= Length(s) do
  begin
    if copy(s, i, 1) = '%' then
    begin
      Ch := StrToIntDef('$' + copy(s, i + 1, 2), -1);
      if (Ch > 0) and (Ch < 256) then
        result := result + Char(Ch);
      inc(i, 2);
    end
    else
      result := result + copy(s, i, 1);
    inc(i);
  end;
end;

function StdWrite(Output: THandle; Str: string): boolean;
var
  Escritos: Cardinal;
begin
  if WriteFile(Output,PChar(Str)^,Length(Str),Escritos,nil) then
    Result:= Escritos <> Cardinal(Length(Str))
  else Result:= FALSE;
end;

function StdWriteln(Output: THandle; Str: string): boolean;
begin
  Result:= StdWrite(Output,Str+#13#10);
end;

function GetEnvVar(Nombre: string): string;
var
  Str: PChar;
  Len: Integer;
begin
  Len:= GetEnvironmentVariable(PChar(Nombre),nil,0);
  if Len > 0 then
  begin
    GetMem(Str,Len+1);
    try
      GetEnvironmentVariable(PChar(Nombre),Str,Len);
      Result:= String(Str);
    finally
      FreeMem(Str);
    end;
  end else Result:= '';
end;

function Guardar(Input: THandle; Archivo: string): boolean;
var
  hFile: THandle;
  Leidos, Escritos, Total: Cardinal;
  Buffer: array[0..1024] of Byte;
  Root: string;
begin
  Total:= StrToIntDef(GetEnvVar('CONTENT_LENGTH'),0);
  if Total > 0 then
  begin
    // Aqui colocamos el directorio donde se colocaran los archivos recibidos
    Root:= 'C:\';
    Archivo:= ExpandFileName(Root+Archivo);
    if StrLIComp(PChar(Root),PChar(Archivo),Length(Root))=0 then
    begin
      hFile:= CreateFile(PChar(Archivo),GENERIC_WRITE,0,nil,CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,0);
      if hFile <> INVALID_HANDLE_VALUE then
      begin
        repeat
          if not ReadFile(Input, Buffer, sizeof(Buffer), Leidos, nil) then
            break;
          if not WriteFile(hFile,Buffer,Leidos,Escritos,nil) then
            break;
          Dec(Total,Leidos);
        until (Leidos = 0) or (Total = 0);
        CloseHandle(hFile);
      end;
    end;
    Result:= Total = 0;
  end else Result:= TRUE;
end;

procedure Vamos;
var
  Output: THandle;
  Input: THandle;
  QueryString: string;
begin
  Output:= GetStdHandle(STD_OUTPUT_HANDLE);
  Input:= GetStdHandle(STD_INPUT_HANDLE);
  if (Output <> INVALID_HANDLE_VALUE) and (Input <> INVALID_HANDLE_VALUE) then
  begin
    QueryString:= Decode(GetEnvVar('QUERY_STRING'));
    StdWriteln(Output,'Content-type: text/html');
    StdWriteln(Output,'');
    if Guardar(Input,QueryString) then
      StdWriteln(Output,'OK')
    else
      StdWriteln(Output,'ERROR');
  end;
end;

begin
  Vamos;
end.

Y por ultimo solo nos queda utilizar la primera funcion para mandar el archivo, de esta manera:
Código Delphi [-]
SubirArchivo('www.tuservidor.com','/cgi-bin/upload.exe?archivo.txt','archivo.txt',80);

Espero que te sirva, aunque si lo que necesitas es subirlo con formato, pues viene siendo lo mismo pero dandole formato a los datos antes de mandarlos.
Responder Con Cita