eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
158 stars 107 forks source link

outputStylesheet resource expression renders invalid resource URI "/ctx/jakarta.faces.resource/library/somefile.png.faces.resource/theme.css.xhtml?ln=lib-for-css" #5388

Closed arnis87 closed 5 months ago

arnis87 commented 5 months ago

Describe the bug

When using #{resource} inside css file its URI gets mangled up in ResourceImpl.getRequestPath:279 For some reason it gets FacesMapping EXTENSION with incorrect pattern, see image: image

To Reproduce

Steps to reproduce the behavior:

  1. Include resource dynamically inside css file
  2. observe that the final css generated by application gets bad URI for the resource:

Original CSS has this expression: src: url("#{resource['primefaces-mytheme:fonts/open-sans-v13-latin-regular.eot']}");

What ends on page is: src: url("/ite/jakarta.faces.resource/fonts/open-sans-v13-latin-regular.eot.faces.resource/theme.css.xhtml?ln=primefaces-mytheme"); Everything starting from .faces.resource/theme.css... is unwanted and most likely coming from ´Referer´ header

I have been able to trace this to C:/.m2/repository/org/glassfish/jakarta.faces/4.0.5/jakarta.faces-4.0.5-sources.jar!/com/sun/faces/application/resource/ResourceImpl.java:279

https://github.com/eclipse-ee4j/mojarra/blob/350fbbea7fe3b2c02eb416934cdebb2c0f9830da/impl/src/main/java/com/sun/faces/application/resource/ResourceImpl.java#L244-L248

https://github.com/eclipse-ee4j/mojarra/blob/350fbbea7fe3b2c02eb416934cdebb2c0f9830da/impl/src/main/java/com/sun/faces/application/resource/ResourceImpl.java#L278-L279 Where it does some replace based on the mapping resolved earlier. Also noticed that since the URI requesting the resource is the css file itself, browser attaches the Referer to the file instead of the base xhtml page.

Expected behavior Correct URI for the resource, same as when the #{resource} is resolved on normal FacesServlet served page.

Screenshots

Additional context Using JEE10 stack with Mojarra Faces impl 4.0.5 OpenLiberty 23.0.0.12 Omnifaces 4.2 PrimeFaces 12.0.7 Made manual jar modifications to faces-config.xml file to exclude Omnifaces and PrimeFaces preconfigured resource-handlers.

FacesServlet defined minimally:

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
arnis87 commented 5 months ago

I did manage to work around this issue for my own css files by inlining the rules that had #{resource..} however this is still issue for external resources that use dynamic resources like primeicons (tries to load fonts but gets bad URI)

Simplest way I found to reproduce this seems to be just to create css file with single rule where some url is resolved and request that css via GET, it is easily observable that the URI rendered in the css is incorrect.

Another way to bypass the issue would be to use Omnifaces UnmappedResourceHandler as it removes the need to have #{resource[..]} and allows defining the url in a simpler way

BalusC commented 5 months ago

I get you're using GlassFish. Which version exactly? The mapping info (the HttpServletMappingImpl instance) is provided by GlassFish so it's a bug in GlassFish if it gives incorrect information.

arnis87 commented 5 months ago

@BalusC Forgot to mention the container but I am using Open Liberty 23.0.0.12

melloware commented 5 months ago

For some reason I thought open liberty used MyFaces?

arnis87 commented 5 months ago

Could be - I am actually including Mojarra jar in my war as I could not get JEE 9 and 10 to run with their feature faces-4.0. It just would not recognize that faces 4 should be used and started to look for old jsf classes. With Mojarra impl included manually it runs

BalusC commented 5 months ago

This is a bug in server, not in JSF. JSF does not create HttpServletMapping implementation, the server does. JSF is merely reading the information returned by server.

I guess that the OpenLiberty version being used has a bug in extracting the extension, that it is only looking at the first occurrence of the period character instead of the last occurrence, or that it forgot to split beforehand after the last slash.

Try another server and you'll see.

arnis87 commented 5 months ago

Ok, I will verify this with some other container at some point. Closing this for now since not classified as JSF issue but WLP bug.