Skip to content

feat: route checks honour the route verb - #149

Merged
oleksandr-nc merged 7 commits into
mainfrom
feat/route-verbs
Oct 23, 2026
Merged

oleksandr-nc merged 7 commits into
mainfrom
feat/route-verbs

Conversation

@oleksandr-nc

@oleksandr-nc oleksandr-nc commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

AppAPI's PHP proxy checks a request against an ExApp's routes by path and HTTP method: the first route whose URL and verb both match decides the access level. HaRP only looked at the path, so the first route with a matching URL decided for every method and the <verb> of the routes in info.xml had no effect. An ExApp that declares one URL with different verbs and access levels behaved differently behind HaRP than behind the PHP proxy, and a route that lists only GET accepted every other method as well.

AppAPI sends each route's verb to HaRP from its next releases on (nextcloud/app_api#1138, backported to stable32 to stable35), so HaRP can match the way the PHP proxy does.

Changes

  • The SPOE message passes the request method (method=method in spoe-agent.conf), and routes accept an optional verb.
  • The first route whose URL matches the path and whose verb lists the method decides, as in the PHP proxy. The method is compared case-sensitively with the methods listed in the verb (separated by commas or whitespace), and HEAD is accepted wherever GET is listed.
  • A method that no route of the path lists gets 405 Method Not Allowed with an Allow header. It is decided before the user lookup and does not count toward the IP ban, as link checkers, monitors and CORS preflight requests send such requests. The agent also sets not_found, so a custom /haproxy.cfg without the new 405 rule answers 404.
  • The bruteforce protection of the route that decided applies, instead of that of the first route with a matching URL.
  • Routes without a verb (AppAPI versions before the change above) and requests without a method (a custom spoe-agent.conf without method) keep the path-only matching.
  • README: a step for ExApp developers under "Adapting ExApps to use HaRP", including how older HaRP and AppAPI versions match routes.

As in the PHP proxy, a method can now also fall through to a later, broader route with a lower access level, for example to a USER catch-all after an ADMIN route that lists only some methods. I checked the routes of every ExApp in the App Store and of the public ExApps on GitHub against the requests their clients send. The only one affected is Visionatrix 1.5.1 (Nextcloud 32): the ComfyUI it embeds for admins sends PATCH to open its Logs panel, which the ExApp's route does not list, so that panel gets 405 until PATCH is added to the route.

HaRP uses the verbs once it loads an ExApp's routes: after a restart, or when AppAPI sends them on enabling or updating the ExApp.

Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 51d8010f-bb8d-4cf6-8a3d-921397067f8f
📥 Commits

Reviewing files that changed from the base of the PR and between bbc2109 and ae47f46.

📒 Files selected for processing: 2
  • .github/workflows/tests-deploy-docker.yml
  • tests/unit/test_route_verbs.py

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 339ab0aa-8c77-4c43-b409-2a314c66c669
📥 Commits

Reviewing files that changed from the base of the PR and between 430afb2 and bbc2109.

📒 Files selected for processing: 3
  • README.md
  • haproxy_agent.py
  • tests/unit/test_route_verbs.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

ExApp route configuration now supports HTTP method restrictions. The request method reaches the route handler, which selects the first route matching both path and method. When routes match the path but reject the method, the handler sets transaction variables that cause the HTTP and HTTPS frontends to return 405 with an Allow header. The README documents method declarations, HEAD handling, and URL-only matching for older HaRP or AppAPI versions that omit verbs.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to bbc21

Method-aware routing and 405 responses appear consistent across the handler and standard frontend configuration. No identified issue prevents merging after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 30 functions across 2 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "feat: route checks honour the route verb" matches the main change: HaRP now matches ExApp routes by path and HTTP verb, as the PHP proxy does. The summary covers the new optional verb on ro…
Description check Passed The description explains the problem (HaRP matched only by path, so route verbs had no effect), the fix (method-aware matching with the optional verb, 405 with Allow header, per-route bruteforce setti…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "feat: route checks honour the route verb" matches the main change: HaRP now matches ExApp routes by path and HTTP verb, as the PHP proxy does. The summary covers the new optional verb on routes, method-aware route selection, and the 405 response with an Allow header. The title is short, specific, and uses no vague terms.

Full details: Description check

Explanation

The description explains the problem (HaRP matched only by path, so route verbs had no effect), the fix (method-aware matching with the optional verb, 405 with Allow header, per-route bruteforce settings), and the README addition. It also gives the AppAPI dependency and compatibility notes. This matches the changeset in the summary, so the check passes.

Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 30 functions across 2 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1d5e7e12-e079-4026-b7bb-dcc33465df09
📥 Commits

Reviewing files that changed from the base of the PR and between 08945db and 430afb2.

📒 Files selected for processing: 5
  • README.md
  • haproxy.cfg.template
  • haproxy_agent.py
  • spoe-agent.conf
  • tests/unit/test_route_verbs.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread haproxy_agent.py Outdated
Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
…he deploy test

Signed-off-by: Oleksandr Piskun <oleksandr2088@icloud.com>
@oleksandr-nc
oleksandr-nc merged commit 7b64b10 into main Oct 23, 2026
18 checks passed
@oleksandr-nc
oleksandr-nc deleted the feat/route-verbs branch October 23, 2026 12:00
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