Created
July 29, 2022 16:57
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2022 Zentered OÛ, [email protected] | |
* 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