Compare commits
2 Commits
1e6bb27404
...
8f500c590e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f500c590e | ||
|
|
18a875a764 |
@ -210,6 +210,31 @@ class DoodstreamUploader {
|
|||||||
// Fallback: try fetching from upload page HTML
|
// Fallback: try fetching from upload page HTML
|
||||||
const pageRes = await this._fetch(BASE_URL + '/?op=upload');
|
const pageRes = await this._fetch(BASE_URL + '/?op=upload');
|
||||||
const html = await pageRes.text();
|
const html = await pageRes.text();
|
||||||
|
|
||||||
|
// Current doodstream format: the upload server is the action of the
|
||||||
|
// multipart upload form, e.g.
|
||||||
|
// <form name="file" enctype="multipart/form-data"
|
||||||
|
// action="https://xxx.cloudatacdn.com/upload/01?SESSID" ...>
|
||||||
|
// <input type="hidden" name="sess_id" value="SESSID">
|
||||||
|
// The node is assigned per page-load and the action carries a session token
|
||||||
|
// in its query string that matches the page's hidden sess_id. We refresh
|
||||||
|
// this.sessId from THIS page so the multipart sess_id field matches the node
|
||||||
|
// URL — login-time and node tokens otherwise diverge and the upload comes
|
||||||
|
// back with an empty filecode.
|
||||||
|
const actionMatch = html.match(/action=["'](https?:\/\/[^"']+\/upload\/[^"']*)["']/i);
|
||||||
|
if (actionMatch) {
|
||||||
|
const url = actionMatch[1].replace(/&/g, '&'); // un-escape HTML entities in query
|
||||||
|
const freshSess = html.match(/name=["']sess_id["'][^>]*value=["']([a-zA-Z0-9]+)["']/);
|
||||||
|
if (freshSess) {
|
||||||
|
this.sessId = freshSess[1];
|
||||||
|
} else {
|
||||||
|
_debugLog('upload_server: form action found but no sess_id on page; keeping existing sessId');
|
||||||
|
}
|
||||||
|
_debugLog(`upload_server: using form action node=${url} sess=${this.sessId}`);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy fallback: srv_url JS variable (older doodstream theme).
|
||||||
const srvMatch = html.match(/srv_url['":\s]+['"]?(https?:\/\/[^'">\s]+)['"]?/i);
|
const srvMatch = html.match(/srv_url['":\s]+['"]?(https?:\/\/[^'">\s]+)['"]?/i);
|
||||||
if (srvMatch) return srvMatch[1];
|
if (srvMatch) return srvMatch[1];
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "3.3.25",
|
"version": "3.3.26",
|
||||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -87,6 +87,27 @@ test('getUploadServer: falls back to srv_url in upload-page HTML', async () => {
|
|||||||
assert.equal(await up._getUploadServer(), 'https://node7.cloudatacdn.com/upload/01');
|
assert.equal(await up._getUploadServer(), 'https://node7.cloudatacdn.com/upload/01');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getUploadServer: parses current form-action node and refreshes sess_id from the same page', async () => {
|
||||||
|
const up = new DoodstreamUploader();
|
||||||
|
up.sessId = 'stale-from-login';
|
||||||
|
up._fetch = async (url) => {
|
||||||
|
if (/op=upload_server/.test(url)) return fakeRes('<html>not json</html>');
|
||||||
|
return fakeRes('<form name="file" enctype="multipart/form-data" action="https://n9.cloudatacdn.com/upload/01?FRESH123" method="post"><input type="hidden" name="sess_id" value="FRESH123"></form>');
|
||||||
|
};
|
||||||
|
const url = await up._getUploadServer();
|
||||||
|
assert.equal(url, 'https://n9.cloudatacdn.com/upload/01?FRESH123');
|
||||||
|
assert.equal(up.sessId, 'FRESH123'); // critical: form-field token must match the node URL token
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getUploadServer: un-escapes & in the form-action query string', async () => {
|
||||||
|
const up = new DoodstreamUploader();
|
||||||
|
up._fetch = async (url) => {
|
||||||
|
if (/op=upload_server/.test(url)) return fakeRes('<html>not json</html>');
|
||||||
|
return fakeRes('<form name="file" enctype="multipart/form-data" action="https://n9.cloudatacdn.com/upload/01?a=1&b=2" method="post"></form>');
|
||||||
|
};
|
||||||
|
assert.equal(await up._getUploadServer(), 'https://n9.cloudatacdn.com/upload/01?a=1&b=2');
|
||||||
|
});
|
||||||
|
|
||||||
test('getUploadServer: throws (no silent dead fallback) when discovery fails', async () => {
|
test('getUploadServer: throws (no silent dead fallback) when discovery fails', async () => {
|
||||||
const up = new DoodstreamUploader();
|
const up = new DoodstreamUploader();
|
||||||
up._fetch = async () => fakeRes('<html><body>login required</body></html>', { status: 200 });
|
up._fetch = async () => fakeRes('<html><body>login required</body></html>', { status: 200 });
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user