Gusb3ll / elysia-compression

Compression plugin for elysia
https://www.npmjs.com/package/elysia-compression
MIT License
21 stars 8 forks source link

Doesn't work well with html plugin #2

Closed webdevcody closed 1 year ago

webdevcody commented 1 year ago

I was working on an app which uses the "@elysiajs/html" plugin, but depending on where I call .use(compression()), my browser would either download a file when I load my route, or it wouldn't apply compression at all.

For example, this code just made my browser download the file

new Elysia()
  .use(compression())
  .use(html())

but this code just never ran the compression

new Elysia()
  .use(html())
  .use(compression())

I am doing some other things in my app, so maybe there is another issue, but my fix was the remove the html() plugin and instead directly set the content-type in my routes so allow compression to be applied.

Gusb3ll commented 1 year ago

Will have a look, ty for reporting 👍

M-Gonzalo commented 1 year ago

Same happened to me a couple of hours ago

Gusb3ll commented 1 year ago

Same happened to me a couple of hours ago

Try upgrading to 0.0.5 and see if its still happen 🙏

M-Gonzalo commented 1 year ago

Same happened to me a couple of hours ago

Try upgrading to 0.0.5 and see if its still happen 🙏

Reinstalled 0.0.5 but same happens. Depending on where I put it, it either doesn't do anything at all, or causes the browser to download a file

Gusb3ll commented 1 year ago

Seem like I can't reproduce on my end, can you provide the code snippet for me?

image
Host: localhost:4000
User-Agent: insomnia/8.1.0
Accept: */*
Content-Type: text/html; charset=utf8
Content-Encoding: deflate
Date: Sat, 30 Sep 2023 06:04:09 GMT
Content-Length: 80

Here's my implementation

import { Elysia } from 'elysia'
import { html } from '@elysiajs/html'
import { compression } from 'elysia-compression'

const app = new Elysia()
  .use(html())
  .use(compression({ type: 'deflate' }))
  .all('/', () => ({ value: 'Hello, World!' }))
  .get(
    '/html',
    () =>
      `<html lang="en">
        <head>
          <title>Hello World</title>
        </head>
        <body>
          <h1>Hello World</h1>
        </body>
      </html>`,
  )
  .listen(4000)

console.log(
  `Elysia is running at http://${app.server?.hostname}:${app.server?.port}`,
)

export type App = typeof app
M-Gonzalo commented 1 year ago

@Gusb3ll

import { Elysia } from "elysia"
import { swagger } from "@elysiajs/swagger"

import logger from "./plugins/basicLogger"
import successResponseFormatter from "./plugins/successResponseFormatter"

const app = new Elysia()
  .use(logger)
  .use(swagger())
  .use(successResponseFormatter)
  // Simulate a delay of at most one and a half second
  .get("/:id", ({ params: { id } }) => Bun.sleep(Math.random() * 1_500).then(() => ({ id })))
  .all("*", ({ set }) => { set.status = 404; return { success: false, error: "Not found" } })
  .listen(3000)

console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`)

This is my app. I tried introducing compression at every level, and even commenting out all additional functionality, like plugins. Maybe it's working for you because you're returning HTML and I'm returning JSON?

Gusb3ll commented 1 year ago

Somehow the content-type header is malformed

Host: localhost:3000
User-Agent: insomnia/8.1.0
Accept: */*
Content-Encoding: gzip
content-type: application/octet-stream -> should be application/json
Date: Sun, 01 Oct 2023 03:13:19 GMT
Content-Length: 30

so when you open it in the browser it will download it

Gusb3ll commented 1 year ago

The current workaround should be just setting the header explicitly

  .get('/:id', ({ params: { id }, set }) => {
    set.headers['Content-Type'] = 'application/json'
    return Bun.sleep(Math.random() * 1_500).then(() => ({ id }))
  })

and now you can open it in the browser without it being downloaded with the compression applied

image
SaltyAom commented 1 year ago

5, please make sure to have compression plugin use after HTML plugin

Gusb3ll commented 1 year ago

Should be working on 0.0.6 now

grctest commented 12 months ago

I found it wasn't playing well with the swagger plugin neither, so I chose to implement compression myself https://github.com/BTS-CM/beet_api/blob/main/src/lib/cache.ts#L17 though i'll now need to add a compression flag so swagger can spit out uncompressed data too lol