Skip to content

Latest commit

 

History

History
executable file
·
94 lines (72 loc) · 2.93 KB

fileUploads.md

File metadata and controls

executable file
·
94 lines (72 loc) · 2.93 KB

File Uploads

A special case of using form data is handling file uploads.

There are two main form encoding types:

  • application/x-www-form-urlencoded (the default)
  • multipart/form-data

When you wish to include file upload elements, you must choose multipart/form-data as your form's enctype (encoding) type.

All code used below can be seen in action as a complete example at https://github.com/iamjono/perfect-file-uploads.

An example HTML form containing the correct encoding and file input element might be represented like this:

<form 
	method="POST" 
	enctype="multipart/form-data" 
	action="/upload">
	<input type="file" name="filetoupload">
	<br>
	<input type="submit">
</form>

Receiving the File on the Server Side

Because the form is a POST method, we will handle the route with a method: .post:

var routes = Routes()
routes.add(
	method: .post, 
	uri: "/upload", 
	handler: handler)
server.addRoutes(routes)

Once the request has been offloaded to the handler we can:

// Grab the fileUploads array and see what's there
// If this POST was not multi-part, then this array will be empty

if let uploads = request.postFileUploads, uploads.count > 0 {
	// Create an array of dictionaries which will show what was uploaded
	var ary = [[String:Any]]()

	for upload in uploads {
		ary.append([
			"fieldName": upload.fieldName,
			"contentType": upload.contentType,
			"fileName": upload.fileName,
			"fileSize": upload.fileSize,
			"tmpFileName": upload.tmpFileName
			])
	}
	values["files"] = ary
	values["count"] = ary.count
}

As demonstrated above, the file(s) uploaded are represented by the request.postFileUploads array, and the various properties such as fileName, fileSize and tmpFileName can be accessed from each array component.

Note: The files uploaded are placed in a temporary directory. It is your responsibility to move them into the desired location.

So let's create a directory to hold the uploaded files. This directory is outside of the webroot directory for security reasons:

// create uploads dir to store files
let fileDir = Dir(Dir.workingDir.path + "files")
do {
	try fileDir.create()
} catch {
	print(error)
}

Next, inside the for upload in uploads code block, we will create the action for the file to be moved:

// move file
let thisFile = File(upload.tmpFileName)
do {
	let _ = try thisFile.moveTo(path: fileDir.path + upload.fileName, overWrite: true)
} catch {
	print(error)
}

Now the uploaded files will move to the specified directory with the original filename restored.

For more information on file system manipulation, see the Directory Operations and File Operations chapters.