[ 
https://issues.apache.org/jira/browse/WW-5640?focusedWorklogId=1027815&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1027815
 ]

ASF GitHub Bot logged work on WW-5640:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 01/Jul/26 10:19
            Start Date: 01/Jul/26 10:19
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1765:
URL: https://github.com/apache/struts/pull/1765

   Fixes [WW-5640](https://issues.apache.org/jira/browse/WW-5640)
   
   ## What
   
   Adds first-class **WebJars** support to Struts core: client-side libraries 
packaged as WebJars (`org.webjars:*`, shipped under 
`META-INF/resources/webjars/<name>/<version>/…`) can be referenced by a 
**version-less logical path** and are resolved + served through Struts' 
existing static-content pipeline.
   
   Example: a template references `bootstrap/css/bootstrap.min.css` → Struts 
serves `META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css` at 
`<ctx>/static/webjars/bootstrap/5.3.8/css/bootstrap.min.css`.
   
   ## Why
   
   Plugins/apps currently vendor client-side assets on the classpath and 
re-commit them each release (the struts2-bootstrap plugin commits ~2000 files 
by hand). WebJars replace this with a dependency bump (auto-updatable via 
Renovate/Dependabot). First intended consumer: the struts2-bootstrap plugin 
(separate work).
   
   ## Changes
   
   - **Dependency:** `org.webjars:webjars-locator-lite:1.1.3` (MIT; single 
Apache-2.0 transitive dep `jspecify`; no Jackson/classpath-scanner — the 
variant Spring Framework 6.2 adopted).
   - **`WebJarUrlProvider`** (container bean, the public seam for plugins) + 
`DefaultWebJarUrlProvider` wrapping a singleton `WebJarVersionLocator`.
   - **Serving:** a `/webjars/**` branch in `DefaultStaticContentLoader` 
reusing existing caching; content-type map extended for 
fonts/svg/source-maps/json/ico.
   - **`<s:webjar>` tag + `<@s.webjar>` macro** emitting the resolved URL 
string (composes with `<s:script>`/`<s:link>`; supports `var`).
   - **Config:** `struts.webjars.enabled` (default `true`), 
`struts.webjars.allowlist` (comma-separated; empty = all).
   
   ## Security
   
   Resolution is hard-constrained to the `META-INF/resources/webjars/` root: 
per-segment `..`/`.` rejection and backslash rejection before the locator is 
called, a containment re-check on the resolved path, locator-backed resolution 
only (unknown webjar → null), plus the optional allowlist. Unresolved / 
disabled / traversal / allowlist-blocked all **fail closed** (404 when serving, 
empty output when building URLs). This is hardening for the new endpoint, not a 
fix to existing shipped behavior.
   
   ## Testing
   
   - Unit: resolution (known → versioned path/URL; unknown → empty), traversal 
rejection (both `resolveResourcePath` and `resolveUrl`), allowlist, disabled; 
content-type mappings.
   - Serving: 200 + content-type for a known asset, 404 for unknown, 404 when 
disabled (servlet-mocked).
   - Tag/macro: renders the resolved URL; `var` storage; empty on unresolved.
   - Full `core` suite: **2985 tests, 0 failures**. No regression to existing 
static-content serving.
   
   Backward compatible: `enabled=true` only activates the new 
`<staticContentPath>/webjars/**` namespace; existing `/static/**` serving is 
untouched.




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1027815)
    Remaining Estimate: 0h
            Time Spent: 10m

> Add WebJars support to Struts core
> ----------------------------------
>
>                 Key: WW-5640
>                 URL: https://issues.apache.org/jira/browse/WW-5640
>             Project: Struts 2
>          Issue Type: New Feature
>          Components: Core
>            Reporter: Lukasz Lenart
>            Priority: Major
>             Fix For: 7.3.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Add first-class WebJars support to Struts core so client-side libraries 
> packaged as WebJars (shipped under 
> {{META-INF/resources/webjars/<name>/<version>/…}}) can be referenced by a 
> version-less logical path and served through Struts' existing static-content 
> pipeline.
> Example: a template references bootstrap/css/bootstrap.min.css; Struts 
> resolves and serves 
> {{META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css}}.
> Today plugins and apps vendor client-side assets directly on the classpath 
> and re-commit them on every upgrade (the struts2-bootstrap plugin commits 
> ~2000 files by hand each release). WebJars replace this with a dependency 
> bump (auto-updatable via Renovate/Dependabot).
> Scope (core only):
> - Add {{org.webjars:webjars-locator-lite}} (MIT; one Apache-2.0 transitive 
> dep) for version resolution.
> - New {{WebJarUrlProvider}} container bean — the public, injectable seam for 
> plugins.
> - Serve {{<staticContentPath>/webjars/**}} via a branch in 
> {{DefaultStaticContentLoader}}, reusing existing caching; extend content-type 
> coverage for fonts/svg/source-maps.
> - Thin {{<s:webjar>}} tag + {{<@s.webjar>}} macro emitting the resolved URL 
> string.
> - New config: {{struts.webjars.enabled}} (default true), 
> {{struts.webjars.allowlist}} (optional).
> - Security: constrain resolution to the webjars root, block .. traversal, 
> fail closed (404 / no URL) on unresolved paths.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to