diff --git a/src/base-apis.js b/src/base-apis.js
index 086477365..bf2381790 100644
--- a/src/base-apis.js
+++ b/src/base-apis.js
@@ -1071,6 +1071,10 @@ MatrixBaseApis.prototype.searchUserDirectory = function(opts) {
* @param {string=} opts.name Name to give the file on the server. Defaults
* to file.name.
*
+ * @param {boolean=} opts.includeFilename if false will not send the filename,
+ * e.g for encrypted file uploads where filename leaks are undesirable.
+ * Defaults to true.
+ *
* @param {string=} opts.type Content-type for the upload. Defaults to
* file.type, or applicaton/octet-stream.
*
diff --git a/src/http-api.js b/src/http-api.js
index 82548855e..b753d6bf8 100644
--- a/src/http-api.js
+++ b/src/http-api.js
@@ -118,6 +118,10 @@ module.exports.MatrixHttpApi.prototype = {
* @param {string=} opts.name Name to give the file on the server. Defaults
* to file.name.
*
+ * @param {boolean=} opts.includeFilename if false will not send the filename,
+ * e.g for encrypted file uploads where filename leaks are undesirable.
+ * Defaults to true.
+ *
* @param {string=} opts.type Content-type for the upload. Defaults to
* file.type, or applicaton/octet-stream.
*
@@ -152,6 +156,9 @@ module.exports.MatrixHttpApi.prototype = {
opts = {};
}
+ // default opts.includeFilename to true (ignoring falsey values)
+ const includeFilename = opts.includeFilename !== false;
+
// if the file doesn't have a mime type, use a default since
// the HS errors if we don't supply one.
const contentType = opts.type || file.type || 'application/octet-stream';
@@ -272,10 +279,26 @@ module.exports.MatrixHttpApi.prototype = {
}
});
let url = this.opts.baseUrl + "/_matrix/media/v1/upload";
- url += "?access_token=" + encodeURIComponent(this.opts.accessToken);
- url += "&filename=" + encodeURIComponent(fileName);
+
+ const queryArgs = [];
+
+ if (includeFilename && fileName) {
+ queryArgs.push("filename=" + encodeURIComponent(fileName));
+ }
+
+ if (!this.useAuthorizationHeader) {
+ queryArgs.push("access_token="
+ + encodeURIComponent(this.opts.accessToken));
+ }
+
+ if (queryArgs.length > 0) {
+ url += "?" + queryArgs.join("&");
+ }
xhr.open("POST", url);
+ if (this.useAuthorizationHeader) {
+ xhr.setRequestHeader("Authorization", "Bearer " + this.opts.accessToken);
+ }
xhr.setRequestHeader("Content-Type", contentType);
xhr.send(body);
promise = defer.promise;
@@ -283,9 +306,11 @@ module.exports.MatrixHttpApi.prototype = {
// dirty hack (as per _request) to allow the upload to be cancelled.
promise.abort = xhr.abort.bind(xhr);
} else {
- const queryParams = {
- filename: fileName,
- };
+ const queryParams = {};
+
+ if (includeFilename && fileName) {
+ queryParams.filename = fileName;
+ }
promise = this.authedRequest(
opts.callback, "POST", "/upload", queryParams, body, {