Skip to content

Payjoin Mailroom Tracking Issue #941

Open

Description

@nothingmuch

See #775 for discussion

Sub bullets indicate spinoffs of parent, which are directly dependent. Otherwise tasks mostly don't depend on each other.
Most of these do depend on #1232 however, as the ultimate goal here is to unify the directory and relay services.

blocking first release



Far future:

Activity

  1. DanGould commented on Aug 26, 2025

    @DanGould
    Member

    Now that ohttp-relay is up to date with 1.85.0, it could be brought into this repository as a monorepo item. However, it depends on ureq for proxy which'd be nice to replace with reqwest if possible and it depends on nginx for tls termination which would really be better to replace with whatever native ACME solution you cook up for the directory.

    In either case I don't think merging the repos affects payjoin crate's 1.0 stability now so I'm just noting these things for when the time is right.

  2. zealsham commented on Sep 25, 2025

    @zealsham
    Collaborator

    Now that ohttp-relay is up to date with 1.85.0, it could be brought into this repository as a monorepo item. However, it depends on ureq for proxy which'd be nice to replace with reqwest if possible and it depends on nginx for tls termination which would really be better to replace with whatever native ACME solution you cook up for the directory.

    In either case I don't think merging the repos affects payjoin crate's 1.0 stability now so I'm just noting these things for when the time is right.

    @DanGould The ureq crate is only used for integration test in the ohttp-relay repo . i did a replacement with reqswest on my local branch and all test-cases pass .

  3. benalleng commented on Sep 25, 2025

    @benalleng
    Collaborator

    Feel free to open a PR on the ohttp-relay so we can take a look

  4. Harshdev098 commented on Jan 30, 2026

    @Harshdev098
    Contributor

    Hey @spacebear21, Can I work on this refactor to move the existing OHTTP decrypt/encrypt + forwarding logic out of handlers and into a reusable Tower Layer / gateway. That keeps directory/relay logic OHTTP agnostic and easily portable to the unified payjoin-service.

  5. spacebear21 commented on Feb 4, 2026

    @spacebear21
    Collaborator

    Hey @Harshdev098 sorry for delayed response, that sounds like a good next step to follow up on #1296 ! I'd recommend rebasing and working on top of that PR to avoid conflicting work once it gets merged.

  6. 7 remaining items

  7. added a commit that references this issue on Mar 12, 2026
  8. changed the title [-]Directory Service Tracking Issue[/-] [+]Payjoin Mailroom Tracking Issue[/+] on Mar 13, 2026
  9. codaMW commented on Oct 30, 2026

    @codaMW
    Contributor

    I would like to take the "tower_http::limit, remove our custom body size limiter" item.

    The gap, current as of #1983: every request body in payjoin-mailroom/src/directory.rs is fully buffered before any size check, so memory is not bounded by the caps.

    • post_mailbox: body.collect().await...to_bytes() then if req.len() > MAX_MAILBOX_PAYLOAD_BYTES.
    • put_payjoin_v1: same, then > V1_MAX_BUFFER_SIZE.
    • post_fallback_v1: collects, then checks after building the v2-compat body.
    • handle_ohttp_gateway: collects the encapsulated body with no size check at all, even though a valid encapsulated message is a fixed ENCAPSULATED_MESSAGE_BYTES (8192).

    #1983's MAX_MAILBOX_PAYLOAD_BYTES / BHTTP_REQ_BYTES bound what can be stored and returned, which is complementary, but none of them stop a client from making the server buffer an arbitrarily large body first. That is the RAM gap noted here.

    Proposed fix: a tower_http::limit::RequestBodyLimitLayer at the service ingress so oversized bodies are rejected with 413 before being buffered, keeping the existing per-handler checks as semantic validation on the now-bounded body. tower-http is already a dependency (TraceLayer is in use); this enables its limit feature.

    Sizing, which #1983 mostly settles: the largest legitimate body is the direct V1 path at V1_MAX_BUFFER_SIZE (64 KiB); a V2 OHTTP request is a fixed ENCAPSULATED_MESSAGE_BYTES (8192). Two options:

    (a) one global ingress limit at 64 KiB: simplest, bounds per-request memory to 64 KiB everywhere, existing checks still enforce the tighter V2 cap.
    (b) per-route limits: 8192 on the OHTTP gateway route (anything larger is definitionally invalid) and 64 KiB on the direct V1 routes: tighter, rejects an oversized V2 body at the first byte past the fixed size.

    I lean (b) for the gateway since encapsulated messages are fixed size, but I will match your preference. Any reason to avoid a per-route limit?

    Tests: a body one byte over the limit returns 413 at ingress without the handler buffering it; a body at or under the limit still succeeds for V1 PUT, the V1 fallback POST, and the V2 gateway; existing behavior otherwise unchanged. Mailroom tests with default and all features, plus fmt and clippy.

    AI disclosure: I used an AI assistant to inspect the code and draft this comment. I will write and understand the implementation myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    trackingHigh-level tracking issues

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions