Class: cWebHttpMultipartFormdataHandler

Properties  Events  Methods    Index of Classes

Can be used to handle HTTP requests in the multipart/form-data format

Hierarchy

cObject
---cBaseWebComponent
------cWebHttpHandler
---------cWebHttpMultipartFormdataHandler

Library: Web Application Class Library

Package: cWebHttpMultipartFormdataHandler.pkg

Description

This class can be used to handle HTTP requests in the multipart/form-data format. It subclasses the cWebHttpHandler class and extends it with functionality for parsing this request and handling the data in the different fields that are passed. The class is built to handle the HTTP request in chunks, which allows it to handle big posts without reading all the data into memory at once.

To parse a request, send ParseMultipartFormData from OnHttpPost. This should be done before any data is read from the request using RequestDataString or RequestDataUChar. ParseMultipartFormData will call the events OnField, OnFileStart, OnFileChunk and OnFileFinished for the fields & files that are found in the request. The object or subclass are expected to implement these to process the data.

Sample

The example below shows how to handle a simple file upload request:

Use cWebHttpMultipartFormDataHandler.pkg

//  With the cWebHttpHandler you handle complete HTTP requests.
Object oHandleFilePost is a cWebHttpMultipartFormdataHandler
    
    //  The psPath property determines the path in the URL for which requests will be handled.
    Set psPath to "FilePost"
    //  Use psVerbs to filter based on the HTTP Verbs. 
    Set psVerbs to "POST"

    //  Property to temporary store the output channel
    Property Integer piOutChannel -1
        
    Procedure OnHttpPost String sPath String sContentType String sAcceptType Integer iSize
        Boolean bSuccess
        Integer iChnl
        
        Get ParseMultipartFormData to bSuccess
        
        If (bSuccess) Begin
            Send SetResponseStatus 200 "Upload succesfull" 1
            Send OutputString "Succesfully written file!"
        End
        Else Begin
            // Cleanup on failure (delete partial files or so)
            Send SetResponseStatus 500 (psParseError(Self)) (piParseErrorCode(Self))            
        End
    End_Procedure
    
    Procedure OnFileStart String sFieldName String sFileName String sContentType Boolean  ByRef bAbort
        String sPath
        Boolean bExists
        Integer iChnl
        
        //  Open a file for writing
        If (sFieldName = "myfile") Begin
            Get psDataPath of (phoWorkspace(ghoApplication)) to sPath
            Move (sPath + "\Uploads\" + sFileName) to sPath
            
            File_Exist sPath bExists
            
            If (not(bExists)) Begin
                Move (Seq_New_Channel()) to iChnl
                Direct_Output channel iChnl ("binary:" + sPath)
                Set piOutChannel to iChnl
            End
            Else Begin
                Send SetResponseStatus 500 "File already exists" 4
                Move True to bAbort
            End
        End        
    End_Procedure

    Procedure OnFileChunk String sFieldName UChar[]  ByRef ucData
        Integer iChnl
        
        //  Write the chunks to the opened file
        If (sFieldName = "myfile") Begin
            Get piOutChannel to iChnl
            If (iChnl >= 0) Begin
                Write channel iChnl ucData
            End
        End
    End_Procedure
    
    Procedure OnFileFinished String sFieldName
        Integer iChnl
        
        //  Close when finished
        If (sFieldName = "myfile") Begin
            Get piOutChannel to iChnl
            If (iChnl >= 0) Begin
                Close_Output channel iChnl
                Send Seq_Release_Channel iChnl
                
                Set piOutChannel to -1
            End
        End
    End_Procedure
End_Object
The following HTML page can be used with example above to do a file upload:
<html>
<head>
    <title>Upload file</title>
</head>
<body>
    <form action="FilePost" method="post" enctype="multipart/form-data">
        Select file: <input type="file" name="myfile"><br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>