adonisjs / transmit

A Server-Sent-Event module for AdonisJS
MIT License
71 stars 5 forks source link

Gzip on the server was stopping Transmit from working #31

Open eduwass opened 1 week ago

eduwass commented 1 week ago

Package version

2.0.2

Describe the bug

Bug Report: Gzip Interference with Adonis Transmit/Client on Coolify Deployment

Description:

I'm new to Adonis and encountered an issue when deploying Adonis with Transmit (@adonisjs/transmit v2.0.2) and Transmit Client (@adonisjs/transmit-client v1.0.0) packages on a Hetzner VPS via Coolify. The setup works perfectly on my local machine but fails after deployment. I'm not entirely sure if this is a bug, but I wanted to report it in case others experience the same issue.

Environment:

Steps to Reproduce:

  1. Install Adonis and add Transmit and Transmit Client packages.
  2. Deploy the app to a Hetzner VPS via Coolify.
  3. Observe the failure.

Expected Behavior: Transmit should work as expected after deployment, similar to the local environment.

Actual Behavior:

Workaround: Disabling Gzip in Coolify (an option in the Coolify dashboard) resolved the problem.

Additional Information: Since I'm new to Adonis, Iā€™m not sure if this is a bug or a configuration issue. I'm happy to provide more details or logs if necessary.

If it's an actual configuration issue, I think adding this to the documentation for future users would be a good addition.

Thanks for the awesome work!

Reproduction repo

No response

RomainLanz commented 1 week ago

Hey @eduwass! šŸ‘‹šŸ»

This is interesting! Do you know which Reverse Proxy Coolify is setting up on your server?

Also, do you have any logs on your server that may explain why __transmit/events never answer? It should answer and keep the connection open.

I needed to add a few headers to make it work properly with Traefik and Nginx, so it may be something on our side.

eduwass commented 1 week ago

Hi @RomainLanz šŸ‘‹

Thanks for chiming in so quickly!

I believe Coolify does set up a reverse proxy using Traefik to manage traffic, here's a Configuration file I've found:

networks:
  coolify:
    external: true
services:
  traefik:
    container_name: coolify-proxy
    image: 'traefik:v3.1'
    restart: unless-stopped
    extra_hosts:
      - 'host.docker.internal:host-gateway'
    networks:
      - coolify
    ports:
      - '80:80'
      - '443:443'
      - '8080:8080'
    healthcheck:
      test: 'wget -qO- http://localhost:80/ping || exit 1'
      interval: 4s
      timeout: 2s
      retries: 5
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
      - '/data/coolify/proxy:/traefik'
    command:
      - '--ping=true'
      - '--ping.entrypoint=http'
      - '--api.dashboard=true'
      - '--api.insecure=false'
      - '--entrypoints.http.address=:80'
      - '--entrypoints.https.address=:443'
      - '--entrypoints.http.http.encodequerysemicolons=true'
      - '--entryPoints.http.http2.maxConcurrentStreams=50'
      - '--entrypoints.https.http.encodequerysemicolons=true'
      - '--entryPoints.https.http2.maxConcurrentStreams=50'
      - '--providers.docker.exposedbydefault=false'
      - '--providers.file.directory=/traefik/dynamic/'
      - '--providers.file.watch=true'
      - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
      - '--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json'
      - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'
      - '--providers.docker=true'
    labels:
      - traefik.enable=true
      - traefik.http.routers.traefik.entrypoints=http
      - traefik.http.routers.traefik.service=api@internal
      - traefik.http.services.traefik.loadbalancer.server.port=8080
      - coolify.managed=true

Regarding the request, my server logs were showing a completed HTTP request, but it didn't show up as completed in the browser:

[14:13:45.505] INFO (140): Completed HTTP request
    method: "GET"
    url: "/__transmit/events"
    requestHeaders: {
      "host": "gzip.sp500.info",
      "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Safari/605.1.15",
      "accept": "application/json",
      "accept-encoding": "gzip, deflate, br",
      "accept-language": "en-US,en;q=0.9",
      "cache-control": "no-cache",
      "cookie": "adonis-session=s%3AeyJtZXNzYWdlIjoieXBsZnMxM240d3hlZmprYXVmMXR5ZzFwIiwicHVycG9zZSI6ImFkb25pcy1zZXNzaW9uIn0.YVWZnXsjdstZqEyUwFCY08vzmfqyFk4n-5IizkfkoPk",
      "pragma": "no-cache",
      "priority": "u=3, i",
      "referer": "https://gzip.sp500.info/",
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-forwarded-for": "194.158.70.13",
      "x-forwarded-host": "gzip.sp500.info",
      "x-forwarded-port": "443",
      "x-forwarded-proto": "https",
      "x-forwarded-server": "5ef697d65c1a",
      "x-real-ip": "194.158.70.13",
      "x-request-id": "txrc88ky54xj8tix998i8hsq"
    }
    requestBody: {}
    responseHeaders: {
      "set-cookie": "adonis-session=s%3AeyJtZXNzYWdlIjoieXBsZnMxM240d3hlZmprYXVmMXR5ZzFwIiwicHVycG9zZSI6ImFkb25pcy1zZXNzaW9uIn0.YVWZnXsjdstZqEyUwFCY08vzmfqyFk4n-5IizkfkoPk; Max-Age=7200; Path=/; HttpOnly; Secure; SameSite=Lax"
    }
    status: 200
    responseTime: 2.27261
    clientIp: "172.18.0.3"
    queryString: {
      "uid": "d0585165-e6b7-4227-a5e0-18248afcee4e"
    }
    routeParams: {}
    acceptedTypes: [
      "application/json"
    ]
    operation: "completed_http_request"
    file: "app/build/app/middleware/log_request.js"
    function: "LogRequest.handle"

The moment I disabled Gzip in the Coolify UI, this option here: 000216@2x

The request started successfully responding.

I've deployed two instances of the same project with and without gzip to be able to easily see the difference in behavior:

If you open up network tab on the gzip one you'll see how /events is not resolving.

RomainLanz commented 5 days ago

Can you try to monkeypatch the @boringnode/transmit module and add Content-Encoding: deflate in the header sent?