2011-05-31 21 views
6

Estoy tratando de cargar archivos a un Indy (ver 10.5.5) TIdHTTPServer.
He estado buscando soluciones pero hasta ahora no he tenido suerte, lo que encontré fue para versiones anteriores de Indy que no eran compatibles con la versión enviada con Delphi 2010.TIdHTTPServer file upload

Lo que espero sea lograr simplemente carga un archivo usando "multipart/form-data" para el servidor y decodifica , así de sencillo, cualquier ayuda es apreciada.

+1

Para la parte de decodificación MIME, Indy contiene una clase 'TIdDecoderMIME' en la unidad' Protocols \ IdCoderMIME' – mjn

+0

sí, pero no maneja los datos como lo necesito por desgracia ... gracias por su comentario – ComputerSaysNo

+1

10.5 .5 no es muy viejo, pero probaría el actual Indy 10.5.8 versión – mjn

Respuesta

4

Comencé xxm como una forma de crear sitios web con Delphi, y tengo scripts con códigos HTML y Pascal que vuelvo a compilar con solo presionar el botón de actualización del navegador después de realizar los cambios.

Utiliza una interfaz genérica que se "conecta" a IIS, Apache, Internet Explorer, FireFox, y también hay un exe HTTP independiente. La interfaz expone IxxmParameterPostFile en un parámetro cuando se carga un archivo.

Vea un ejemplo en demo 4 Upload.

+1

no es realmente cuestión, sino más bien de el spot, proyecto muy bonito, no puedo creer que no lo haya visto antes. ¿Hay alguna posibilidad de que sea portado a "Free Pascal" para soporte de plataforma cruzada? No tengo suficiente tiempo para "jugar" en este momento , pero seguro le daré más atención a XXM en las próximas semanas. – ComputerSaysNo

+1

La conexión a FreePascal depende de un ComServ.pas decente, que faltaba cada vez que lo verifiqué. Podría tener una puñalada en la creación de un ComServ de código abierto. pas, _if_ Tenía todo el tiempo y dinero del mundo ... –

+0

Te siento Stijn, incluso aunque no puedo cambiar a XXM en este momento, es la opción más cercana a mi pregunta, ¡gracias! – ComputerSaysNo

3

Only suitable solution I can find sin probar personalmente (quisiera saber si esto no te conduce a una solución de trabajo para sus necesidades, y voy a fuego hasta XE y producir algo más elocuente)

+0

solo un FYI, la parte activa de eso es crear un TStream (TFileStream o TMemoryStream), luego llamar a IdHTTP1.Post (, ); – LaKraven

+0

no es exactamente lo que necesito, vea que el problema es que los datos enviados por el navegador también deben decodificarse de MIME a binario. – ComputerSaysNo

+0

ah ... podría valer la pena ajustar su pregunta para aclarar ese requisito :) – LaKraven

8

TIdHTTPServer no es compatible actualmente con multipart/form-data envíos de forma nativa. Eso está en la lista de tareas para Indy 11. Mientras tanto, debe analizar manualmente los datos MIME publicados usando TIdDecoderMIME, como sugirió mjn. Ha habido ejemplos de esto publicados en los foros de Embarcadero e Indy.

+1

Hola, Remy, he logrado averiguarlo ... las demos disponibles no analizan los datos correctamente, dejan el límite final en el archivo ... como una solución temporal en el evento "OnCreatePostStream" del servidor Simplemente creo una secuencia de archivos y en el evento "OnCommandGet" simplemente omito el límite y copio los datos correctos en la "secuencia de archivos final" y parece estar funcionando como necesito al menos por el momento ... – ComputerSaysNo

+0

If se está dejando un límite, entonces no está procesando los datos correctamente. ¿Qué demos estás mirando exactamente? –

+0

http://forums2.atozed.com/viewtopic.php?f=7&t=23732 la segunda publicación es suya, creo (gambit47?), McptEOF no existe en Indy 10.5.5, pero igual traté de subir, a veces (cuando se cargaron archivos grandes, cientos de megs ZIP o archivos RAR) se eliminó el límite; en otros casos, como el límite de PDF se dejó, creo que tiene algo que ver con la combinación CR, LF, CRLF en algún momento al leer el transmitir contenido Actualmente, "OnCreatePostStream" creo una secuencia de archivos, y "OnCommandGet" utilizo ReadLnFromStream para omitir las primeras 4 líneas (información de límites y archivos) y leo hasta ... – ComputerSaysNo

1

http://www.synaptica.info/2014/01/31/tidhttpserver-decode-content-type-multipartform-data/

hago una simple carga de varias partes de esta manera:

unidades usadas:

interface 
uses 
    System.SysUtils, System.Classes, Web.Win.Sockets, IdBaseComponent, 
    IdComponent, IdCustomTCPServer, IdCustomHTTPServer, IdHTTPServer, IdContext, 
    IdTCPServer,System.Generics.Collections, Data.DB, Datasnap.DBClient,IdHeaderList,idGlobal, 
    IdIntercept,IdMessage,IdMessageCoderMIME,IdMessageCoder,IdGlobalProtocols; 

el código de ese bucle en el contenido MIME:

procedure TdmNet.IdHTTPServerCommandGet(AContext: TIdContext; 
    ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
Var 
    ms : TMemoryStream; 
    newdecoder, Decoder: TIdMessageDecoder; 
    boundary, startboundary : String; 
    msgEnd : Boolean; 
    tmp : String; 
    I : Integer; 
    fname : String; 
    tsValues : TStringList; 

begin 
    i := 0; 


    if pos('upload',lowercase(ARequestInfo.Document)) > 0 then 
    begin 
    If ARequestInfo.PostStream = nil then 

     AResponseInfo.ContentText := '<HTML><BODY>unparsed:' + ARequestInfo.UnparsedParams + 
     '<br>Encoding:' + ARequestInfo.ContentEncoding + ARequestInfo.RawHeaders.Values['Content-Type'] + 
     '<br>HashCode:' + IntToStr(ARequestInfo.GetHashCode) + 
     '<br>Params:' + ARequestInfo.Params.Text + ' -->stream nullo<br></BODY><HTML>' 
    Else 
     ARequestInfo.PostStream.Position := 0; 
     msgEnd := False; 


     boundary := ExtractHeaderSubItem(ARequestInfo.ContentType, 'boundary',QuoteHTTP); 
     startboundary := '--' + boundary; 
     repeat 
     tmp := ReadLnFromStream(ARequestInfo.PostStream, -1, True); 
     until tmp = startboundary; 

     decoder := TIdMessageDecoderMIME.Create(nil); 
     TIdMessageDecoderMIME(decoder).MIMEBoundary := boundary; 
     tsValues := TStringList.Create; 

     try 
      repeat 
      decoder.SourceStream := ARequestInfo.PostStream; 
      decoder.FreeSourceStream := false; 
      decoder.ReadHeader; 
      inc(I); 
      case Decoder.PartType of 
      mcptAttachment,mcptText : begin 

           ms := TMemoryStream.Create; 
           ms.Position := 0; 
           newdecoder := Decoder.ReadBody(ms,msgEnd); 
           tmp := Decoder.Headers.Text; 
           fname := decoder.Filename; 
           decoder.Free; 
           decoder := newdecoder; 
           if decoder <> nil then 
           TIdMessageDecoderMIME(decoder).MIMEBoundary := boundary; 
           sleep(100); 
           if fname <> '' then 
           begin 
           ms.SaveToFile(fname); 

           //msgEnd := true; 
           end 
           else 
           begin 
           ms.SaveToFile(inttostr(i) + '.txt'); 
           end; 
           ms.Free; 
          end; 
      mcptIgnore: Begin 
         try 
          FreeAndNil(decoder); 
          decoder := TIdMessageDecoderMIME.Create(nil); 
          TIdMessageDecoderMIME(decoder).MIMEBoundary := boundary; 
         finally 
          ms.Free; 
         end; 
         End; 
      mcptEOF: begin FreeAndNil(decoder); msgEnd := True end; 
      end; 

      until (decoder = nil) or(msgEnd); 
     finally 
     if decoder <> nil then 
     decoder.Free; 

     end; 


     AResponseInfo.ContentText := AResponseInfo.ContentText + '</BODY><HTML>'; 

     AResponseInfo.ContentText := '<HTML><BODY>unparsed:' + ARequestInfo.UnparsedParams + 
     '<br>Encoding:' + ARequestInfo.ContentEncoding + '<br>Conte' + ARequestInfo.RawHeaders.Values['Content-Type'] + 
     '<br>HashCode:' + IntToStr(ARequestInfo.GetHashCode) + 
     '<br>Params:' + ARequestInfo.Params.Text + ' -->stream nullo<br></BODY><HTML>'; 
    end 
    Else 
    Begin 
    AResponseInfo.ContentText := 
    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ' + #10#13 + 
    '<html xmlns="http://www.w3.org/1999/xhtml">                     ' + #10#13 + 
    '<head>                              ' + #10#13 + 
    '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />              ' + #10#13 + 
    '<title>Pagina di prova</title>                        ' + #10#13 + 
    '</head>                              ' + #10#13 + 
    '                               ' + #10#13 + 
    '<body>                              ' + #10#13 + 
    '<h1>Test multipart from <a href="www.synaptica.info">Synaptica Srl</a> </h1> <BR><BR>              ' + #10#13 + 
    '<form action="upload" method="post" enctype="multipart/form-data">                        ' + #10#13 + 
    '<p>key                              ' + #10#13 + 
    ' <input type="text" name="key" id="key" />                     ' + #10#13 + 
    '</p>                              ' + #10#13 + 
    '<p>group                              ' + #10#13 + 
    ' <input type="text" name="group" id="key" />                     ' + #10#13 + 
    '</p>                              ' + #10#13 + 
    '                               ' + #10#13 + 
    '<label for="file">Filename:</label>                       ' + #10#13 + 
    '<label for="file">' + ARequestInfo.Document + '</label>                       ' + #10#13 + 
    '<input type="file" name="file" id="file" />                     ' + #10#13 + 
    '<br />                              ' + #10#13 + 
    '<input type="submit" name="submit" value="Submit" />                  ' + #10#13 + 
    '</form></p>                             ' + #10#13 + 
    '</body>                              ' + #10#13 + 
    '</html>                              '; 
    End; 
1

Parece yo que este es un problema perenne. He analizado todo tipo de propuestas en Internet y no hay nada comparable a MsMultipartparser.pas en oferta. Lamentablemente, no funciona para Unicode.

¿Por qué alguien mucho más inteligente que yo reescribe MsMultipartparser.pas y nos ahorra un montón de problemas?

Indy - no funciona.

IPWorks - parece que solo le da nombre (s) de archivo y más. No se puede averiguar cómo obtener el archivo en sí.

alcínoe - no hay instrucciones de instalación deja explicación solamente y no parece funcionar para XE8 o Delphi 10

Miré a varios otros, pero todos ellos son poco prácticas.

Cuestiones relacionadas