diff --git a/lib/doodstream-upload.js b/lib/doodstream-upload.js index cbfeee6..bb40c3a 100644 --- a/lib/doodstream-upload.js +++ b/lib/doodstream-upload.js @@ -247,7 +247,10 @@ class DoodstreamUploader { } 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}`); + // Capture the form's real fields so upload() submits exactly what the + // browser would (file_title, submit_btn, …) instead of stale hardcoded ones. + this._uploadFormFields = this._parseUploadFormFields(html); + _debugLog(`upload_server: using form action node=${url} sess=${this.sessId} fields=${Object.keys(this._uploadFormFields).join(',')}`); return url; } @@ -269,6 +272,35 @@ class DoodstreamUploader { ); } + /** + * Replicate the non-file fields of doodstream's CURRENT upload form so our + * POST matches what the browser actually submits. Doodstream dropped the old + * `utype` field and added file_title / fakefilepc / submit_btn; submitting a + * stale/incomplete field set can make the node accept the bytes but skip + * registration (→ empty result form). We parse the live form rather than + * hardcode, so we track whatever fields doodstream uses now. The file input + * (type=file) is excluded — the file is streamed separately. + */ + _parseUploadFormFields(html) { + const fields = {}; + if (!html) return fields; + // Narrow to the upload form (its action points at a /upload/ node). + const formMatch = html.match(/
`; + const f = up._parseUploadFormFields(html); + assert.equal(f.sess_id, 'TOK'); + assert.equal(f.fakefilepc, ''); + assert.equal(f.file_title, ''); + assert.ok('submit_btn' in f); + assert.ok(!('file' in f), 'the file input must be excluded (streamed separately)'); +}); + +test('_parseUploadFormFields returns {} for markup without a form', () => { + const up = new DoodstreamUploader(); + assert.deepEqual(up._parseUploadFormFields('