Fix ComfyUI generation for non-relative paths
| @@ -65,6 +65,7 @@ | |||
| 65 | "simple-git": "^3.19.1", | 65 | "simple-git": "^3.19.1", |
| 66 | "slidetoggle": "^4.0.0", | 66 | "slidetoggle": "^4.0.0", |
| 67 | "tiktoken": "^1.0.16", | 67 | "tiktoken": "^1.0.16", |
| 68 | "url-join": "^5.0.0", | ||
| 68 | "vectra": "^0.2.2", | 69 | "vectra": "^0.2.2", |
| 69 | "wavefile": "^11.0.0", | 70 | "wavefile": "^11.0.0", |
| 70 | "webpack": "^5.95.0", | 71 | "webpack": "^5.95.0", |
| @@ -7053,6 +7054,15 @@ | |||
| 7053 | "punycode": "^2.1.0" | 7054 | "punycode": "^2.1.0" |
| 7054 | } | 7055 | } |
| 7055 | }, | 7056 | }, |
| 7057 | "node_modules/url-join": { | ||
| 7058 | "version": "5.0.0", | ||
| 7059 | "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", | ||
| 7060 | "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", | ||
| 7061 | "license": "MIT", | ||
| 7062 | "engines": { | ||
| 7063 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||
| 7064 | } | ||
| 7065 | }, | ||
| 7056 | "node_modules/utf8-byte-length": { | 7066 | "node_modules/utf8-byte-length": { |
| 7057 | "version": "1.0.4", | 7067 | "version": "1.0.4", |
| 7058 | "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", | 7068 | "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", |
| @@ -55,6 +55,7 @@ | |||
| 55 | "simple-git": "^3.19.1", | 55 | "simple-git": "^3.19.1", |
| 56 | "slidetoggle": "^4.0.0", | 56 | "slidetoggle": "^4.0.0", |
| 57 | "tiktoken": "^1.0.16", | 57 | "tiktoken": "^1.0.16", |
| 58 | "url-join": "^5.0.0", | ||
| 58 | "vectra": "^0.2.2", | 59 | "vectra": "^0.2.2", |
| 59 | "wavefile": "^11.0.0", | 60 | "wavefile": "^11.0.0", |
| 60 | "webpack": "^5.95.0", | 61 | "webpack": "^5.95.0", |
| @@ -1112,7 +1112,7 @@ function onHrSecondPassStepsInput() { | |||
| 1112 | 1112 | ||
| 1113 | function onComfyUrlInput() { | 1113 | function onComfyUrlInput() { |
| 1114 | // Remove trailing slashes | 1114 | // Remove trailing slashes |
| 1115 | extension_settings.sd.comfy_url = String($('#sd_comfy_url').val() ?? '').replace(/\/$/, ''); | 1115 | extension_settings.sd.comfy_url = String($('#sd_comfy_url').val()); |
| 1116 | saveSettingsDebounced(); | 1116 | saveSettingsDebounced(); |
| 1117 | } | 1117 | } |
| 1118 | 1118 | ||
| @@ -6,6 +6,7 @@ import fetch from 'node-fetch'; | |||
| 6 | import sanitize from 'sanitize-filename'; | 6 | import sanitize from 'sanitize-filename'; |
| 7 | import { sync as writeFileAtomicSync } from 'write-file-atomic'; | 7 | import { sync as writeFileAtomicSync } from 'write-file-atomic'; |
| 8 | import FormData from 'form-data'; | 8 | import FormData from 'form-data'; |
| 9 | import urlJoin from 'url-join'; | ||
| 9 | 10 | ||
| 10 | import { delay, getBasicAuthHeader, tryParse } from '../util.js'; | 11 | import { delay, getBasicAuthHeader, tryParse } from '../util.js'; |
| 11 | import { jsonParser } from '../express-common.js'; | 12 | import { jsonParser } from '../express-common.js'; |
| @@ -364,8 +365,7 @@ const comfy = express.Router(); | |||
| 364 | 365 | ||
| 365 | comfy.post('/ping', jsonParser, async (request, response) => { | 366 | comfy.post('/ping', jsonParser, async (request, response) => { |
| 366 | try { | 367 | try { |
| 367 | const url = new URL(request.body.url); | 368 | const url = new URL(urlJoin(request.body.url, '/system_stats')); |
| 368 | url.pathname += '/system_stats'; | ||
| 369 | 369 | ||
| 370 | const result = await fetch(url); | 370 | const result = await fetch(url); |
| 371 | if (!result.ok) { | 371 | if (!result.ok) { |
| @@ -381,8 +381,7 @@ comfy.post('/ping', jsonParser, async (request, response) => { | |||
| 381 | 381 | ||
| 382 | comfy.post('/samplers', jsonParser, async (request, response) => { | 382 | comfy.post('/samplers', jsonParser, async (request, response) => { |
| 383 | try { | 383 | try { |
| 384 | const url = new URL(request.body.url); | 384 | const url = new URL(urlJoin(request.body.url, '/object_info')); |
| 385 | url.pathname += '/object_info'; | ||
| 386 | 385 | ||
| 387 | const result = await fetch(url); | 386 | const result = await fetch(url); |
| 388 | if (!result.ok) { | 387 | if (!result.ok) { |
| @@ -400,8 +399,7 @@ comfy.post('/samplers', jsonParser, async (request, response) => { | |||
| 400 | 399 | ||
| 401 | comfy.post('/models', jsonParser, async (request, response) => { | 400 | comfy.post('/models', jsonParser, async (request, response) => { |
| 402 | try { | 401 | try { |
| 403 | const url = new URL(request.body.url); | 402 | const url = new URL(urlJoin(request.body.url, '/object_info')); |
| 404 | url.pathname += '/object_info'; | ||
| 405 | 403 | ||
| 406 | const result = await fetch(url); | 404 | const result = await fetch(url); |
| 407 | if (!result.ok) { | 405 | if (!result.ok) { |
| @@ -429,8 +427,7 @@ comfy.post('/models', jsonParser, async (request, response) => { | |||
| 429 | 427 | ||
| 430 | comfy.post('/schedulers', jsonParser, async (request, response) => { | 428 | comfy.post('/schedulers', jsonParser, async (request, response) => { |
| 431 | try { | 429 | try { |
| 432 | const url = new URL(request.body.url); | 430 | const url = new URL(urlJoin(request.body.url, '/object_info')); |
| 433 | url.pathname += '/object_info'; | ||
| 434 | 431 | ||
| 435 | const result = await fetch(url); | 432 | const result = await fetch(url); |
| 436 | if (!result.ok) { | 433 | if (!result.ok) { |
| @@ -448,8 +445,7 @@ comfy.post('/schedulers', jsonParser, async (request, response) => { | |||
| 448 | 445 | ||
| 449 | comfy.post('/vaes', jsonParser, async (request, response) => { | 446 | comfy.post('/vaes', jsonParser, async (request, response) => { |
| 450 | try { | 447 | try { |
| 451 | const url = new URL(request.body.url); | 448 | const url = new URL(urlJoin(request.body.url, '/object_info')); |
| 452 | url.pathname += '/object_info'; | ||
| 453 | 449 | ||
| 454 | const result = await fetch(url); | 450 | const result = await fetch(url); |
| 455 | if (!result.ok) { | 451 | if (!result.ok) { |
| @@ -516,15 +512,13 @@ comfy.post('/delete-workflow', jsonParser, async (request, response) => { | |||
| 516 | 512 | ||
| 517 | comfy.post('/generate', jsonParser, async (request, response) => { | 513 | comfy.post('/generate', jsonParser, async (request, response) => { |
| 518 | try { | 514 | try { |
| 519 | const url = new URL(request.body.url); | 515 | const url = new URL(urlJoin(request.body.url, '/prompt')); |
| 520 | url.pathname += '/prompt'; | ||
| 521 | 516 | ||
| 522 | const controller = new AbortController(); | 517 | const controller = new AbortController(); |
| 523 | request.socket.removeAllListeners('close'); | 518 | request.socket.removeAllListeners('close'); |
| 524 | request.socket.on('close', function () { | 519 | request.socket.on('close', function () { |
| 525 | if (!response.writableEnded && !item) { | 520 | if (!response.writableEnded && !item) { |
| 526 | const interruptUrl = new URL(request.body.url); | 521 | const interruptUrl = new URL(urlJoin(request.body.url, '/interrupt')); |
| 527 | interruptUrl.pathname += '/interrupt'; | ||
| 528 | fetch(interruptUrl, { method: 'POST', headers: { 'Authorization': getBasicAuthHeader(request.body.auth) } }); | 522 | fetch(interruptUrl, { method: 'POST', headers: { 'Authorization': getBasicAuthHeader(request.body.auth) } }); |
| 529 | } | 523 | } |
| 530 | controller.abort(); | 524 | controller.abort(); |
| @@ -543,8 +537,7 @@ comfy.post('/generate', jsonParser, async (request, response) => { | |||
| 543 | const data = await promptResult.json(); | 537 | const data = await promptResult.json(); |
| 544 | const id = data.prompt_id; | 538 | const id = data.prompt_id; |
| 545 | let item; | 539 | let item; |
| 546 | const historyUrl = new URL(request.body.url); | 540 | const historyUrl = new URL(urlJoin(request.body.url, '/history')); |
| 547 | historyUrl.pathname += '/history'; | ||
| 548 | while (true) { | 541 | while (true) { |
| 549 | const result = await fetch(historyUrl); | 542 | const result = await fetch(historyUrl); |
| 550 | if (!result.ok) { | 543 | if (!result.ok) { |
| @@ -568,8 +561,7 @@ comfy.post('/generate', jsonParser, async (request, response) => { | |||
| 568 | throw new Error(`ComfyUI generation did not succeed.\n\n${errorMessages}`.trim()); | 561 | throw new Error(`ComfyUI generation did not succeed.\n\n${errorMessages}`.trim()); |
| 569 | } | 562 | } |
| 570 | const imgInfo = Object.keys(item.outputs).map(it => item.outputs[it].images).flat()[0]; | 563 | const imgInfo = Object.keys(item.outputs).map(it => item.outputs[it].images).flat()[0]; |
| 571 | const imgUrl = new URL(request.body.url); | 564 | const imgUrl = new URL(urlJoin(request.body.url, '/view')); |
| 572 | imgUrl.pathname += '/view'; | ||
| 573 | imgUrl.search = `?filename=${imgInfo.filename}&subfolder=${imgInfo.subfolder}&type=${imgInfo.type}`; | 565 | imgUrl.search = `?filename=${imgInfo.filename}&subfolder=${imgInfo.subfolder}&type=${imgInfo.type}`; |
| 574 | const imgResponse = await fetch(imgUrl); | 566 | const imgResponse = await fetch(imgUrl); |
| 575 | if (!imgResponse.ok) { | 567 | if (!imgResponse.ok) { |