def get_context(self):
        conf = Config()
        conf.STATSD_HOST = ''
        ctx = Context(config=conf)
        ctx.request = RequestParameters()

        return ctx
Beispiel #2
0
    def get(self,
            crypto,
            image,
            security_key=None,
            **kw):

        cr = Crypto(security_key or self.context.config.SECURITY_KEY)

        try:
            opt = cr.decrypt(crypto)
        except ValueError:
            opt = None

        if not opt and not security_key and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE:
            security_key = self.storage.get_crypto(image)

            cr = Crypto(security_key or self.context.config.SECURITY_KEY)
            opt = cr.decrypt(crypto)

        image_hash = opt and opt.get('image_hash')
        image_hash = image_hash[1:] if image_hash and image_hash.startswith('/') else image_hash
        path_hash = hashlib.md5(image).hexdigest()

        if not image_hash or image_hash != path_hash:
            self._error(404, 'Request denied because the specified image hash is not valid.')
            return

        opt['image'] = image

        self.context.request = RequestParameters(**opt)

        return self.execute_image_operations()
Beispiel #3
0
    async def test_should_raise_for_invalid_compatibility_storage(self):
        request = RequestParameters(url="/image.jpg", )
        config = Config(
            FILE_LOADER_ROOT_PATH=STORAGE_PATH,
            STORES_CRYPTO_KEY_FOR_EACH_IMAGE=True,
        )
        importer = Importer(config)
        importer.import_modules()
        image_bytes = self.get_image_bytes("image.jpg")
        ctx = Context(self.context.server, config, importer)
        ctx.request = request
        storage = Storage(ctx)

        with expect.error_to_happen(
                RuntimeError,
                message=
            ("The 'COMPATIBILITY_LEGACY_RESULT_STORAGE' configuration should point "
             "to a valid result storage when using compatibility result storage."
             ),
        ):
            await storage.get()

        with expect.error_to_happen(
                RuntimeError,
                message=
            ("The 'COMPATIBILITY_LEGACY_RESULT_STORAGE' configuration should point "
             "to a valid result storage when using compatibility result storage."
             ),
        ):
            await storage.put(image_bytes)
Beispiel #4
0
    def get_filter(self, filter_name, params_string="", config_context=None):
        config = Config(
            FILTERS=[filter_name],
            LOADER="thumbor.loaders.file_loader",
            FILE_LOADER_ROOT_PATH=join(dirname(realpath(__file__)), "fixtures",
                                       "filters"),
        )
        importer = Importer(config)
        importer.import_modules()

        req = RequestParameters()

        srv = ServerParameters(8888, "localhost", "./tests/test.conf", None,
                               "DEBUG", None)
        srv._security_key = "MY_SECURE_KEY"

        context = Context(config=config, importer=importer, server=srv)
        context.request = req
        context.request.engine = context.modules.engine
        context.request_handler = mock.MagicMock(request=mock.MagicMock(
            protocol="http",
            host="localhost:8888",
        ))

        if config_context is not None:
            config_context(context)

        self.context = context

        fltr = importer.filters[0]
        fltr.pre_compile()

        context.transformer = Transformer(context)

        return fltr(params_string, context=context)
Beispiel #5
0
 def topic(self):
     config = Config(
         AUTO_WEBP=False,
         RESULT_STORAGE_FILE_STORAGE_ROOT_PATH="/tmp/thumbor/result_storages%s" % (random.choice(['', '/'])))
     context = Context(config=config)
     context.request = RequestParameters(accepts_webp=False)
     return FileStorage(context)
Beispiel #6
0
 def test_can_get_orig_dimensions(self):
     params = RequestParameters(
         width="orig",
         height="orig",
     )
     expect(params.width).to_equal('orig')
     expect(params.height).to_equal('orig')
Beispiel #7
0
        def topic(self):
            config = Config()
            context = Context(None, config, Importer(config))
            context.request = RequestParameters()

            engine = MockInvalidResultEngine(context=context)
            return engine.read()
Beispiel #8
0
    def get_filter(self, filter_name, params_string="", config_context=None):
        config = Config(FILTERS=[filter_name],
                        LOADER='thumbor.loaders.file_loader',
                        FILE_LOADER_ROOT_PATH=join(dirname(realpath(__file__)),
                                                   'fixtures', 'filters'))
        importer = Importer(config)
        importer.import_modules()

        req = RequestParameters()

        context = Context(config=config, importer=importer)
        context.request = req
        context.request.engine = context.modules.engine

        if config_context is not None:
            config_context(context)

        self.context = context

        fltr = importer.filters[0]
        fltr.pre_compile()

        context.transformer = Transformer(context)

        return fltr(params_string, context=context)
Beispiel #9
0
 def setUp(self):
     super(FakeRotateEngineRotateFilterTestCase, self).setUp()
     conf = Config()
     imp = Importer(conf)
     imp.filters = [Filter]
     self.context = Context(None, conf, imp)
     self.context.request = RequestParameters()
Beispiel #10
0
 def setUp(self):
     super().setUp()
     conf = Config()
     imp = Importer(conf)
     imp.filters = [Filter]
     self.context = Context(None, conf, imp)
     self.context.request = RequestParameters()
Beispiel #11
0
    def on_finish(self):
        super().on_finish()
        self.context = getattr(self, "context", None)

        if self.context is None:
            return

        if not hasattr(self.context, "request"):
            self.context.request = RequestParameters()

        total_time = (datetime.datetime.now() -
                      self._response_start).total_seconds() * 1000
        status = self.get_status()
        self.context.metrics.timing("response.time", total_time)
        self.context.metrics.timing(f"response.time.{status}", total_time)
        self.context.metrics.incr(f"response.status.{status}")

        if status == 200 and self.context is not None:
            if self.context.request.smart:
                self.context.metrics.incr("response.smart.count")
                self.context.metrics.timing("response.smart.latency",
                                            total_time)
            else:
                self.context.metrics.incr("response.not_smart.count")
                self.context.metrics.timing("response.not_smart.latency",
                                            total_time)

        if self._response_ext is not None:
            ext = self._response_ext
            self.context.metrics.incr(f"response.format{ext}")
            self.context.metrics.timing(f"response.time{ext}", total_time)

            if self._response_length is not None:
                self.context.metrics.incr(f"response.bytes{ext}",
                                          self._response_length)
Beispiel #12
0
 def test_can_get_params_with_custom_crop():
     params = RequestParameters(
         crop={"top": 30, "right": 20, "bottom": 40, "left": 10}
     )
     expect(params.crop).to_be_like(
         {"top": 30, "right": 20, "bottom": 40, "left": 10}
     )
     expect(params.should_crop).to_be_true()
Beispiel #13
0
 def test_can_get_params_from_request(self):
     request = mock.Mock(path='/test.jpg',
                         headers={
                             'Accept': 'image/webp',
                         })
     params = RequestParameters(request=request, image='/test.jpg')
     expect(params.accepts_webp).to_be_true()
     expect(params.image_url).to_equal('/test.jpg')
Beispiel #14
0
    def get(self, **kw):

        if not self.validate(kw['image']):
            self._error(404)
            return

        self.context.request = RequestParameters(**kw)
        return self.execute_image_operations()
    def get_context(self):
        conf = Config()
        conf.STATSD_HOST = ''
        ctx = Context(config=conf)
        ctx.request = RequestParameters()
        ctx.request.filters.append('auto')

        return ctx
Beispiel #16
0
    def get_context(self):
        conf = Config()
        conf.STATSD_HOST = ''
        conf.FFMPEG_PATH = which('ffmpeg')
        ctx = Context(config=conf)
        ctx.request = RequestParameters()
        ctx.request.filters.append('gifv')

        return ctx
Beispiel #17
0
    def get_context(self):
        conf = Config()
        conf.STATSD_HOST = ""
        conf.FFMPEG_PATH = which("ffmpeg")
        ctx = Context(config=conf)
        ctx.request = RequestParameters()
        ctx.request.filters.append("gifv")

        return ctx
Beispiel #18
0
        def topic(self):
            ctx = get_context()
            ctx.modules.engine.image = ctx.modules.engine.gen_image((10, 10), 'rgba(0,0,0,0)')
            req = RequestParameters(width=10, height=10)
            ctx.request = req

            filter_instances = ctx.filters_factory.create_instances(ctx, "fill(ff0000, false)")
            filter_instances[0].run()
            return ctx.modules.engine
Beispiel #19
0
    def check_image(self, kw):
        if self.context.config.MAX_ID_LENGTH > 0:
            # Check if an image with an uuid exists in storage
            exists = yield gen.maybe_future(self.context.modules.storage.exists(kw['image'][:self.context.config.MAX_ID_LENGTH]))
            if exists:
                kw['image'] = kw['image'][:self.context.config.MAX_ID_LENGTH]

        url = self.request.path

        if not self.validate(kw['image']):
            self._error(400, 'No original image was specified in the given URL')
            return

        kw['request'] = self.request
        kw['image'] = quote(kw['image'].encode('utf-8'))

        self.context.request = RequestParameters(**kw)

        has_none = not self.context.request.unsafe and not self.context.request.hash
        has_both = self.context.request.unsafe and self.context.request.hash

        if has_none or has_both:
            self._error(400, 'URL does not have hash or unsafe, or has both: %s' % url)
            return

        if self.context.request.unsafe and not self.context.config.ALLOW_UNSAFE_URL:
            self._error(400, 'URL has unsafe but unsafe is not allowed by the config: %s' % url)
            return

        if self.context.config.USE_BLACKLIST:
            blacklist = yield self.get_blacklist_contents()
            if self.context.request.image_url in blacklist:
                self._error(400, 'Source image url has been blacklisted: %s' % self.context.request.image_url)
                return

        url_signature = self.context.request.hash
        if url_signature:
            signer = self.context.modules.url_signer(self.context.server.security_key)

            url_to_validate = url.replace('/%s/' % self.context.request.hash, '') \
                .replace('/%s/' % quote(self.context.request.hash), '')

            valid = signer.validate(unquote(url_signature), url_to_validate)

            if not valid and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE:
                # Retrieves security key for this image if it has been seen before
                security_key = yield gen.maybe_future(self.context.modules.storage.get_crypto(self.context.request.image_url))
                if security_key is not None:
                    signer = self.context.modules.url_signer(security_key)
                    valid = signer.validate(url_signature, url_to_validate)

            if not valid:
                self._error(400, 'Malformed URL: %s' % url)
                return

        self.execute_image_operations()
Beispiel #20
0
 def test_can_get_params_with_crop():
     params = RequestParameters(
         crop_left=10,
         crop_right=20,
         crop_top=30,
         crop_bottom=40,
     )
     expect(params.crop).to_be_like(
         {"top": 30, "right": 20, "bottom": 40, "left": 10}
     )
Beispiel #21
0
        def topic(self):
            ctx = get_context()
            for item in DATA:
                ctx.modules.engine.image = ctx.modules.engine.gen_image(item[1], '#fff')
                req = RequestParameters(fit_in=True, width=item[0][0], height=item[0][1])
                ctx.request = req

                filter_instances = ctx.filters_factory.create_instances(ctx, "fill(blue)")
                filter_instances[0].run()
                yield (filter_instances[0].engine.image.size, item[2])
Beispiel #22
0
 def test_can_get_params_with_custom_crop(self):
     params = RequestParameters(
         crop={
             'top': 30, 'right': 20, 'bottom': 40, 'left': 10
         }
     )
     expect(params.crop).to_be_like({
         'top': 30, 'right': 20, 'bottom': 40, 'left': 10
     })
     expect(params.should_crop).to_be_true()
Beispiel #23
0
 def test_can_get_params_with_crop(self):
     params = RequestParameters(
         crop_left=10,
         crop_right=20,
         crop_top=30,
         crop_bottom=40,
     )
     expect(params.crop).to_be_like({
         'top': 30, 'right': 20, 'bottom': 40, 'left': 10
     })
    def to_context(self, detectors=None, ignore_detector_error=False):
        if detectors is None:
            detectors = []
        ThreadPool.reset()
        self.engine = MockEngine((self.source_width, self.source_height))

        flip_horizontally = flip_vertically = False

        if self.target_width != "orig":
            flip_horizontally = self.target_width < 0
            self.target_width = abs(self.target_width)

        if self.target_height != "orig":
            flip_vertically = self.target_height < 0
            self.target_height = abs(self.target_height)

        importer = Importer(None)
        importer.detectors = detectors
        importer.storage = NoStorage
        config = Config()
        config.IGNORE_SMART_ERRORS = ignore_detector_error
        ctx = Context(server=None, config=config, importer=importer)
        ctx.modules.engine = self.engine

        ctx.request = RequestParameters(
            buffer=None,
            debug=False,
            meta=self.meta,
            crop={
                "left": self.crop_left,
                "top": self.crop_top,
                "right": self.crop_right,
                "bottom": self.crop_bottom,
            },
            adaptive=self.adaptive,
            full=self.full,
            fit_in=self.fit_in,
            horizontal_flip=flip_horizontally,
            vertical_flip=flip_vertically,
            width=self.target_width,
            height=self.target_height,
            halign=self.halign,
            valign=self.valign,
            focal_points=self.focal_points,
            smart=True,
            extension="JPEG",
            filters=[],
            quality=80,
            image="some.jpeg",
            stretch=self.stretch,
        )
        ctx.request.engine = self.engine
        ctx.request.engine.extension = ".jpeg"

        return ctx
Beispiel #25
0
        def topic(self):
            conf = Config()
            imp = Importer(conf)
            imp.filters = [Filter]
            ctx = Context(None, conf, imp)
            ctx.request = RequestParameters()

            filter_instances = ctx.filters_factory.create_instances(
                ctx, "format(invalid)")

            filter_instances[0].run()
Beispiel #26
0
    def get_optimizer(self, filters=None, progressive=False):
        conf = Config()
        conf.STATSD_HOST = ''
        conf.JPEGTRAN_PATH = '/somewhere/jpegtran'
        conf.PROGRESSIVE_JPEG = progressive
        req = RequestParameters(filters=filters)
        ctx = Context(config=conf)
        ctx.request = req
        optimizer = Optimizer(ctx)

        return optimizer
Beispiel #27
0
    def get_optimizer(filters=None, progressive=False, scans_file=""):
        conf = Config()
        conf.STATSD_HOST = ""
        conf.JPEGTRAN_PATH = "/somewhere/jpegtran"
        conf.PROGRESSIVE_JPEG = progressive
        conf.JPEGTRAN_SCANS_FILE = scans_file
        req = RequestParameters(filters=filters)
        ctx = Context(config=conf)
        ctx.request = req
        optimizer = Optimizer(ctx)

        return optimizer
    def topic(self):
        conf = Config()
        req = RequestParameters(quality=100)
        ctx = Context(None, conf, None)
        ctx.request = req

        filters = [Filter]
        compile_filters(filters)
        filter_instances = create_instances(ctx, filters, "quality(10)")

        filter_instances[0].run_filter()
        return ctx.request.quality
Beispiel #29
0
        def topic(self):
            ctx = get_context()
            for item in DATA:
                (size_requested, size_cropped, size_results, image_color, detected_color) = item

                ctx.modules.engine.image = ctx.modules.engine.gen_image(size_cropped, image_color)
                req = RequestParameters(fit_in=True, width=size_requested[0], height=size_requested[1])
                ctx.request = req

                filter_instances = ctx.filters_factory.create_instances(ctx, "fill(auto)")

                yield (filter_instances[0].get_median_color(), detected_color)
Beispiel #30
0
        def topic(self):
            conf = Config()
            imp = Importer(conf)
            imp.filters = [Filter]
            ctx = Context(None, conf, imp)
            ctx.request = RequestParameters()

            runner = ctx.filters_factory.create_instances(ctx, "format(webp)")
            filter_instances = runner.filter_instances[
                thumbor.filters.PHASE_POST_TRANSFORM]

            filter_instances[0].run()
            return ctx.request.format