httpSaveFilesFromUpload()
The function returns the HTTP content of a Blob variable that was received from an HTTP client via an HTML form. The function copies the content of this blob variable (a file) into a directory.
Synopsis
int
httpSaveFilesFromUpload(
blob
content,
string
boundary,
string
targetdirectory,
mapping
formdata);
Parameter
Parameter | Meaning |
---|---|
content | The content that was selected via an HTML form. |
boundary | The boundary parameter is the separator defined by the HTTP header. It defines a string for the HTTP content to separate multiple content parts of the upload. See example further below. |
targetdirectory |
The parameter targetdirectory defines an HTTP server local directory, where the uploaded files are saved when the function is called. e.g. "D:\\Data\\" |
formdata |
The mapping contains the form data:
The second mapping contains
The rest of the mapping keys represent the header information of a form field. Example: "fileupload" : mapping 4 items WCCOActrl3: "success" : 1 WCCOActrl3: "content" : "hosts.txt" WCCOActrl3: "Content-Type" : "text/plain" WCCOActrl3: "Content-Disposition" : "form-data; name=\"fileupload\"; filename=\"D:\\hosts.txt\"" |
Return value
The function httpSaveFilesFromUpload returns 0 on success, otherwise -1.
Error
Wrong or missing arguments.
Description
The function returns the HTTP content of a Blob variable that was received from an HTTP client via an HTML form. The function copies the content of this blob variable (a file) into a directory.
WinCC OA does not support the upload type multipart/mixed. The upload of several files via one POST request is, however, possible. For POST request, see variable "formDoc" in the example below.
To improve the security on the client:
- Limit the selection of the possible directory.
- Limit the possible HTML file type.
To improve the security on the server:
- Limit the selection of the possible target directory.
- By using the function blobGetValue() you can query the content and can check the file name, the extension or the content type before saving a file. After saving: You can scan the target directory by using an antivirus software, check the file by name or extension and depending on the result, delete or copy the file to the final target directory.
Example
The following example starts an HTTP server at the port 12000 without authentication, creates a form with input fields for the selection of the data that should be copied. The example executes the function httpSaveFilesFromUpload in order to copy data.
#uses "CtrlHTTP"
int MAXLENGTH = 100 * 1024 * 1024;
// 100 MB
main()
{
// starts the HTTP Server at Port 12000 without authentication,
httpServer(FALSE,12000);
httpSetMaxContentLength(MAXLENGTH);
// Register Upload handler
// Use http://localhost:12000/filetest URL, in order to upload data
// httpConnect registers the functions "filetest1" and "fileupload" as Web resource
// under the names "/filetest" and "/" as well as "/fileupload" and "/query_2"
int k = httpConnect("filetest1","/filetest");
DebugN("httpConnect:", k);
int l = httpConnect("fileupload","/query_2");
DebugN("httpConnect:", l);
}
// See rfc1867 for detailed information on form-based file uploads in HTML
string filetest1()
{
// Form example with two fields of types "file" and "submit".
//This means for selecting files and copying the selected data.
string formDoc = "<html><head><title>File Upload</title>"
"<body><h1>"
"<form action=\"/query_2\" method=\"post\" enctype=\"multipart/form-data\">"
"<input type=\"file\" name=\"dateiupload\"> "
"<input type=\"submit\" name=\"btn[upload]\"> "
"<td><font face=\"Arial\"><input type=\"text\" size=\"40\" name=\"folder\" value=\"Dokumente/neu\"></font></td></form>"
"</body></html>";
return formDoc;
DebugN("Formdoc:", formDoc);
// Returns the form
}
void fileupload(blob content, string user, string ip, dyn_string headernames, dyn_string headervalues, int connIdx)
{
int pos =0;
int len = bloblen(content);
string val;
blobGetValue(content,pos,val,len);
DebugN(val);
DebugN("blobGetValue - content:", content);
string contentType = httpGetHeader(connIdx, "Content-Type");
int pos = strpos(contentType, "boundary=");
// Returns the string boundary= from the string "contentType
if (pos >= 0)
{
string boundary = substr(contentType, pos + 9);
// The "boundary" parameter is a separator defined by the HTTP header, substr cuts the string "contentType" off as of "pos" + 9 characters
DebugN("Boundary:", boundary, contentType);
// Outputs the content of the "boundary" parameter as well as contentType
mapping result;
int retval = httpSaveFilesFromUpload(content, boundary, "D:\\Test\\", result);
DebugN("result", result);
for(int i = 1; i <= mappinglen(result); i++) DebugN("mappingGetValue", i, "is =" + mappingGetValue(result,i));
//Copies the content of the Content variable into the directory "D:/Test"
dyn_string fNames = getFileNames("D:\\Test\\");
DebugN("File names:",fNames);
copyAllFiles("D:\\Test\\", "D:\\Test\\Target\\");
DebugN("return", retval);
}
// parse content & extract file(s)
// use info from header Content-Type: multipart/form-data; boundary=BOUNDARY
// now search for BOUNDARY\r\n
// next line holds
// Content-Disposition: form-data; name="myfile"; filename="FILENAME"\r\n
// Content-Type: MIMETYPE\r\n
// \r\n
// here comes the content up to the next boundary (with trailing \r\n)
// BOUNDARY
}
Assignment
CTRL PlugIn
Availability
CTRL, UI