WMS Capabilities response contains incorrect URL for GetLegendGraphic request when using custom legend image. It's missing path to "styles" directory.
Steps to reproduce:
Open the "grass" style in the style editor.
Click on Add legend, type in "grass_fill.png" (file existing in default data_dir/styles).
Click on "Auto-detect image and size" link. All legend fields are auto filled correctly (width and height is 32, format is image/png;charset=UTF-8).
Save the style.
Make a WMS GetCapabilites request and look for the URL of the grass style in tigeroly_landmarks layer. It's http://localhost:8080/geoserver/grass_fill.png which is incorrect. The correct link is http://localhost:8080/geoserver/styles/grass_fill.png
Apache Tomcat 8.0.30 or embedded Jetty
Just confirmed, the same issue does exist when requesting WMS 1.1.1.
I just peeked into the code and found out the following:
the onlineresource validator in org.geoserver.wms.web.data.ExternalGraphicPanel accepts a relative path only if it's a valid path to an image in the styles directory (or it's subdirectory)
but you must not put "styles" at the begining of the path, because the styles directory is implied (it's hardcoded as resource lookup root location)
therefore, if you put simple "grass_fill.png" as the legend's Online Resource, the StyleInfo object created when submitting the style form (either in StyleEditPage or StyleNewPage) does not have the styles directory as a prefix of its Online Resource string
finally, when the handleLegendURL method of the org.geoserver.wms.capabilities.Capabilities_1_3_0_Transformer class is building the custom legend URL, it's basically just concatenating two strings:
the request.getBaseUrl(), e.g. "http://localhost:8080/geoserver/"
the legend.getOnlineResource(), e.g. "grass_fill.png"
and we end up with invalid URL for legends relative to the styles directory...
I was wondering what is the best fix.
a simple way is to concat the "styles/" string with the result of legend.getOnlineResource() when calling buildUrl in the handleLegendURL method. Then do the same in all other Capabilities Transformers.
pros: it's simple
cons: it creates a secret dependency between the style form validator and capabilities URL transformers
tell Wicket to automagically prepend the online resource with the "styles/" prefix whenever the online resource string is a relative path
pros: no code outside of form handling needs to be changed
cons: I don't know anything about Wicket or form handling in general, maybe it's not possible; it would create a secret dependency between the form validator and Wicket code anyway (but it's better than the previous option in my opinion)
There might be other ways, e.g. don't do the whole 'implicit styles directory' in the form validation, but I'm not familiar enough with GeoServer sources as a whole to be able to assess it's pros and cons. Personally I'd like to have the possibility to use not just the global styles directory but also the styles dir relative to the workspace dir, but that's out of scope of this issue.
Thanks for the fix alex (https://github.com/geoserver/geoserver/pull/1679). The code was implemented differently from the documentation. Fix applied to master and 2.9.x branch.
Two other things to test:
Test if a custom legend graphic works for a workspace style? I expect it does not since we only have a mapping to the styles folder.
Test if an SLD 1.1 file (that can include a legnd graphic as part of the XML) is handled in any form.
Thanks for the research and discussion @peterko - the functionality was already documented as relative to the SLD file (seeking behaviour similar to how external graphics are resolved in the SLD file).
There is one problem with this approach (which I hope to test as noted above). The styles folder is published in main applicationContext.xml
We will need to use our own implementation which is smart enough to handle styles/icon.png and styles/workspace/icon.png.
Mass closing all resolved issues not modified in the last 4 weeks