ReadBody and Binary data

Giganews Newsgroups
Subject: ReadBody and Binary data
Posted by:  Leonardo_M._Ramé
Date: Fri, 10 Apr 2009

Hi, In a previous post I'd read you'll fix a problem with
TIdMessageDecoderMIME to allow reading binary data.

In an embedded web server, I'm trying to allow my users to upload files
using multipart/form-data, then in OnCommandGet, I decode the multipart
data, and save the uploaded file.

The problem is my program only receives a part of approximately 1mb of
the uploaded files.

Here is the code I copied from an old message by Remy Lebeu:

procedure TForm1.GetCommand(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
    Decoder, NewDecoder: TIdMessageDecoder;
    DestStream: TStream;
    IdPostStream, IdDestStream: TStream;
    MsgEnd: Boolean;
begin
    if ARequestInfo.Document = '/' then
    begin
        AResponseInfo.ResponseNo := 200;
        AResponseInfo.ContentText :=
            '<html>' + #13#10 +
            '<body>' + #13#10 +
            '<form method="post" action="/upload"
enctype="multipart/form-data">' + #13#10 +
            '<input type="file" name="myFile">' + #13#10 +
            '<input type="submit">' + #13#10 +
            '</form>' + #13#10 +
            '</body>' + #13#10 +
            '</html>';
    end
    else
    if ARequestInfo.Document = '/upload' then
    begin
        // if not TextIsSame(ARequestInfo.ContentType,
'multipart/form-data') then
        //    raise Exception.Create('Invalid post type');
        Decoder := TIdMessageDecoderMIME.Create(nil);
        try
            ARequestInfo.PostStream.Position := 0;
            Decoder.SourceStream := ARequestInfo.PostStream;
            Decoder.FreeSourceStream := False;
            TIdMessageDecoderMIME(Decoder).MIMEBoundary := Decoder.ReadLn;
            MsgEnd := False;
            repeat
                Decoder.ReadHeader;
                if Decoder.PartType = mcptAttachment then
                begin
                    DestStream := TFileStream.Create('c:\' +
ExtractFileName(Decoder.Filename), fmCreate);
                    try
                        IdDestStream := TMemoryStream.Create;
                        try
                            NewDecoder :=
Decoder.ReadBody(IdDestStream, MsgEnd);
                            try
                                IdDestStream.Position := 0;

TMemoryStream(IdDestStream).SaveToStream(DestStream);
                                // use Decoder.Headers,
Decoder.Filename, and IdDestStream as needed...
                            finally
                                FreeAndNil(Decoder);
                            end;
                        finally
                            FreeAndNil(IdDestStream);
                        end;
                    finally
                        FreeAndNil(DestStream);
                    end;
                end;
            until MsgEnd or (Decoder = nil);
        finally
            FreeAndNil(Decoder);
        end;
    end else begin
        AResponseInfo.ResponseNo := 404;
        AResponseInfo.ContentText :=
            '<html>' + #13#10 +
            '<body>' + #13#10 +
            'Page not found:<br>' + #13#10 +
            '<b>' + ARequestInfo.Document + '</b>' + #13#10 +
            '</body>' + #13#10 +
            '</html>';
    end;
end;

Thanks in advance,
Leonardo.

Replies