2011-05-31 3 views
6

Я пытаюсь загрузить файлы в Indy (версия 10.5.5) TIdHTTPServer.
Я искал решения, но пока не повезло, что я нашел для старых версий Indy, которые не были совместимы с версией, поставляемой с Delphi 2010.Загрузка файла TIdHTTPServer

Что я надеюсь достичь просто загрузите файл с использованием «multipart/form-data» на сервер и декодировать он, простой, любая помощь приветствуется.

+1

Для части MIME-декодирования Indy содержит класс 'TIdDecoderMIME' в блоке' Protocols \ IdCoderMIME' – mjn

+0

да, но он не обрабатывает данные, поскольку мне это нужно, к сожалению ... спасибо за ваш комментарий – ComputerSaysNo

+1

10.5 .5 не очень старый, но я бы попробовал текущий Indy 10.5.8 версия – mjn

ответ

4

Я начал xxm как способ создания сайтов с помощью Delphi, и после внесения изменений с помощью кода HTML и Pascal скомпилировался с помощью кнопки обновления браузера.

Он использует общий интерфейс, который «подключается к» IIS, Apache, Internet Explorer, FireFox, и есть автономный HTTP exe. Интерфейс предоставляет IxxmParameterPostFile параметр при загрузке файла.

См., Например, demo 4 Upload.

+1

это не вопрос, но в значительной степени пятно, очень приятный проект, я не могу поверить, что раньше этого не видел. Любой шанс, что он портирован на «Free Pascal» для кросс-платформенной поддержки? У меня нет достаточно времени, чтобы «играть» в данный момент , но я уверен, что в ближайшие пару недель вам будет больше внимания. – ComputerSaysNo

+1

Портирование на FreePascal зависит от достойного ComServ.pas, который отсутствовал в последний раз, когда я проверял. У меня есть удар по созданию ComServ с открытым исходным кодом. pas, _if_ У меня было все время и деньги мира ... –

+0

Я чувствую, что вы Stijn, даже «Я не могу переключиться на XXM прямо сейчас, это самый близкий вариант для моего вопроса, спасибо! – ComputerSaysNo

3

Only suitable solution I can find без лично тестирования (дайте мне знать, если это не приведет вас к рабочему раствору для ваших нужд, и я вспылить Х и производить что-то более красноречивое)

+0

просто FYI, активная часть которого создает TStream (TFileStream или TMemoryStream), а затем вызывает IdHTTP1.Post (, ); – LaKraven

+0

Это не совсем то, что мне нужно, см. Проблему в том, что данные, отправляемые браузером, также необходимо декодировать из MIME в двоичный. – ComputerSaysNo

+0

ах ... возможно, стоит подправить ваш вопрос, чтобы уточнить это требование :) – LaKraven

8

TIdHTTPServer в настоящее время не поддерживает multipart/form-data представления изначально. То есть в списке задач Indy 11. В то же время вы должны разобрать опубликованные данные MIME вручную, используя TIdDecoderMIME, как предположил mjn. Были примеры того, что было опубликовано на форумах Embarcadero и Indy.

+1

Hi Remy, мне удалось это выяснить ... доступные демоверсии не корректно обрабатывают данные, они оставляют конечную границу в файле ... как временное решение в событии OnCreatePostStream сервер Я просто создаю поток файлов, а на мероприятии «OnCommandGet» я просто пропускаю границу и копирую правильные данные в «финальном потоке файлов», и, похоже, он работает по мере необходимости, по крайней мере на данный момент ... – ComputerSaysNo

+0

граница остается позади, тогда вы неправильно обрабатываете данные. На какие демонстрации вы точно смотрите? –

+0

http://forums2.atozed.com/viewtopic.php?f=7&t=23732 второй пост - ваш, я считаю (gambit47?), McptEOF не существует в Indy 10.5.5, но я все же пытался загрузить, иногда (когда большие файлы были загружены, были удалены сотни мегабайтных ZIP или RAR-файлов), в других случаях, таких как PDF, граница осталась, я считаю, что она имеет какое-то отношение к комбинации CR, LF, CRLF в какой-то момент, когда вы читаете поток. В настоящее время «OnCreatePostStream» я создаю поток файлов, а «OnCommandGet» использую ReadLnFromStream для обхода первых 4 строк (информация о границах и файлах) и читайте до тех пор, пока ... – ComputerSaysNo

1

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

я простая многочастная загрузка, как это:

используемых единицы:

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; 

код, петля на содержании мима:

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

кажется, что это постоянная проблема. Я просмотрел всевозможные предложения в Интернете, и нет ничего сопоставимого с предлагаемым MsMultipartparser.pas. К сожалению, это не работает для Unicode.

Почему кто-то намного умнее меня переписывает MsMultipartparser.pas и спасает нас всех от ужаса?

Indy - не работает.

IPWorks - похоже, просто дает вам имя файла и т. Д. Не удается решить, как получить файл.

Alcinoe - нет инструкции по установке не говоря уже объяснения и не похоже на работу для X Е8 или Delphi 10

Я посмотрел на несколько других, но все они непрактичны.