Not sending headers with upload request

Fixes #2728
This commit is contained in:
JC Brand 2021-11-21 11:55:31 +01:00
parent fa562cabae
commit 2af758e66d
3 changed files with 26 additions and 4 deletions

View File

@ -14,6 +14,7 @@
- #2647: Singleton mode doesn't work
- #2704: Send button doesn't work in a multi-user chat
- #2725: Send new presence status to all connected MUCs
- #2728: Not sending headers with upload request
- Emit a `change` event when a configuration setting changes
- 3 New configuration settings:

View File

@ -4,8 +4,7 @@ import log from '../../log.js';
import { _converse, api, converse } from '../../core.js';
import { getOpenPromise } from '@converse/openpromise';
const u = converse.env.utils;
const { Strophe } = converse.env;
const { Strophe, sizzle, u } = converse.env;
/**
* Mixin which turns a `ModelWithContact` model into a non-MUC message. These can be either `chat` messages or `headline` messages.
@ -192,6 +191,18 @@ const MessageMixin = {
return api.sendIQ(iq);
},
getUploadRequestMetadata (stanza) {
const headers = sizzle(`slot[xmlns="${Strophe.NS.HTTPUPLOAD}"] put header`, stanza);
// https://xmpp.org/extensions/xep-0363.html#request
// TODO: Can't set the Cookie header in JavaScipt, instead cookies need
// to be manually set via document.cookie, so we're leaving it out here.
return {
'headers': headers
.map(h => ({ 'name': h.getAttribute('name'), 'value': h.textContent }))
.filter(h => ['Authorization', 'Expires'].includes(h.name))
}
},
async getRequestSlotURL () {
const { __ } = _converse;
let stanza;
@ -205,8 +216,9 @@ const MessageMixin = {
'is_ephemeral': true
});
}
const slot = stanza.querySelector('slot');
const slot = sizzle(`slot[xmlns="${Strophe.NS.HTTPUPLOAD}"]`, stanza).pop();
if (slot) {
this.upload_metadata = this.getUploadRequestMetadata(stanza);
this.save({
'get': slot.querySelector('get').getAttribute('url'),
'put': slot.querySelector('put').getAttribute('url')
@ -222,6 +234,7 @@ const MessageMixin = {
uploadFile () {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = async () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
log.info('Status: ' + xhr.status);
@ -275,6 +288,7 @@ const MessageMixin = {
};
xhr.open('PUT', this.get('put'), true);
xhr.setRequestHeader('Content-type', this.file.type);
this.upload_metadata.headers?.forEach(h => xhr.setRequestHeader(h.name, h.value));
xhr.send(this.file);
}
};

View File

@ -449,6 +449,8 @@ describe("XEP-0363: HTTP File Upload", function () {
</iq>`);
const promise = u.getOpenPromise();
spyOn(XMLHttpRequest.prototype, 'setRequestHeader');
spyOn(XMLHttpRequest.prototype, 'send').and.callFake(async () => {
const message = view.model.messages.at(0);
const el = await u.waitUntil(() => view.querySelector('.chat-content progress'));
@ -461,7 +463,12 @@ describe("XEP-0363: HTTP File Upload", function () {
promise.resolve();
});
_converse.connection._dataRecv(mock.createRequest(stanza));
return promise;
await promise;
expect(XMLHttpRequest.prototype.setRequestHeader.calls.count()).toBe(2);
expect(XMLHttpRequest.prototype.setRequestHeader.calls.all()[0].args[0]).toBe('Content-type');
expect(XMLHttpRequest.prototype.setRequestHeader.calls.all()[0].args[1]).toBe('image/jpeg');
expect(XMLHttpRequest.prototype.setRequestHeader.calls.all()[1].args[0]).toBe('Authorization');
expect(XMLHttpRequest.prototype.setRequestHeader.calls.all()[1].args[1]).toBe('Basic Base64String==');
}));
});
});