Posts by divinus

The Forum will be updated on the 12.10.2026 (the next monday).
A maintenance mode will be active approximately from 7:00 until 7:30 CEST/UTC+2h

    SM1312 - happy to.

    The idea is that Conquest itself is not modified at all. It sits inside the stack exactly as it ships, and everything around it is what changes.

    Traefik is the only thing actually exposed. It terminates TLS and routes each request by host and path, and that is where the access rules live - one entry point instead of a handful of open ports.

    Keycloak, with its own small Postgres, provides the identity: per-user authentication, sessions and JWT tokens, which is what the medical-system guidance asks for - who is this user, audit, session control - without touching Conquest's code. oauth2-proxy sits in front of the browser app that has no native login of its own, so that app only sees a request once the user has authenticated.

    Conquest and its MariaDB run untouched: dgate for DIMSE, the Apache/PHP web layer, the web apps.

    Loki, Alloy and Grafana collect and display the logs - the audit-trail and monitoring side.

    docker-socket-proxy is a narrow allow-list in front of the Docker API. The management view needs to start and stop containers, and exposing the raw docker socket is root-level RCE, so it gets only the few endpoints it needs.

    Routing is split into three tiers by who the consumer is: the viewers and the main console are served inside the perimeter without a login; /app/newweb sits behind Keycloak SSO; /api/dicom requires a JWT, which is the DICOMweb path for machine clients such as OsiriX.

    On Windows, the honest answer is no: the stack is built for Docker on Linux. Two of the pieces it relies on are Linux kernel features - macvlan, so Conquest can hold its own address on the LAN, and host networking. Under Docker Desktop your Linux containers run inside a Linux VM, so the host is that VM rather than your desktop; I tested it and a container binding a port there was not reachable from outside the VM. It could be reworked to use published ports instead, but that is a change to the stack rather than a setting.

    If what you want is Conquest in Docker without the security layer, that part does run anywhere:

    Code
    https://github.com/DivNet-MakeIT/conquest-basic-mariadb

    Two containers, Conquest and MariaDB, with a second compose file for Docker Desktop that uses published ports instead of host networking. It has no authentication in front of the web interface, so it belongs on a trusted network - exactly as Marcel says above.

    Marcin

    Hi Marcel,


    This is exactly the direction a few of us have been working in, and it lines up with your point precisely: keep malicious actors out and never expose the raw web interface.


    We built a complete, self-contained protective layer around Conquest, with the DICOM engine itself left untouched - everything wraps around it. In our setup Conquest sits behind:


    - Traefik as the single entry point - TLS everywhere, no service ports exposed;

    - Keycloak (OIDC) + oauth2-proxy in front of every web / DICOMweb route, with local accounts and optional Active Directory / LDAP federation;

    - capability-based access control (RBAC) - each group/role is granted specific capabilities, enforced server-side;

    - DICOMweb (QIDO/WADO/STOW) with per-user authorization and full access auditing (who / when / which study), shipped to Loki + Grafana;

    - bundled OHIF / Papaya viewers, plus one-click OsiriX / Weasis using short-lived tokens.


    It is packaged as a Docker Compose stack with a guided installer, aimed at deployments that need to meet NIS2 / GDPR-style requirements while still running on an internal, trusted network - not the open internet, as you rightly stress.


    The engine is unchanged; it is all a layer around it. We are considering releasing it and wanted to gauge interest first - would this be useful to others here? Happy to write up the architecture and answer questions.


    Marcin (DivNet)

    UPDATE / FIX FOUND — WADO-RS multipart boundary missing \r\n (RFC 2046 violation in rquery.lua)


    After further investigation I found the root cause and fix. Posting here so Marcel can apply it to the official source.


    --- ROOT CAUSE ---


    The WADO-RS response is multipart/related; type="application/dicom". RFC 2046 §5.1.1 defines:


    delimiter := CRLF dash-boundary


    The CRLF (\r\n) before --boundary is mandatory — it is part of the boundary syntax, not just a trailing newline from the previous part.


    In rquery.lua, function getinstances(), the loop was written as:


    f:write("--"..bd.."\r\n") -- WRONG: missing \r\n before --


    The closing boundary already had it correct: f:write("\r\n--"..bd.."--\r\n\r\n")


    So only the final boundary had the required \r\n prefix. Strict RFC 2046 parsers (like OsiriX MD 14.2.1) search for the pattern \r\n--boundary, find only 1 match (the closing one), and treat the entire response body as a single body-part. Parsing hundreds of concatenated DICOM files as one object produces a corrupt file — which OsiriX renders as a grayscale gradient instead of the actual image.


    --- THE FIX ---


    In getinstances(), change:


    f:write("--"..bd.."\r\n")


    to:


    f:write("\r\n--"..bd.."\r\n")


    Full corrected loop:


    for i=0, #r-1 do

    r[i]:Write(t)

    f:write("\r\n--"..bd.."\r\n") -- fixed: \r\n before --boundary

    f:write("Content-Type: application/dicom\r\n")

    f:write("Content-Transfer-Encoding: binary\r\n\r\n")

    g = io.open(t, "rb")

    f:write(g:read('*a'))

    g:close()

    end

    f:write("\r\n--"..bd.."--\r\n\r\n") -- closing boundary (was already correct)


    --- VERIFICATION ---


    After the fix, a study with 143 instances (~65 MB) returns exactly 144 occurrences of \r\n--boundary (143 opening + 1 closing). Before the fix, only 1 occurrence was found. OsiriX MD now displays all images correctly.


    --- NOTE ---


    I noticed the rquery.lua header already contains:

    -- 20230808 mvh added \r\n before boundary - missed by weasis loader


    This suggests Marcel previously fixed this for Weasis compatibility. The Docker image of Conquest 1.5.0f I was running did not have this fix in the active rquery.lua served by Apache (/var/www/html/api/dicom/rquery.lua). It may be that the fix is present in the source tree but was not included in the distributed package, or was applied only to a specific code path.


    Environment: Conquest DICOM 1.5.0f / Docker / Apache + Lua dgate / OsiriX MD 14.2.1 / macOS

    Hello Marcel,

    I checked the multipart response more closely.

    The response contains 143 occurrences of:

    Content-Type: application/dicom

    and 143 occurrences of:

    Content-Transfer-Encoding: binary

    However, the multipart boundary appears only twice: once at the beginning and once as the final closing boundary.

    So it looks like all DICOM objects may be concatenated inside one multipart section instead of being separated by a boundary before each object.

    Could this be the reason why OsiriX cannot parse the WADO-RS response correctly?

    Best regards,

    Marcin

    Hello Marcel,

    I performed an additional test.

    The legacy WADO request through dgate.php returns a valid DICOM file, which can be downloaded successfully.

    The DICOM object appears to be correct and contains valid image data.

    The issue only occurs when retrieving the study through the DICOMweb API endpoint:

    /api/dicom/rs/studies/<StudyInstanceUID>

    The same study works correctly when accessed through:

    • Conquest web interface (/app/newweb)
    • Legacy WADO (dgate.php?requestType=WADO)
    • Classic DICOM Query/Retrieve (C-FIND / C-GET / C-MOVE)
    • OHIF

    Only the DICOMweb study retrieval endpoint produces the problem in OsiriX.

    Best regards,

    Marcin

    Hello Marcel,

    As far as I can tell, the DICOM images themselves are not damaged.

    The same studies are displayed correctly in:

    • OHIF
    • Conquest web interface (/app/newweb)
    • Classic DICOM Query/Retrieve (C-FIND / C-GET / C-MOVE)

    Only the DICOMweb retrieval path produces the issue in OsiriX.

    I can also retrieve the study through DICOMweb with curl and receive a valid multipart response containing all DICOM objects.

    Unfortunately, I do not currently have another DICOMweb PACS source available for comparison. However, I can try to set up Orthanc and compare the DICOMweb response generated by Orthanc versus Conquest for the same study.

    Best regards,

    Marcin

    Hello Marcel,

    I tested the URL:

    /api/dicom/rs/studies/1.2.840.113619.6.388.16254670578653476717748544641543505467

    The response is returned as a file. The downloaded file is approximately 68.5 MB in size and is saved by the browser as an MHTML/MHT file.

    When retrieved with curl, the response has:

    Content-Type: multipart/related
    Content-Type: application/dicom (for each part)

    and contains the DICOM objects from the study.

    I have attached a screenshot of the downloaded file.

    I captured the response with curl.

    The request was:

    GET /api/dicom/rs/studies/1.2.840.113619.6.388.16254670578653476717748544641543505467

    with header:

    Accept: multipart/related; type=application/dicom

    The server responds with HTTP 200 OK and:

    Content-Type: multipart/related; boundary=Zjg1ke2qS8Mh9b4AOvmBVPpU3xRDQ6Cu
    Transfer-Encoding: chunked

    The downloaded file size is about 65.2 MB.

    So the endpoint returns a multipart response containing the DICOM objects from the study.

    Best regards,

    Marcin

    Hello Marcel,

    I added the /rendered routes in index.php as suggested and mapped them to thumbnail(..., 512).

    However, after checking the Apache access log, it looks like OsiriX does not call the /rendered endpoint at all.

    During retrieval, OsiriX only calls:

    GET /api/dicom/rs/studies

    and then:

    GET /api/dicom/rs/studies/

    There are no requests to /rendered, /thumbnail, /frames or /instances in the access log.

    So it seems that OsiriX is retrieving the whole study through WADO-RS Study Retrieve as application/dicom, not using the rendered image endpoint.

    Best regards,

    Marcin


    Hello Marcel,

    I performed some additional tests and would like to share the results.

    When accessing the study through the standard Conquest web interface (/app/newweb), the images are displayed correctly and the anatomy is visible as expected.

    However, when accessing the same study through the DICOMweb endpoint (/api/dicom/rs), the images are not displayed correctly in OsiriX and appear as a grayscale gradient.

    I have attached the corresponding logs for both tests.

    Additional observations:

    • OHIF displays the images correctly.
    • Classic DICOM Query/Retrieve (C-FIND, C-GET and C-MOVE) works correctly.
    • The issue is only reproducible when using the DICOMweb / WADO-RS path.
    • Apache returns HTTP 200 responses for the DICOMweb requests.
    • The WADO-RS response is returned as multipart/related, and all parts have Content-Type: application/dicom.
    • The same behavior is reproducible on a clean Docker installation with the default Conquest configuration.

    At the moment, the issue appears to be isolated to the DICOMweb/WADO-RS retrieval path.

    I have attached the logs collected during these tests for your review.

    Best regards,

    Marcin

    Hello Marcel,

    Yes, the images are displayed correctly through the OHIF viewer. I tested the same study and series, and the images are rendered properly in OHIF with the correct grayscale and anatomical details visible.

    The issue only occurs when OsiriX retrieves the image through WADO. Instead of the actual MR image, OsiriX receives and displays only a smooth grayscale gradient from black to white.

    I will enable debug logging and reproduce the issue again.

    Could you please advise which debug settings would be the most useful for investigating WADO image generation? If there are specific options in dicom.ini or a preferred log level that would help identify the problem, I will enable them and provide the resulting logs.

    Best regards,

    Marcin

    Hello Marcel,

    Thank you for looking into this.

    The issue is not related to a specific Window Level / Window Width requested by the client. The problem occurs when OsiriX downloads the image through WADO and displays the default presentation.

    I have attached an example screenshot. Instead of displaying the actual MR image, the downloaded image appears as a smooth grayscale gradient from black to white. The anatomical information is completely missing.

    When the same DICOM file is opened directly from the PACS storage or viewed in OHIF, the image is displayed correctly. The problem only occurs when the image is retrieved through the WADO interface.

    Regarding your question about rounding Window Center and Window Width to integers: I do not think this is the root cause. Even if the window values were slightly different, I would still expect to see the anatomy, perhaps with different contrast. Instead, the returned image contains only a grayscale gradient and no diagnostic image content.

    Could there be an issue in the pixel data conversion or in the generation of the JPEG/PNG image returned by WADO?

    Best regards,

    Marcin

    Hello,

    To better understand what might be causing the issue, I recreated the environment using Docker.

    I have attached a fully working Docker Compose configuration that reproduces the same graphics problem when downloading WADO images.

    Could you please take a look and let me know if you notice anything unusual?

    Feel free to use the Docker configuration for your own testing if it is helpful.

    Best regards,

    Marcin

    Thank you for your reply. I apologize for the delay, but I was "trapped" in Asia due to operations in the Middle East and have only just returned to my duties.

    Regarding the previous issue...
    As you can see in the photos, when I use WADO and download the research (to Osirix), only the first frame (photo) in the entire series appears to be correct, while the rest of the photos are completely gray or a gray gradient. I don't know if this is related to the configuration of Conquest itself, permissions issues for the TMP files where the files are processed, or perhaps something else.

    Hello Marcel,

    I’m seeing a rendering issue with Conquest PACS 1.5.0f.
    Images retrieved via WADO look grayscale-distorted (tonal scale compressed / wrong window), similar to the attached example. They are not simply darker; the gray ramp looks incorrect.

    This occurs regardless of transfer syntax:

    • Implicit VR Little Endian
    • Explicit VR Little Endian
    • JPEG 2000 Lossless

    Opening the same study in the OHIF web viewer looks correct (proper window/level), so the stored pixel data seems fine and the problem appears limited to WADO conversion.

    Environment

    • Conquest: 1.5.0f
    • Database: MariaDB (local)
    • Viewers tested: OHIF (OK), OsiriX / direct browser download / curl (distorted)

    Question
    Could this be related to VOI LUT / Window translation during WADO export, or a dicom.ini or config files option that affects WADO JPEG generation?
    Which parameters/converters should I check or adjust to ensure correct grayscale mapping in WADO output?

    Thanks in advance for your help!

    Yes I'm on Linux

    I have logging level eq 0

    Everything was fine till 3 days before.
    I had then lots of query requests without additional terms so it returns more than 10k rows
    After one of that request I notice in logs file note about grabbing file and after that this notification about processing was started

    I've got all of servers based on Linux and conquest 1.4.16/17

    Hello

    I've got in logs whole the time messages like below

    Tue Apr 25 16:00:20 2017 Virtualquery: cleaning response from server: MAIN-DICOM -9987 13
    Tue Apr 25 16:00:20 2017 Virtualquery: processing response from server: MAIN-DICOM
    Tue Apr 25 16:00:20 2017 Virtualquery: cleaning response from server: MAIN-DICOM -9987 13
    Tue Apr 25 16:00:20 2017 Virtualquery: processing response from server: MAIN-DICOM
    Tue Apr 25 16:00:20 2017 Virtualquery: cleaning response from server: MAIN-DICOM -9987 13
    Tue Apr 25 16:00:20 2017 Virtualquery: processing response from server: MAIN-DICOM
    Tue Apr 25 16:00:20 2017 Virtualquery: cleaning response from server: MAIN-DICOM -9987 13
    Tue Apr 25 16:00:20 2017 Virtualquery: processing response from server: MAIN-DICOM
    Tue Apr 25 16:00:20 2017 Virtualquery: cleaning response from server: MAIN-DICOM -9987 13
    Tue Apr 25 16:00:20 2017 Virtualquery: processing response from server: MAIN-DICOM


    What can i do to stop it?

    When i turn VirtualServerFor off this messages not show any more but i need to have virtualserver working so what can i do?

    best reg

    M.

    U can control system without access to server. To change acrnema You can use your browser what's easier for average users. Only after change u have to reload dgate to load new values.
    This before was only example... structure of database can be modify.
    the same with routing... configuration by web will be easier than wrote all sentences in file...

    that's my opinion :)

    best regards

    Marcin