fix(DicomWebDataSource): set correct cross-service URLs on DICOMweb clients#6009
fix(DicomWebDataSource): set correct cross-service URLs on DICOMweb clients#6009galenzo17 wants to merge 2 commits into
Conversation
✅ Deploy Preview for ohif-dev canceled.
|
| * Applies the URL fix from index.ts lines ~211-219. | ||
| * Extracted here to test in isolation. | ||
| */ | ||
| function applyServiceUrls( | ||
| qidoClient: MockDICOMwebClient, | ||
| wadoClient: MockDICOMwebClient, | ||
| config: { qidoRoot: string; wadoRoot: string; stowRoot?: string } | ||
| ) { | ||
| const effectiveStowRoot = config.stowRoot || config.wadoRoot; | ||
|
|
||
| qidoClient.wadoURL = config.wadoRoot; | ||
| qidoClient.stowURL = effectiveStowRoot; | ||
|
|
||
| wadoClient.qidoURL = config.qidoRoot; | ||
| wadoClient.stowURL = effectiveStowRoot; | ||
| } |
There was a problem hiding this comment.
Test logic decoupled from production code
applyServiceUrls is a hand-copied extract of the assignment block in index.ts. If the production logic changes (e.g., a guard is added, a URL property is renamed, or a new client is introduced), these tests will continue to pass while the real behavior regresses silently. The tests should import and exercise the actual createDicomWebApi initializer (or at minimum import a shared utility), not duplicate its logic inline.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/default/src/DicomWebDataSource/index.test.ts
Line: 27-42
Comment:
**Test logic decoupled from production code**
`applyServiceUrls` is a hand-copied extract of the assignment block in `index.ts`. If the production logic changes (e.g., a guard is added, a URL property is renamed, or a new client is introduced), these tests will continue to pass while the real behavior regresses silently. The tests should import and exercise the actual `createDicomWebApi` initializer (or at minimum import a shared utility), not duplicate its logic inline.
How can I resolve this? If you propose a fix, please make it concise.…lients The dicomweb-client library sets qidoURL, wadoURL, and stowURL all to the same base url when no prefixes are provided. This causes requests to be routed to the wrong endpoint when qidoRoot and wadoRoot differ (e.g. /qidors/ vs /wadors/). Extract applyServiceUrls into a shared utility so the production code and tests exercise the same function. After constructing the clients, call applyServiceUrls to assign the correct cross-service URLs. Also adds an optional stowRoot config field for deployments with a separate STOW endpoint. Closes OHIF#5820 Signed-off-by: Agustin Bereciartua <bereciartua.agustin@gmail.com>
e8dc14f to
37ef346
Compare
…h coalescing Use ?? instead of || for stowRoot fallback to respect explicit empty strings. Wrap assignments in undefined checks so client URLs are not overwritten when a root is not provided. Signed-off-by: Agustin Bereciartua <bereciartua.agustin@gmail.com>
| const effectiveStowRoot = config.stowRoot ?? config.wadoRoot; | ||
|
|
||
| if (config.wadoRoot !== undefined) { | ||
| qidoClient.wadoURL = config.wadoRoot; | ||
| qidoClient.stowURL = effectiveStowRoot; | ||
| } | ||
|
|
||
| if (config.qidoRoot !== undefined) { | ||
| wadoClient.qidoURL = config.qidoRoot; | ||
| wadoClient.stowURL = effectiveStowRoot; | ||
| } |
There was a problem hiding this comment.
When
config.qidoRoot is defined but both config.wadoRoot and config.stowRoot are undefined, effectiveStowRoot resolves to undefined. The second if block guard only checks config.qidoRoot !== undefined, so wadoClient.stowURL is overwritten with undefined, corrupting the client state. TypeScript strict mode also flags the assignment since effectiveStowRoot: string | undefined is not assignable to stowURL: string. Moving effectiveStowRoot inside each guard (where the relevant root is guaranteed defined) eliminates both the runtime risk and the type error.
| const effectiveStowRoot = config.stowRoot ?? config.wadoRoot; | |
| if (config.wadoRoot !== undefined) { | |
| qidoClient.wadoURL = config.wadoRoot; | |
| qidoClient.stowURL = effectiveStowRoot; | |
| } | |
| if (config.qidoRoot !== undefined) { | |
| wadoClient.qidoURL = config.qidoRoot; | |
| wadoClient.stowURL = effectiveStowRoot; | |
| } | |
| if (config.wadoRoot !== undefined) { | |
| const effectiveStowRoot = config.stowRoot ?? config.wadoRoot; | |
| qidoClient.wadoURL = config.wadoRoot; | |
| qidoClient.stowURL = effectiveStowRoot; | |
| } | |
| if (config.qidoRoot !== undefined) { | |
| const effectiveStowRoot = config.stowRoot ?? config.wadoRoot; | |
| wadoClient.qidoURL = config.qidoRoot; | |
| wadoClient.stowURL = effectiveStowRoot; | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/default/src/DicomWebDataSource/utils/applyServiceUrls.ts
Line: 14-24
Comment:
When `config.qidoRoot` is defined but both `config.wadoRoot` and `config.stowRoot` are undefined, `effectiveStowRoot` resolves to `undefined`. The second `if` block guard only checks `config.qidoRoot !== undefined`, so `wadoClient.stowURL` is overwritten with `undefined`, corrupting the client state. TypeScript strict mode also flags the assignment since `effectiveStowRoot: string | undefined` is not assignable to `stowURL: string`. Moving `effectiveStowRoot` inside each guard (where the relevant root is guaranteed defined) eliminates both the runtime risk and the type error.
```suggestion
if (config.wadoRoot !== undefined) {
const effectiveStowRoot = config.stowRoot ?? config.wadoRoot;
qidoClient.wadoURL = config.wadoRoot;
qidoClient.stowURL = effectiveStowRoot;
}
if (config.qidoRoot !== undefined) {
const effectiveStowRoot = config.stowRoot ?? config.wadoRoot;
wadoClient.qidoURL = config.qidoRoot;
wadoClient.stowURL = effectiveStowRoot;
}
```
How can I resolve this? If you propose a fix, please make it concise.
Summary
wadoURL,qidoURL,stowURL) on each DICOMweb client so requests are routed to the right endpoint whenqidoRootandwadoRootdiffer (e.g./qidors/vs/wadors/)stowRootconfig field for deployments with a separate STOW endpointstowRoot, same-root (no-op), andstowRootfallback scenariosCloses #5820
Test plan
qidoRootandwadoRootdifferstowRootis used when providedqidoRoot === wadoRootstowURLdefaults towadoRootwhenstowRootis omittedGreptile Summary
This PR fixes cross-service URL routing in the
DicomWebDataSourceby introducingapplyServiceUrls, a utility that post-construction assigns the correctwadoURL,qidoURL, andstowURLon each DICOMweb client whenqidoRootandwadoRootdiffer. It also adds an optionalstowRootconfig field and a dedicated test suite for the new utility.applyServiceUrls.tsguards assignments with!== undefinedchecks and uses??forstowRootfallback — both are improvements over naive falsy checks.index.tswires the utility into theinitializeblock immediately after client construction and extendsDicomWebConfigwithstowRoot.qidoRootis provided while bothwadoRootandstowRootare absent, which would causewadoClient.stowURLto be set toundefinedat runtime.Confidence Score: 4/5
Safe to merge after addressing the
effectiveStowRootundefined-assignment edge case inapplyServiceUrls.tsWhen
config.qidoRootis defined but bothconfig.wadoRootandconfig.stowRootare absent,effectiveStowRootisundefinedandwadoClient.stowURLis overwritten with it — silently corrupting the client for any STOW operation. The guard onqidoRootonly protectswadoClient.qidoURL, not thestowURLassignment that follows it.extensions/default/src/DicomWebDataSource/utils/applyServiceUrls.ts— theeffectiveStowRootcomputation needs to move inside eachifguardImportant Files Changed
effectiveStowRootthat can beundefinedinside theqidoRootguard block, corruptingwadoClient.stowURLqidoRootis defined butwadoRootandstowRootare both absentapplyServiceUrlsinto theinitializehook and addsstowRoottoDicomWebConfig; the integration point itself is straightforwardPrompt To Fix All With AI
Reviews (3): Last reviewed commit: "fix(DicomWebDataSource): guard against u..." | Re-trigger Greptile