Skip to content

Instantly share code, notes, and snippets.

@imiric
Forked from Rob--W/html5-formdata-polyfilll.js
Last active January 14, 2021 10:04
Show Gist options
  • Save imiric/f759d3ba5ad7c6bb4eed81c7b596af31 to your computer and use it in GitHub Desktop.
Save imiric/f759d3ba5ad7c6bb4eed81c7b596af31 to your computer and use it in GitHub Desktop.
FormData polyfill for k6
/*
* FormData polyfill for k6
* (c) 2014 Rob Wu <rob@robwu.nl>
* License: MIT
*
* This simplifies the creation of multipart/form-data requests from k6 scripts.
* It was adapted from the original version by Rob Wu to remove references of
* XMLHttpRequest and File related code which isn't supported in k6.
**/
(function(exports) {
if (exports.FormData) {
// Don't replace FormData if it already exists
return;
}
// Export variable to the global scope
exports.FormData = FormData;
function FormData() {
// Force a Constructor
if (!(this instanceof FormData)) return new FormData();
// Generate a random boundary - This must be unique with respect to the form's contents.
this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36);
var internal_data = this.data = [];
/**
* Internal method.
* @param inp String | ArrayBuffer | Uint8Array Input
*/
this.__append = function(inp) {
var i = 0, len;
if (typeof inp == 'string') {
for (len = inp.length; i < len; ++i)
internal_data.push(inp.charCodeAt(i) & 0xff);
} else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */
if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */
inp = new Uint8Array(inp);
for (len = inp.byteLength; i < len; ++i)
internal_data.push(inp[i] & 0xff);
}
};
}
/**
* @param name String Key name
* @param value String|typed array|ArrayBuffer Value
* @param filename String Optional File name (when value is not a string).
**/
FormData.prototype.append = function(name, value, filename) {
if (this.__endedMultipart) {
// Truncate the closing boundary
this.data.length -= this.boundary.length + 6;
this.__endedMultipart = false;
}
if (arguments.length < 2) {
throw new SyntaxError('Not enough arguments');
}
var part = '--' + this.boundary + '\r\n' +
'Content-Disposition: form-data; name="' + name + '"';
if (typeof value.byteLength == 'number') {
// Duck-typed typed array or array buffer
part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n';
part += 'Content-Type: application/octet-stream\r\n\r\n';
this.__append(part);
this.__append(value);
part = '\r\n';
} else {
part += '\r\n\r\n' + value + '\r\n';
}
this.__append(part);
};
/**
* Close finishes the multipart message and writes the trailing boundary end line to the output.
**/
FormData.prototype.close = function() {
if (!this.__endedMultipart) this.__append('--' + this.boundary + '--\r\n');
this.__endedMultipart = true;
};
/**
* Return an ArrayBuffer with the contents of the data processed so far.
**/
FormData.prototype.buffer = function() {
return new Uint8Array(this.data).buffer;
};
})(this || self);
import http from 'k6/http';
import { FormData } from './formdata.js';
const logo1 = open('logo1.png', 'b');
const logo2 = open('logo2.png', 'b');
export default function () {
const fd = new FormData();
fd.append('files', logo1, 'logo1.png');
fd.append('files', logo2, 'logo2.png');
fd.close(); // write the trailing boundary
const res = http.post('http://127.0.0.1:9000/postmultipart', fd.buffer(),
{ headers: { 'Content-Type': 'multipart/form-data; boundary=' + fd.boundary }});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment