flow
flow copied to clipboard
23.1.0 Dynamic Image Resource not resolved (works with 23.0.11)
Description of the bug
I'm running multiple Vaadin Spring Servlets, and the root servlet running at path /* cannot properly resolve image resources since version 23.1.0.
I'm registering Images like so:
return new Image(new StreamResource(name, () -> new ByteArrayInputStream(data)), name);
resulting in a call to StreamResourceRegistry::registerSource where the resource is put in the session registry.
In 23.0.11 StreamRequestHandler::handleRequest properly figures out the correct session registry the resource was registered to, and displays the image.
In 23.1.0 a different session registry than the one where the resource was added to is found for the request resulting in response.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource is not found for path=" + pathInfo);
Expected behavior
Dynamic Image Resource resolves as it did in 23.0.11.
Minimal reproducible example
Would probably take a workday to create one to be honest.
Basically I have three SpringServlets (without rootMapping)
One SpringServlet with the mapping "/*"
A second SpringServlet with the mapping "/1/*"
And a third SpringServlet with the mapping "/2/*"
The second and third SpringServlet can use dynamic resources fine, the first one cannot load them since 23.1.0
May be related to #13795
Versions
- Vaadin / Flow version: 23.1.0
- Java version: OpenJDK 17
- OS version: Windows 11
- Browser version (if applicable): -
- Application Server (if applicable): -
- IDE (if applicable): Intellij IDEA
I have the feeling the problem may be that here https://github.com/vaadin/flow/commit/f570561#diff-75fc0cfcc226080cc330db93bedfbe5b6e1c5dc81908a7c7adf6be1e84ee6e15R85 /Vaadin/* is added as mapping for each servlet, which maybe makes the request get handled by a different servlet than the resource was registered to, as multiple servlets include the same /Vaadin/* mapping. I really don't have enough knowledge of how vaadin does it's route mapping internally to know for sure though.
All dynamic resource requests are still supposed to go to /somepath/VAADIN/…. and not /VAADIN/…
If they go to VAADIN in the root of the context, it certainly won’t work correctly
@Artur- I think there's a misunderstanding the only place where dynamic resources don't seem to work is the servlet for the root path /*:
Before in version 23.0.11:
Dynamic resource from SpringServlet with mapping /* -> /VAADIN/dynamic/resource/0/04438ac2-0cd2-4753-b845-e6a5dbf3cee1/LOGO_BIG -> resolved correctly
Dynamic resource from SpringServlet with mapping /1/* -> /1/VAADIN/dynamic/resource/0/0c11e399-0d66-48a6-aae3-c3871bd425e8/LOGO_SMALL-> resolved correctly
Now in version 23.1.0
Dynamic resource from SpringServlet with mapping /* -> /VAADIN/dynamic/resource/0/ee4dca8d-d4a2-4630-a010-320822f6c569/LOGO_BIG -> 404
Dynamic resource from SpringServlet with mapping /1/* -> /1/VAADIN/dynamic/resource/0/cdb0edf1-9fe4-4fe0-b7db-68bbc52b67e3/LOGO_SMALL-> resolved correctly
Alright so a guess about the problem. The VaadinSession instance is tied to the servlet so it will be different for the /* and the /VAADIN/* servlet. The UI instance is part of the /* VaadinSession and the resource is registered there, the request goes to the /VAADIN/* servlet and that VaadinSession has no resources registered at all.
->
If you have a /* Vaadin servlet mapping, there should never be a separate /VAADIN/* servlet as it won't work. The /* servlet will handle everything needed.
If you handle your servlet registrations manually you probably never want the Vaadin servlet registration logic to even run.
Okay, so I removed my custom registered root servlet. It seems to work properly now. But I'd rather use my own custom SpringServlet, and not the default Vaadin one. How would I go about disabling the default Vaadin root servlet registration logic as you proposed?
I originally implemented the root servlet (and the other dynamic servlets) according to the docs here: https://vaadin.com/docs/latest/flow/integrations/spring/spring-mvc . There is an example how to register a root servlet. But as it is documented there it breaks dynamic resources now (before it worked fine). As I understand it, it seems to cause some mapping overlap of /VAADIN.
Hi, I was having similar issue after upgrading Vaadin to 23.2.4 and migrated Spring security while trying to display dynamic content on an iFrame, which is caused by ‘x-frame-options’ set to ‘deny’ in Spring.