🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
3 messages
3 total messages Started by noel Mon, 24 Oct 2005 18:10
Help on how to decode multipart/form-data
#3353
Author: noel
Date: Mon, 24 Oct 2005 18:10
37 lines
2056 bytes
Hello All.

I am building a HTTP server and trying to decode the data from an HTML 
form. The form action is POST and it has a File field.
The form is sent as a "multipart/form-data" instead of the more familiar
"application/x-www-form-urlencoded" form.

the TIdHTTPRequestInfo -> Params does not contain the parameters as 
usual as these are transfered as the different parts of the message ...

+----
  Content-type: multipart/form-data, boundary=AaB03x

         --AaB03x
         content-disposition: form-data; name="field1"

         Joe Blow
         --AaB03x
         content-disposition: form-data; name="pics"
         Content-type: multipart/mixed, boundary=BbC04y

         --BbC04y
         Content-disposition: attachment; filename="file1.txt"
+---------+

My question is how do i decode the different parts from the 
TidHTTPServer OnCommandGet handler ...
Do i need to use another component ?

There is a TIdMultiPartFormDataStream that is used to
send such POST request as a client ... but i need to do the reverse
that is to receive and decode ...

Any help anyone ?
Many thanks !

No�l Bouchard
Re: Help on how to decode multipart/form-data
#3368
Author: Remy Lebeau (TeamB)
Date: Mon, 24 Oct 2005 23:59
119 lines
5189 bytes
"noel" <noel@teledata.qc.ca> wrote in message
news:435d2270$1@newsgroups.borland.com...

> the TIdHTTPRequestInfo -> Params does not contain
> the parameters as usual

Correct, because it is not supposed to.  The Params property is not meant to
be used with "multipart/form-data" transmissions.

You need to use the OnCreatePostStream event to create an instance of your
own TStream object.  If you do not, then TIdHTTPServer uses its own TStream
to receive the data and then frees the TStream prior to triggering the
OnCommandGet event.  You need access to that TStream in order to process a
"multipart/form-data" transmission.  You can access it via the
Request->PostStream in the OnCommandGet event handler.

> My question is how do i decode the different parts from the
> TidHTTPServer OnCommandGet handler ...

You have to decode the data manually.  You can use TIdMessageCoderMIME for
that.  For example (untested):


    void __fastcall TForm1::IdHTTPServer1CreatePostStream(TIdPeerThread
*AThread, TStream* &VPostStream)
    {
        VPostStream = new TMemoryStream;
    }

    bool __fastcall TForm1::DecodeFormData(const AnsiString &Header, TStream
*Stream)
    {
        bool MsgEnd = false;

        TIdMessageDecoderMIME *decoder = new TIdMessageDecoderMIME(NULL);
        try
        {
            decoder->MIMEBoundary =
TIdMIMEBoundary::FindBoundary(__classid(TIdMIMEBoundary), Header);

            ((TIdStream*)Stream)->ReadLn();

            do
            {
                decoder->ReadHeader();
                switch( decoder->PartType )
                {
                    case mcptUnknown:
                        throw Exception("Unknown form data detected");
                        break;

                    case mcptText:
                    {
                        AnsiString tmp =
decoder->Headers->Values["Content-Type"];
                        AnsiString ContentType = Fetch(tmp, ";");

                        TMemoryStream *DataStrm = new TMemoryStream;
                        try
                        {
                            decoder = decoder->ReadBody(DataStrm, MsgEnd);

                            if( AnsiSameText(ContentType,
"multipart/mixed") )
                                DecodeFormData(tmp, DataStrm);
                            else
                                // use DataStrm as needed...
                        }
                        __finally {
                            delete DataStrm;
                        }
                        break;
                    }

                    case mcptAttachment:
                    {
                        AnsiString FileName =
ExtractFileName(decoder->FileName);
                        if( !FileName.IsEmpty() )
                            FileName = ("c:\\some folder\\" + FileName);
                        else
                            FileName = MakeTempFilename("c:\\some
folder\\");

                        TFileStream *FileStrm = new TFileStream(FileName,
fmCreate);
                        try {
                            decoder = decoder->ReadBody(FileStrm, MsgEnd);
                        }
                        __finally {
                            delete FileStrm;
                        }
                        break;
                }
                while( (decoder) && (!MsgEnd) );
            }
            __finally
            {
                if( decoder )
                    delete decoder;
            }
        }
    }

    void __fastcall TForm1::IdHTTPServer1CommandGet(TIdPeerThread *AThread,
TIdHTTPRequestInfo *ARequestInfo, TIdHTTPResponseInfo *AResponseInfo)
    {
        AnsiString tmp = ARequestInfo->Headers->Values["Content-Type"];
        AnsiString ContentType = Fetch(tmp, ";");

        if( AnsiSameText(ContentType, "multipart/form-data") )
            DecodeFormData(hdr, ARequestInfo->PostStream);
        else
            // use request data as needed...
    }


Gambit
Re: Help on how to decode multipart/form-data
#3365
Author: Hans Galema
Date: Tue, 25 Oct 2005 00:04
29 lines
1946 bytes
noel wrote:

> I am building a HTTP server and trying to decode the data from an HTML 
> form. The form action is POST and it has a File field.
> The form is sent as a "multipart/form-data" instead of the more familiar
> "application/x-www-form-urlencoded" form.

Please show the complete html source for that <form> ... </form> and
tell the name of the file the user choosed.

>  Content-type: multipart/form-data, boundary=AaB03x
> 
>         --AaB03x
>         content-disposition: form-data; name="field1"
> 
>         Joe Blow

   field1=Joe Blow

Which browser did you use ? Are the results the same with
different browsers ?

>         content-disposition: form-data; name="pics"
>         Content-disposition: attachment; filename="file1.txt"

Is that original ? One time 'content-' and once 'Content-' ?
Please copy and paste instead of typing in.

Hans.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads