Skip to content

Fix/Ajax download#83

Open
TDannhauer wants to merge 3 commits intoFRAMEWORK_6_0from
fix/Ajax-Download
Open

Fix/Ajax download#83
TDannhauer wants to merge 3 commits intoFRAMEWORK_6_0from
fix/Ajax-Download

Conversation

@TDannhauer
Copy link
Copy Markdown
Contributor

Summary

This PR adds PSR-15-compatible download handling for routed requests by introducing a dedicated download controller and wiring explicit download routes in Horde routing config.

Context / Problem

Attachment downloads in routed/mobile flows could fall through the middleware stack and end in a generic fallback response (No Response by middleware or payload Handler) when no matching download endpoint was resolved in the PSR-15 path.
Historically, downloads were handled by the legacy script endpoint (services/download/index.php). As traffic increasingly goes through the router/middleware pipeline, that behavior needed an equivalent PSR-15 entry point.

Changes

vendor/horde/horde/config/routes.php

Added an explicit download service route in Horde routes:

  • Primary route: /services/download/
  • Secondary route: /services/download (no trailing slash variant)
  • Controller: DownloadController::class
  • Defaults: HordeAuthType => 'NONE'
  • Methods: GET, POST
    Why this matters
  • Ensures routed requests for download URLs are matched deterministically.
  • Handles both trailing-slash and no-slash URL forms.
  • Avoids route miss/fallback behavior in Rampage middleware flow.

vendor/horde/horde/src/DownloadController.php (new file)

Introduced a dedicated PSR-15 request handler for download service dispatch.
What it does

  • Implements Psr\Http\Server\RequestHandlerInterface.
  • Merges query/body parameters into Variables (legacy-compatible input shape).
  • Reads and normalizes fn into filename.
  • Delegates to legacy app download logic via:
    • $registry->callAppMethod($vars->app, 'download', ['args' => [$vars]])
  • Returns a PSR-7 response with download semantics:
    • Content-Type
    • Content-Disposition
    • Content-Length
    • Cache-Control
    • response body payload (string/resource paths handled)
      Why a separate controller
  • Keeps concerns separated:
    • AjaxDispatchController = AJAX dispatch/envelope flow
    • DownloadController = binary/file response flow
  • Better maintainability and clearer responsibility boundaries.
  • Cleaner fit to PSR-15 architecture than embedding binary-download behavior into AJAX dispatch code.

Behavioral Impact

  • Download requests routed through PSR-15 now receive a valid download response instead of middleware fallback.
  • Route matching is more robust due to dual /services/download + /services/download/ support.
  • Legacy download behavior is preserved in spirit by delegating to existing app-level download API methods.

Backward Compatibility / Risk

  • Additive change (new controller + new routes), no removal of legacy script endpoint.
  • Minimal risk to non-download flows.
  • Main risk surface is header/body behavior differences vs legacy script in edge cases; implementation mirrors expected semantics.

Validation Performed

  • PHP syntax checks passed for:
    • vendor/horde/horde/config/routes.php
    • vendor/horde/horde/src/DownloadController.php
  • No linter errors in touched files.

Test Plan

  • Open attachment download URLs with and without trailing slash route shape.
  • Verify downloads for common MIME types (application/pdf, images, generic binary).
  • Verify valid/invalid token and app combinations behave as expected.
  • Confirm no regression in existing AJAX endpoints (/services/ajax.php/...).

TDannhauer added 3 commits May 5, 2026 12:20
This class handles download service requests in a PSR-15 compliant manner, processing parameters and returning appropriate responses based on the request.
Added detailed PHPDoc comments to DownloadController class, explaining its purpose and usage as a PSR-15 controller for download service dispatch.
Added a new download service route with specified methods and defaults.
@TDannhauer TDannhauer requested a review from ralflang May 5, 2026 10:46
@TDannhauer
Copy link
Copy Markdown
Contributor Author

fixes together with PR horde/imp#38 issue horde/imp#37

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