Class PushHttpHandler

java.lang.Object
com.iizix.server.push.engine.http.PushHttpHandler

public final class PushHttpHandler extends Object
The eight POST /iizi-push/<operation> operations of PUSH-WIRE-CONTRACT.md version 2, section 5: keys, subscribe, unsubscribe, reset, subscriptions, push, count and list. Every name on the wire comes from PushWire, which the client's izPush.WIRE is proved to equal.

The front door, in order (sections 1 and 3): anything but POST is 405; on a production server a request that is not on a secure port - decided by the one rule of WSHelper.isSecure, never by a header - is 403 secure_port_required before Authorization is read, with a WARNING naming the user whose credential crossed the network in clear; an unknown operation is 404; then the caller is authenticated, the body is parsed (empty is the empty object, anything but a JSON object is 400), and the operation checks its privilege (section 4), its device header (device operations only, section 5.0) and its members.

Every reply is a non-empty JSON object, application/json;charset=utf-8, Cache-Control: no-store, with ok. A failure is {ok:false, error, message} where error is from the closed vocabulary of PushWire.ERRORS, so a caller branches on it; a 401 carries the RFC 7617 challenge. No reply ever carries key material, a credential or the request's own subscription object: the subscription keys and FCM tokens enter in subscribe and never leave.

No challenge to a Browser (CC-PUSH-401-BASIC): a 401 to a request that carries Sec-Fetch-Mode or Origin (isBrowserRequest(HttpServletRequest)) is the same status and body without the challenge, which would open the Browser's own login dialog on a same-origin page.

Names: an application ID and a Topic are validated with Utilities.getValidName and the returned string, canonicalised through AppPushConfigs.canonicalAppId(String) when the application is loaded, is what is stored and looked up. On subscribe and unsubscribe, * is the server itself, the iiziRun clients that chose no application, and the empty Topic is the application-level subscription; on subscriptions, push, count and list, * is every application and the empty Topic every Topic (ruled 2026-09-26, CC-PUSH-ROADMAP row 5 A; PushEngine.send(String,String,long[],IPushNotification,DeliveryUrgency)).

The notification of push (section 6) is the caller's object with the server's data.iizi added: the message ID, the application, the Topic and the send time. The FCM leg alone adds the caller's object once more under data.iizi.notification (FcmTransport.buildMessage(String, PushMessage, long, DeliveryUrgency)), because the members FCM maps to native fields never reach the device's JavaScript; the Web Push leg, whose Service Worker decrypts the whole object, carries it once (ruled 2026-09-23, CC-PUSH-P3 RR-11). It is refused with 400 payload_too_large, before anything is sent, when the Web Push plaintext exceeds its limit, or when the FCM payload exceeds its limit and a recipient has an FCM subscription (section 6.3).

Author:
Christopher Mindus
  • Field Details

    • NO_UID

      public static final long NO_UID
      The uid of a caller that is not a database user: a user of the credentials file, or one registered from Java through IPushUserRegistry (PUSH-CREDENTIALS.md sections 3 and 7). Such a caller has no subscriptions and no device.
      See Also:
    • HEADER_DEVICE

      public static final String HEADER_DEVICE
      The device UUID header: "X-iizi".
      See Also:
  • Constructor Details

  • Method Details

    • handle

      public void handle(String operation, HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws IOException
      Handles one request.
      Parameters:
      operation - The operation name, one of PushWire.OPERATIONS, or null or any other string for a path that names none (answered 404 after the front door, so that a production server refuses an insecure request before it says which operations exist).
      request - The request.
      response - The response.
      out - The writer of the response.
      Throws:
      IOException - For I/O errors.