cObject
---cBaseWebComponent
------cWebHttpHandler
---------cWebHttpMultipartFormDataHandler
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.
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>