Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save PatrickHeneise/8f2c72c16c4e68e829e58ade64aba553 to your computer and use it in GitHub Desktop.
Save PatrickHeneise/8f2c72c16c4e68e829e58ade64aba553 to your computer and use it in GitHub Desktop.
Google Cloud Function to stream a file from multipart/form-data to Google Cloud Storage
/**
* Copyright (c) 2022 Zentered OÛ, patrick@zentered.co
* This code is licensed under the terms of the MIT license
*
* This code demonstrates how to create a Google Cloud Function to receive
* a file sent via `multipart/form-data`. The file is then streamed directly
* to Google Cloud Storage, without using a temporary file.
*
* The function returns any `fields` sent as FormData
*
*
* Useful links:
* - https://googleapis.dev/nodejs/storage/latest/File.html#createWriteStream
* - https://github.com/mscdex/busboy#readme
*
* Inspiration:
* - https://gist.github.com/msukmanowsky/c8daf3720c2839d3c535afc69234ab9e
* - https://stackoverflow.com/a/68666478/459329
* - https://stackoverflow.com/a/65749616/459329
*/
'use strict'
import Busboy from 'busboy'
import { Storage } from '@google-cloud/storage'
function asyncBusboy(req, res) {
return new Promise((resolve, reject) => {
const storage = new Storage()
const bucket = storage.bucket(process.env.BUCKET)
const fields = []
const busboy = Busboy({
headers: req.headers,
limits: {
fileSize: 10 * 1024 * 1024
}
})
busboy.on('field', (key, value) => {
fields[key] = value
})
busboy.on('file', (name, file, fileInfo) => {
const { mimeType } = fileInfo
const destFile = bucket.file(fileName)
const writeStream = destFile.createWriteStream({
metadata: {
contentType: fileInfo.mimeType,
metadata: {
originalFileName: fileInfo.filename
}
}
})
file.pipe(writeStream)
})
busboy.on('close', function () {
return resolve({ fields })
})
if (req.rawBody) {
busboy.end(req.rawBody)
} else {
req.pipe(busboy)
}
})
}
export const multipartForm = async (req, res) => {
if (req.method !== 'POST') {
return res.status(405).end()
}
try {
const { fields } = await bb(req, res, myBucket)
console.log(fields)
} catch (err) {
console.error(err)
return res.status(500).send(err)
}
return res.status(200).send()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment