webp-sh / webp_server_go

Go version of WebP Server. A tool that will serve your JPG/PNG/BMP/SVGs as WebP/AVIF format with compression, on-the-fly.
https://docs.webp.sh
GNU General Public License v3.0
1.83k stars 175 forks source link

Support multiple backends in proxy mode #206

Closed bugfest closed 1 year ago

bugfest commented 1 year ago

Is your feature request related to a problem? Please describe. As of version 0.8.0, webp_server_go only support a single backend URL to run in proxy mode. If a user wants to use the same instance to optimize assets from two different backends it's required to spin multiple service instances.

Describe the solution you'd like Allow webp_server_go to handle multiple backend instances and provide routing using host header mappings.

Also, currently enabling proxy mode depends on the config IMG_PATH; and it'd be safer to rely on a more imperative way to enable this mode; I suggest using PROXY.ENABLE = true to enable this mode.

E.g: Providing a configuration like:

{
  "HOST": "127.0.0.1",
  "PORT": "3333",
  "QUALITY": "80",
  "IMG_PATH": "/opt/pics",
  "EXHAUST_PATH": "/opt/exhaust",
  "ALLOWED_TYPES": ["jpg","png","jpeg","bmp"],
  "ENABLE_AVIF": false,
  "PROXY": {
    "ENABLE": true,
    "BACKEND": "http://origin.default-backend.com:8000",
    "HOST_MAP": {
      "www.example1.com": {
        "URL": "http://origin.example1.com:8000"
      },
      "www.example2.com": {
        "URL": "http://origin.example2.com:8000"
      }
    }
  }
}

0) curl -H 'Accept: image/webp' http://127.0.0.1:3333/path/to/image.jpg does not maches any mapping and fetches the remote image from http://origin.default-backend.com:8000/path/to/image.jpg and re-compress it in webp 1) curl -H 'Host: www.example1.com' -H 'Accept: image/webp' http://127.0.0.1:3333/path/to/image.jpg can fetch the remote image from http://origin.example1.com:8000/path/to/image.jpg and re-compress it in webp 2) curl -H 'Host: www.example2.com' -H 'Accept: image/webp' http://127.0.0.1:3333/path/to/image.jpg can fetch the remote image from http://origin.example2.com:8000/path/to/image.jpg and re-compress it in webp

Describe alternatives you've considered Spinning multiple instances of webp_server_go, one for each backend

Additional context When dealing with multiple backends, there's a possibility of collision in the local cache. There're also problems related with the URI sanitization, as these steps can alter the URI the backend is expecting.

As currently the URI is used to create the file path + name. I propose using a hashing function to not use URI to store those.

bugfest commented 1 year ago

PR to implement this feature #207

bugfest commented 1 year ago

Hi @n0vad3v, I noticed you added the discussion tag here; please let me know if you need me adding more info or context

n0vad3v commented 1 year ago

Hi @bugfest , sorry I've forgot to reply to this issue after some review on your PR creating labels on this, my apologies.😅

Thanks you very much for you PR and implementation, nicely done!

Currently my main concern about this feature is that, will this break the simplicity for the whole configuration, a similar situation to this is to support multi-path, which is implemented in https://github.com/webp-sh/webp_server_java , the configuration file for that looks like this:

{
  "host": "127.0.0.1",
  "port": 3333,
  "imgMap": {
    "/i": "/home/ubuntu/pic",
    "/img": "/home/ubuntu/pic2",
    "/": "/home/pic1"
  },
  "allowedTypes": ["jpg","png","jpeg","webp"]
}

While using WebP Server Go, the only way to archive this is to create symbol links, documented at https://docs.webp.sh/usage/multipath/. And both of them are not quite elegant in my view.

As currently our code structure is not elegant at all(tons of code are under main package) , @BennyThink and I are planning to do some code refactoring on it later.

So emmm, I am still a bit confused about whether WebP Server Go should involve these features right now. 😇

@BennyThink do you have any ideas on this?

BennyThink commented 1 year ago

We should have a refactor, use different package so we can take good use of exportable symbols.

bugfest commented 1 year ago

Thanks for the reply @n0vad3v & @BennyThink, would that be ok if I adapt my implemetation to support imgMap with local file & remote backend (as you can see, the feature I'm more interested in) so that the configuration remains simple?

For example, porting my conf example to yours:

{
  "HOST": "127.0.0.1",
  "PORT": "3333",
  "IMG_PATH": "/opt/pics",
  "IMG_MAP": {
    "/i": "/home/ubuntu/pic",
    "/img": "/home/ubuntu/pic2",
    "/": "/home/pic1",
    "http://www.example.com": "http://origin.example.com:8000",
  },
  "ALLOWED_TYPES": ["jpg","png","jpeg","webp"]
}

PS. I agree with the refactor; my very first contribution focused on code re-use. Happy to help.

n0vad3v commented 1 year ago

Closing this PR now as https://github.com/webp-sh/webp_server_go/pull/207 is already merged.