google / neuroglancer

WebGL-based viewer for volumetric data
Apache License 2.0
1.09k stars 295 forks source link

Safari and iOS rendering issue #473

Open copypasteearth opened 1 year ago

copypasteearth commented 1 year ago

Hi I am working on loading a dataset from my private server, and it is working on chrome as expected, but safari and ios it is not working

chrome:

Screenshot 2023-07-17 at 5 24 59 PM

Safari

Screenshot 2023-07-17 at 5 24 47 PM

any help with this would be great, i need it to work in ios they are just showing as grey boxes though i tried setting opacity to 1 which didnt work

jbms commented 1 year ago

what does the javascript console show?

copypasteearth commented 1 year ago

@jbms this is what safari is showing

Screenshot 2023-07-17 at 6 21 28 PM
jbms commented 1 year ago

It looks like there may be an issue with content-encoding. Can you check the network console and see what the request and response headers are?

copypasteearth commented 1 year ago

@jbms here is for the info file

`Request GET /api/v1/imaging_suite/data/precomputed_volumes/CDF75295-5F86-498A-883F-49F5224B911E/Control/Sample_1/uCT//decal/info HTTP/1.1 Accept: / Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: keep-alive Host: my web server Origin: https://neuroglancer-demo.appspot.com Referer: https://neuroglancer-demo.appspot.com/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.15

Response HTTP/1.1 200 OK Access-Control-Allow-Origin: https://neuroglancer-demo.appspot.com Cache-Control: no-cache Connection: close Content-Disposition: inline; filename=info Content-Length: 466 Content-Type: application/octet-stream Date: Mon, 17 Jul 2023 22:29:24 GMT ETag: "1689631189.723098-466-3650691274" Last-Modified: Mon, 17 Jul 2023 21:59:49 GMT Server: gunicorn Set-Cookie: session=339418c0-3d33-42da-9bd7-6999420fd567.GF-g-bSi5nbFkerPOgdj0-s9RaA; Expires=Wed, 16 Aug 2023 22:29:24 GMT; HttpOnly; Path=/; SameSite=Lax Vary: Origin X-Robots-Tag: noindex, nofollow`

here is for one of the chuncks

`Request GET /api/v1/imaging_suite/data/precomputed_volumes/CDF75295-5F86-498A-883F-49F5224B911E/Control/Sample_1/uCT//decal/13530.0_13530.0_13530.0/768-896_640-768_0-2 HTTP/1.1 Accept: / Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: keep-alive Host: my server Origin: https://neuroglancer-demo.appspot.com Referer: https://neuroglancer-demo.appspot.com/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.15

Response HTTP/1.1 200 OK Access-Control-Allow-Origin: https://neuroglancer-demo.appspot.com Cache-Control: no-cache Connection: close Content-Disposition: inline; filename=768-896_640-768_0-2.gz Content-Encoding: gzip Content-Length: 6741 Content-Type: application/octet-stream Date: Mon, 17 Jul 2023 22:53:16 GMT ETag: "1689631189.5351033-6741-3579390298" Last-Modified: Mon, 17 Jul 2023 21:59:49 GMT Server: gunicorn Set-Cookie: session=d19e6c6b-e3d8-4bdf-8394-b571c1a4011c.8cZSRs7XbDV075s7LufjVG0xKDg; Expires=Wed, 16 Aug 2023 22:53:16 GMT; HttpOnly; Path=/; SameSite=Lax Vary: Origin X-Robots-Tag: noindex, nofollow`

jbms commented 1 year ago

My best guess is that Safari is not gzip-decoding the responses sent by the server. However, it does seem to be sending an accept-encoding header, so I don't really know why that could be.

copypasteearth commented 1 year ago

@jbms Let me give you some more info here. When i run the server locally, i am using a docker image that is compatible with apple silicon and it works, but when i deploy it to an EC2 linux instance it does not work but its the same exact code and this is the problem

jbms commented 1 year ago

Perhaps you can try manually fetching from the server, either by just copying the URL into the address bar in Safari, or using the javascript console and using const response = await fetch("https://...."); and seeing if you get the gzip-decoded response, or the gzip-encoded response. The browser should be decoding the response automatically. Perhaps also check if the headers differ at all between local vs ec2.

copypasteearth commented 1 year ago

@jbms here is the 2 files downloaded in browsers, the one with the gz extension was from chrome, the other version is from safari, any ideas here

Screenshot 2023-07-17 at 7 34 52 PM
jbms commented 1 year ago

You said that the behavior differs when running the server locally vs on EC2 --- I'd suggest seeing exactly how the responses (especially the headers) differ.

copypasteearth commented 1 year ago

@jbms actually it is not working locally, do you have any tips for getting safari to work with it, like some common problems with safari?

jbms commented 1 year ago

Sorry, I don't have much experience with Safari.

xgui3783 commented 1 year ago

Just a stab in the dark here, I can imagine Safari might see

Content-Disposition: inline; filename=768-896_640-768_0-2.gz
Content-Encoding: gzip

And chose not to decode the gzip?

copypasteearth commented 1 year ago

@xgui3783 is there anything I can try here

xgui3783 commented 1 year ago

@copypasteearth

It looks you are using gunicorn server, are you using fastapi? flask? frameworks usually have a way for you to strip the headers.

For a quick and dirty check if that is the issue, you could set up a reverse proxy, and strip the content-disposition header.

edited for clarity

copypasteearth commented 1 year ago

@xgui3783 it is an airflow server which uses flask behind the scenes, i am wrapping flask with flask-cors also

xgui3783 commented 1 year ago

@copypasteearth

Not familiar with airflow, unforunately, but if a flask is somewhere on the stack, perhaps, just for debug's sake, you could try https://pypi.org/project/flask-http-middleware/

but change the middleware to something like

class StripContentDispositionMiddleWare(BaseHTTPMiddleware):
    def __init__(self):
        super().__init__()

    def dispatch(self, request, call_next):
        # t0 = time.time()
        response = call_next(request)
        # response_time = time.time()-t0
        response.headers.pop("Content-Disposition", None)
        # response.headers.add("response_time", response_time)
        print("middleware is run everytime a request is made")
        return response
copypasteearth commented 1 year ago

@xgui3783 stripping Content-Disposition from response headers fixed the problem, Thank you