Skip to content

WW-3717 feat(core): restrict an action to HTTP methods with an http-method attribute - #2038

Merged
lukaszlenart merged 4 commits into
mainfrom
feature/WW-3717-http-method-attribute
Oct 17, 2026
Merged

lukaszlenart merged 4 commits into
mainfrom
feature/WW-3717-http-method-attribute

Conversation

@lukaszlenart

@lukaszlenart lukaszlenart commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Fixes WW-3717

Summary

  • New optional http-method attribute on <action> in struts-7.5.dtd, e.g. http-method="post" or http-method="get,post" (case-insensitive). An unknown method name fails configuration loading.
  • Enforced by HttpMethodInterceptor, which now reads the action config as well as the existing @HttpGet/@HttpPost/@AllowedHttpMethod… annotations. When both apply, the request must satisfy both.
  • Wildcard / regex actions keep the restriction declared on the pattern (ActionConfigMatcher).
  • A rejected request still gets the bad-request result when one can be resolved — exact name, a catch-all * result, or an unknown handler such as the Convention plugin. Otherwise the interceptor answers 405 with an Allow header and returns NONE, instead of failing with "No result defined".
  • A warning is logged at startup for an action that declares http-method while its interceptors do not include httpMethod.

One action name still maps to one config; routing the same name to different configs per method is WW-5785 (8.0.0). Convention-plugin coverage via the annotations is verified in WW-5786.

Behaviour changes worth a migration note

  • Annotation-only actions with no resolvable bad-request result now get 405 + Allow instead of a 500. Request methods outside HttpMethod (e.g. PROPFIND) on restricted actions now get 405 instead of an IllegalArgumentException.
  • Unit tests that run HttpMethodInterceptor through MockActionProxy must give it an ActionConfig, since the config is read on every request (and the rejection path needs a container on the ActionContext, which the test base classes already set). This is deliberately not null-guarded.
  • The existing testWildcardResolvedExecuteRejectsGetThroughRealProxy now asserts 405 + Allow: POST: its fixture maps no bad-request result.

Test plan

  • New XmlConfigurationProviderHttpMethodTest (parsing, list/case handling, wildcard carry-over, invalid value, startup warning) and new HttpMethodInterceptorTest cases (config only, annotation only, both, mapped / global / catch-all / unknown-handler results, 405 + Allow, unknown request method) — each watched failing before the implementation
  • Mutations checked: dropping the matcher copy, an exact-name-only result check, and config overriding the annotation each fail their tests
  • ./mvnw test -DskipAssembly -pl core — 3510 tests, 0 failures
  • ./mvnw install -DskipAssembly -DskipITs (full reactor, final commit) — 4850 tests, 0 failures, including the Convention plugin tests that caught an eager UnknownHandlerManager injection on the first push (fixed in ced991c: the manager is now looked up from the request's container only when a request is rejected)

Docs: struts-site PR follows (new "HTTP Methods" section in Action Configuration).

🤖 Generated with Claude Code

lukaszlenart and others added 2 commits October 16, 2026 16:34
…ethod attribute

Adds an optional http-method attribute to <action> in the 7.5 DTD,
enforced by HttpMethodInterceptor together with the existing
@HttpGet/@HttpPost/@AllowedHttpMethod annotations; when both apply the
request must satisfy both. Wildcard and regex actions keep the
restriction, and an invalid method name fails configuration loading.

A rejected request still gets the bad-request result when the action
maps one; otherwise the interceptor now answers 405 with an Allow
header instead of failing with "No result defined". A warning is logged
for an action that declares http-method but whose interceptors do not
include httpMethod.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ocation does

Before answering 405 the interceptor now also accepts a catch-all "*"
result and a result supplied by an unknown handler (e.g. the Convention
plugin's {action}-bad-request page), so existing annotation users keep
their page. Adds a test where the annotation narrows the configured
methods.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
lukaszlenart and others added 2 commits October 16, 2026 17:24
… is rejected

Injecting UnknownHandlerManager into HttpMethodInterceptor built the
unknown handlers while the interceptor was created during configuration
loading, before ConventionUnknownHandler could find its parent package,
which broke every Convention plugin application at startup. Resolve the
manager from the request's container only on the reject path instead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Makes ActionConfig.httpMethods private, narrows rejectRequest to throw
IOException, simplifies the end of equals, and tidies two tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sonarqubecloud

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart merged commit f69198c into main Oct 17, 2026
8 checks passed
@lukaszlenart
lukaszlenart deleted the feature/WW-3717-http-method-attribute branch October 17, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant