GithubHelp home page GithubHelp logo

imgproxy / imgproxy Goto Github PK

View Code? Open in Web Editor NEW
8.2K 77.0 594.0 35.73 MB

Fast and secure standalone server for resizing and converting remote images

Home Page: https://imgproxy.net

License: MIT License

Go 92.54% C 6.00% Dockerfile 0.39% Shell 0.66% JavaScript 0.41%
image resize-images crop-image microservice docker jpeg png libvips image-processing avif

imgproxy's Introduction

imgproxy logo

GH Test GH Lint Docker Pulls


imgproxy is a fast and secure standalone server for resizing, processing, and converting images. The guiding principles behind imgproxy are security, speed, and simplicity.

imgproxy is able to quickly and easily resize images on the fly, and it's well-equipped to handle a large amount of image resizing. imgproxy is a fast, secure replacement for all the image resizing code inside your web application (such as resizing libraries, or code that calls ImageMagick or GraphicsMagic). It's also an indispensable tool for processing images from a remote source. With imgproxy, you don’t need to repeatedly prepare images to fit your design every time it changes.

To get an even better introduction, and to dive deeper into the nitty gritty details, check out this article: imgproxy: Resize your images instantly and securely

Simplicity

"No code is better than no code."

imgproxy only includes the must-have features for image processing, fine-tuning, and security. Specifically,

  • It would be great to be able to flip images, apply masks, or round corners, but in most cases, it is possible — and is much easier — to do that using CSS.
  • It may be great to have built-in HTTP caching of some kind, but it is way better to use a Content-Delivery Network or a caching proxy server for this, as you will have to do this sooner or later in the production environment.
  • It might be useful to have everything built in — such as HTTPS support — but, again, an easy way to solve that would be just to use a proxying HTTP server, a load balancer, or a CDN.

Speed

imgproxy takes advantage of probably the most efficient image processing library out there – libvips. It’s scary fast and comes with a very low memory footprint. Thanks to libvips, we can readily and extemporaneously process a massive amount of images.

imgproxy uses Go’s raw (no wrappers) native net/http package to omit any overhead while processing requests and provides the best possible HTTP support.

You can take a look at some benchmarking results and compare imgproxy with some well-known alternatives in our benchmark report.

Security

In terms of security, the massive processing of remote images is a potentially dangerous endeavor. There are a number of possible attack vectors, so it’s a good idea to take an approach that considers attack prevention measures as a priority. Here’s how imgproxy does this:

  • imgproxy checks the image type and its “real” dimensions when downloading. The image will not be fully downloaded if it has an unknown format or if the dimensions are too big (you can set the max allowed dimensions). This is how imgproxy protects from so-called "image bombs”, like those described in this doc.

  • imgproxy protects image URLs with a signature, so an attacker cannot enact a denial-of-service attack by requesting multiple image resizes.

  • imgproxy supports authorization by HTTP header. This prevents imgproxy from being used directly by an attacker but allows it to be used via a CDN or a caching server — simply by adding a header to a proxy or CDN config.

Usage

Check out our 📑 Documentation.

Author

Sergey "DarthSim" Alexandrovich

Special thanks

Many thanks to:

License

imgproxy is licensed under the MIT license.

See LICENSE for the full license text.

Security Contact

To report a security vulnerability, please contact us at [email protected]. We will coordinate the fix and disclosure.

imgproxy's People

Contributors

0xflotus avatar a1tus avatar apeckham avatar bantonj avatar darthsim avatar dependabot-preview[bot] avatar dependabot[bot] avatar ehiggs avatar envek avatar euaaaio avatar joec4i avatar koenpunt avatar mantos avatar marckohlbrugge avatar mcfedr avatar mikulas avatar phantomray avatar prasanna-rkumar avatar princemaple avatar printercu avatar r1w1s1 avatar renchap avatar rkallenkoot avatar sauerbraten avatar selul avatar skryukov avatar sxdx avatar sxppro avatar tuomasva avatar vasfed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imgproxy's Issues

Gravity Coordinates

In order to be able to replace the image rendering of TYPO3, a popular open source CMS on high volume sites, we would need a more specific focus definition instead of cardinal points.

TYPO3 stores it's focus information as floats in the following form

{"x":1.27308888826e-16,"y":0.23441582680105,"width":1,"height":0.7659494452306}

The focus area is defined via floats between 0 and 1 from the left top corner down to the right bottom. It is passed along the desired size and resizing type to the renderer. Would it be possible integrate that into imgproxy too?

Allow disabling signatures

As I run imgproxy behind the main application server to apply authorization, there's not much point in signing it. It's both coding and runtime overhead, so can we make it optional?

How to use imgproxy with https ?

Or how to make it work on https port.
Without https on my imgproxy server all the pages using it works as "unsafe"
Need some advice how to or what I should to to force it to serve as https
Temporarily I decided to deploy it on Heroku, but what url I should use ? with or without port number then ?
What I'm trying is: https://myimgproxy.herokuapp.com/ but I'm getting 404 ....
Ok sorted it. wrong key and salt :)

Beginner issue

I'm kinda confused, installed and it seems to work but (on local server it says: "request cancelled while waiting for connection (client timeout exceeded while awaiting headers)").
Is there any option to make it work on local machine ?
Before I've had an error related to the DNS, sorted it out changing DNS order but it still won't work :(

Feature Request: Rotation only

I want to be able to turn off the enlarge option, but I depend on the images being rotated according to their EXIF data.

ie: If I have a 300 x 300 image, and want a 500 x 500 thumbnail, I want to be able to turn enlarge off so that ImgProxy will still serve a 300 x 300 image. If that image has EXIF rotation, I still need the EXIF rotation to be applied in what is served to the client.

imgproxy 2.0.0 - Invalid token cause of url parameter

Hi DarthSim,

I just tested version 2.0.0 on our staging system and it only produces "Invalid token" errors.
It looks like version 2.0.0 now uses url parameters to calculate the Token.

version 1.1.8:
CfcihlU34vwExBCyL7m2Ojmyw4K13Y3cioWttti6yN4/fit/2330/1185/no/1/bG9jYWw6Ly8vY21zL2Ntcy41YTNiOGI4YjQ1MTQ0MC4xNDI2OTUzNi5qcGVn.webp => works
CfcihlU34vwExBCyL7m2Ojmyw4K13Y3cioWttti6yN4/fit/2330/1185/no/1/bG9jYWw6Ly8vY21zL2Ntcy41YTNiOGI4YjQ1MTQ0MC4xNDI2OTUzNi5qcGVn.webp?32256495 => works

version 2.0.0
CfcihlU34vwExBCyL7m2Ojmyw4K13Y3cioWttti6yN4/fit/2330/1185/no/1/bG9jYWw6Ly8vY21zL2Ntcy41YTNiOGI4YjQ1MTQ0MC4xNDI2OTUzNi5qcGVn.webp => works
CfcihlU34vwExBCyL7m2Ojmyw4K13Y3cioWttti6yN4/fit/2330/1185/no/1/bG9jYWw6Ly8vY21zL2Ntcy41YTNiOGI4YjQ1MTQ0MC4xNDI2OTUzNi5qcGVn.webp?32256495 => doesn´t work

Is this the new default behavior?

Best regards
Marc

Default Config and Url Formarts

By now, more and more needs and parameters are added to the request URL, the format of /%signature/%resizing_type/%width/%height/%gravity/%enlarge/%encoded_url.%extension doesn't seem capable of taking too many parameters unless extending it to a very long string.

I think a default config should be set and we only need to set size and sometimes set other parameters by keywords.

Can't reach the original url

The original is http://temp.huabot.com/upload/b6e74385099c208fa310ee7d0168e270e40de4c9.jpg

the encode url is:

https://gw.huabot.com/5dfdfd4631d32b3d7f43/8tTFM0X5HpqCoeZYobmmpNKLfzy--Osv3LWC016AyPQ/fill/140/140/no/1/aHR0cDovL3RlbXAu/aHVhYm90LmNvbS91/cGxvYWQvYjZlNzQz/ODUwOTljMjA4ZmEz/MTBlZTdkMDE2OGUy/NzBlNDBkZTRjOS5q/cGc.png

but the imgproxy can not reach the original url

in base64 debug

$ echo aHR0cDovL3RlbXAuaHVhYm90LmNvbS91cGxvYWQvYjZlNzQzODUwOTljMjA4ZmEzMTBlZTdkMDE2OGUy
http://temp.huabot.com/upload/b6e74385099c208fa310ee7d0168e270e40de4c9.j

$ echo 'http://temp.huabot.com/upload/b6e74385099c208fa310ee7d0168e270e40de4c9.jpg' | base64
aHR0cDovL3RlbXAuaHVhYm90LmNvbS91cGxvYWQvYjZlNzQzODUwOTljMjA4ZmEzMTBlZTdkMDE2OGUyNzBlNDBkZTRjOS5qcGcK

not the right original url

https issue

Because I still have some issues with Https ... Is there any other option than docker ?
For example use it on normal CentOS server ?
if yes how to do it ?
I couldn't find a word about ....

Background colour for jpegs

Hello, it would be helpful if it would be possible to set the background color for jpges when creating them from image types with alpha channel.

Problem on install

I am using CentOS 7 and already installed vips but when I type

go get -f -u github.com/DarthSim/imgproxy

this error appear.

# pkg-config --cflags vips
Package vips was not found in the pkg-config search path.
Perhaps you should add the directory containing `vips.pc'
to the PKG_CONFIG_PATH environment variable
No package 'vips' found
pkg-config: exit status 1

Anyone can help?

UPDATE:
NO PROBLEM, solved, I just add
PKG_CONFIG_PATH point to /usr/local/lib/pkgconfig

Huge image: Image is unreachable error

No Need to Protect Extensions

The supported format of browsers/clients needed to be checked on the browser side or on the app side, if the extensions can be changed on the user side, it would be more convenient to use.

I've read in the document, the reason to protect URLs is to prevent DDOS attacks, but as the support of the extensions is limited, the harm is slight and I think the benefit is worth the cost?

By the way, thanks for your great efforts.
This project is awesome!

Imgproxy on CentOS - vips installed, still don't work

Guys, I've spent a quiet few minutes to install all the dependencies, required by "vips" required by Imgproxy but it still won't work.
[root@.......]# rpm -Uvh vips-8.5.8-1.el7.remi.x86_64.rpm
warning: vips-8.5.8-1.el7.remi.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 00f97f56: NOKEY
Preparing... ################################# [100%]
package vips-8.5.8-1.el7.remi.x86_64 is already installed

There must be still something missing or imgproxy's requirements are very precise ?
Wrong vips ?

allow to specify Etag random value

In console we see message:
2018/08/31 10:29:23 ETag support is activated. The random value was generated to be used for ETag calculation: c0fd3d0196c3209049f6dcf76af47226

It would be great to be able to specify Etag Random value in program startup using parameters/ env variables.

Reason:
If we run multiple instances we would like to have same Etag from every imgproxy running. If value is random generated on program start, the http ETAG signature header will change for every instance of imgproxy running.

Can't build on Ubuntu 16.04

$ cat /etc/issue
Ubuntu 16.04.2 LTS

$ go version
go version go1.6.2 linux/amd64

$ vips --version
vips-8.2.2-Sat Jan 30 17:12:08 UTC 2016

Geting the following:

$ go get -f -u github.com/DarthSim/imgproxy
# github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg
In file included from go/src/github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg/vips.go:5:0:
go/src/github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg/vips.h: In function ‘vips_reduce_bridge’:
go/src/github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg/vips.h:125:9: warning: implicit declaration of function ‘vips_reduce’ [-Wimplicit-function-declaration]
  return vips_reduce(in, out, xshrink, yshrink, NULL);
         ^
# github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg
/tmp/go-build499020947/github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg/_obj/vips.cgo2.o: In function `vips_reduce_bridge':
go/src/github.com/DarthSim/imgproxy/vendor/github.com/h2non/bimg/vips.h:125: undefined reference to `vips_reduce'
collect2: error: ld returned 1 exit status

Is there any minimal required version of go or libvips?

Accept Header support this time maybe?

Hi Sergey,

as you are actively working on version 2.0 I´d like to kindly ask if you could (again) think about implementing accept header support. I believe some of the other closed issues #4 and #23 had the same wish:
Providing jpg and webp over one URL based on browser support with the advantage of saving space in the picture element (or whatever others use) plus dynamically provide the best possible image.

I understand the danger of DDos but see two options:

  1. enable it through env var and leave it disabled as default
  2. dropping invalid headers in cdn (if supported) or nginx reverse proxy config to not reach imgproxy

Thank you and best regards
Marc

CORS Headers

There are tools such as cropperjs which try to do a regular GET for images to get more information before loading the image. Modern browsers will block this request due to the lack of CORS headers. It would be wonderful if we could configure ImgProxy to respond with Access-Control-Allow-Origin: * headers as well as responding to OPTIONS requests to allow this to work.

Feature Request: Multiple local folders

The feature request #42 is good, but can sets one folder only.
It will be more convenient if we would add two or more folders where imgproxy could finds images to resize.

Docker container restarts randomly

We observe random restarts when running the Docker container:

2018/05/28 10:09:01 [ZCn...Bn.jpg
2018/05/28 10:09:02 Starting server at :8080
2018/05/28 10:09:03 [w3m...Bn.jpg
2018/05/28 10:09:03 [Had...

This happens at least a couple of times per hour.

Use AWS S3 bucket as image source

S3 is a great place to store images and can be used as an image source. Once images are processed, it can be written to another path.

Filters support

Have you considered to add filters support?

At least sharpen would make sense, as proxied image with reduced dimension is always blurry due to the compression algorithm.

More question than issue

Is it possible to modify imgproxy code to be able to create a selected size of image even if aspect ratio is no 1x1. What I mean is I need to resize image to the very specific size like a 600x600 while image is for example 800x600. I don't want to cut anything I would like to fit it into 600x600 in the center of square and stripes above and below. Is imgproxy doing something like that ?
I can't see anything in manual.

Feature Request: Support Images from local file system

We absolutely love imgproxy for its simplicity. Currently we have an array of microservices orchestrated by dockers, and the containers all share a simple file volume so they can all access the files.

Currently to serve a thumbnail out of a file from the shared file volume, we would have to create another file http server, thus it incurs unnecessary file IO overhead because the file gets read, downloaded, read again before it is resized and served. It would be great that imgproxy could provide such capacity read files from file protocol. Thanks.

I tried adding a VIPS 8.5.8 to heroku but still no gif support

I made the app using the heroku button and then added this buildpack: https://github.com/kespry/heroku-buildpack-vips
It has VIPS 8.5.8 in there so above what the check does in the imgproxy code for gif support. Any idea why it would not work.

Here is an example of a URL i tried: https://epicpxls-imgproxy.herokuapp.com/n3jn6OCnw2FrV1sVJfCqw3mDtWFE6YDADRE-6H4KbcU/fill/300/300/no/1/aHR0cHM6Ly9pdGVt/cy5lcGljcHhscy5j/b20vc2hyaW5lL2Nh/Y2hlLzYwMjJkNTEx/ZmIxMmQ3Y2QyOGI5/MGJmMjdiZGFkNzEw/LmdpZg.gif

Rotate after resize

Hello, congratulations on your nice project!

It seems to apply EXIF autorotate at the start of processing:

https://github.com/DarthSim/imgproxy/blob/master/vips.h#L176

In my opinion, it's better to do rotates near the end. If you rotate at the start, you'll force libvips to decompress the whole image into memory then rotate from that. If you rotate after shrinking, there will be less work to do, and you'll be able to stream the shrink operation.

The libvips thumbnail operation handles it like this:

https://github.com/jcupitt/libvips/blob/master/libvips/resample/thumbnail.c#L338

  1. Open image, do any shrink-on-load. Images are opened in sequential access mode, so they can be streamed and will not need much memory.

1a. It has support for linear shrinking, which you can probably skip.

  1. Premultiply alpha, shrink, unpremultiply alpha, colour space transformation.

  2. If there's rotation, allocate a memory buffer, run the previous stages into that, then rotate from the memory buffer.

  3. Crop, embed, and write to output.

This order should drop memory use and also reduce latency, since processing can start as soon as the compressed image data is ready, and you won't need to wait for the input image to be decoded.

I may well have horribly misunderstood your code.

Consider larger default limits

Even regular (not panoramas) photos from iPhone (which is not the highest-resolution camera on the market) have 4032 × 3024 resolution nowadays. Consider increasing default limits.

Another suggestion: you have limits for maximum dimension. Let's assume that I want to support panorama photos from iPhone. Their resolution is up to 16382 × 3932 pixels which is about 64 megapixels. So I have to set IMGPROXY_MAX_SRC_DIMENSION to 16382. This unleashes sources up to 268 megapixels, which is totally crazy. So I suggest limiting source resolution instead of dimensions. In this case, I will be able to set IMGPROXY_MAX_SRC_RESOLUTION to 65MP and get the desired behaviour.

imgproxy doesn't rotate jpegs according to EXIF neither keeps EXIF

Some images should be displayed in the different orientation than physically stored in the file. This information is stored in Orientation EXIF tag.

imgproxy doesn't rotate the processed image according to EXIF and also strips EXIF completely from result images including orientation tag.

Most browsers nowadays don't respect that tag and don't rotate images, so someone should do it.

Some corrections

Hey Sergey,

Great job with imgproxy. We are thinking of writing a libvips engine for thumbor. I had not heard about it previously.

Anyways, just wanted to clarify a couple things from the article you published at https://evilmartians.com/chronicles/introducing-imgproxy, more specifically about the comparison below:

Cutting extra features and focusing on core functionality allows for a very lightweight and memory-efficient solution. Thumbor, for instance, is very powerful, but its Docker container is 300 times bigger than imgproxy’s. It also does not support 12factor and uses GraphicsMagick as an underlying library, which is considerably slower than vips. Imaginary does not focus on security; anyone can compose a right URL and piggyback on your service. The only protection this tool gives you is a way to set up Authorization HTTP header, but that approach, if not coupled with other security features, makes you vulnerable for a “man-in-the-middle” attack. You are not protected from image bombs either. Picfit uses storage to keep track of transformations. Pilbox does not use vips, does not support 12factor and relies on Tornado web server, that you might not need. Thumbor, by the way, also expects you to use additional software for caching. imgproxy has no such dependencies.

Do you mind clarifying which of the 12factor principles thumbor fails to achieve? If we are missing something it would be in our interest to improve. Thumbor was designed with utmost extensibility in mind, and as such allows all configuration to be overriden using environment variables and scales up using processes.

You are absolutely right in the part of cutting extra and focusing on core functionality, though. Thumbor's core team has been absolutely focused in reducing the codebase, taking advantage of thumbor's extensibility to create new projects for specific dependencies.

Thumbor also does not use GraphicsMagick, at least not stock thumbor. Thumbor uses Pillow engine, an engine in Python C. Maybe not as fast as libvips, but that's not an issue since thumbor's extensible nature allows us to try many different engines (also available GraphicsMagick and OpenCV).

Also, the assertion you make about thumbor's caching engine is just not true. Thumbor does feature an extensible storage of both original and transformed files. This extensibility allows you to use AWS S3, Redis, MongoDB, and a myriad other storage services for your images. That said, thumbor's default storage engine is the filesystem, meaning no additional software is required whatsoever.

I'm not here to bash imgproxy at all, since as a developer I welcome any software that might improve my goal of delivering an incredible experience to my end users, but I think the comparison you are making is being fair and as such is not in the best interest of the people reading your article.

Keep up the good work!

A changelog would be very useful

I am loving imgproxy more and more everyday for its simplicity of generating thumbnails. It's hard to keep track of every dependencies' versions and changes in my ever-increasing codebase. It would be so helpful and informative to keep a change log such as this example, so I can take advantage the latest and greatest.

imgproxy ate all free space on drive

I'm trying to process 7360 × 4912 pixels image and after each request, the free space on the system drive is reduced by 104 MB. This doesn't stop until all space is gone.

$ lsof -p 16119 |grep /tmp
imgproxy 16119 ubuntu    3u      REG  202,1 108557789   2190 /tmp/vips-1-1VW16Y.v (deleted)
imgproxy 16119 ubuntu    7u      REG  202,1 108557789   2847 /tmp/vips-2-ITW36Y.v (deleted)

By the way, 7360*4912*3 ≈ 104 MB.

Vips

Everything works but from time to time I see this error message:
"vips_colourspace: no known route from 'cmyk' to 'srgb'".
Any ideas what to do with it ?
vips supplied wirh imgproxy image so ..... ?
Update ? Fix ?
eventually ..... ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.