Skip to content

Commit

Permalink
views: no cache for badge view
Browse files Browse the repository at this point in the history
* (closes #54).
  • Loading branch information
Diego Rodriguez authored and lnielsen committed May 15, 2018
1 parent cc76296 commit 75a7b07
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
3 changes: 3 additions & 0 deletions invenio_formatter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@

FORMATTER_BADGES_TITLE_MAPPING = {}
"""Mapping of titles."""

FORMATTER_BADGES_MAX_CACHE_AGE = 0
"""The maximum amount of time a badge will be considered fresh."""
32 changes: 25 additions & 7 deletions invenio_formatter/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@

from __future__ import absolute_import, print_function

from flask import Blueprint, Response, current_app
import hashlib
from datetime import datetime as dt
from datetime import timedelta

from flask import Blueprint, Response, current_app, request


def create_badge_blueprint(allowed_types):
Expand Down Expand Up @@ -39,11 +43,25 @@ def badge(title, value, ext='svg'):
elif ext == 'png':
generator = generate_badge_png
mimetype = 'image/png'
return Response(
generator(
current_app.config['FORMATTER_BADGES_TITLE_MAPPING'].get(
title, title),
value),
mimetype=mimetype)

badge_title_mapping = \
current_app.config['FORMATTER_BADGES_TITLE_MAPPING'].get(
title, title)
response = Response(generator(badge_title_mapping, value),
mimetype=mimetype)
# Generate Etag from badge title and value.
hashable_badge = "{0}.{1}".format(badge_title_mapping,
value).encode('utf-8')
response.set_etag(hashlib.sha1(hashable_badge).hexdigest())
# Add headers to prevent caching.
response.headers["Pragma"] = "no-cache"
response.cache_control.no_cache = True
response.cache_control.max_age = \
current_app.config['FORMATTER_BADGES_MAX_CACHE_AGE']
response.last_modified = dt.utcnow()
extra = timedelta(
seconds=current_app.config['FORMATTER_BADGES_MAX_CACHE_AGE'])
response.expires = response.last_modified + extra
return response.make_conditional(request)

return blueprint
24 changes: 24 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,27 @@ def test_views_badge_png(app):
with app.test_client() as client:
response = client.get('/badge/DOI/value.png')
assert b'\x89PNG\r\n' in response.data


def test_views_badge_etag(app):
"""Test Etag for badges."""
with app.app_context():
with app.test_client() as client:
response = client.get('/badge/DOI/value.png')
response = client.get(
'/badge/DOI/value.png',
headers={'If-None-Match': response.headers['ETag']})
assert response.status_code == 304


def test_views_badge_no_cache_headers(app):
"""Test Etag for badges."""
with app.app_context():
with app.test_client() as client:
response = client.get('/badge/DOI/value.png')
assert response.headers['Pragma'] == 'no-cache'
cache_control_values = ['no-cache', 'max-age']
assert set(cache_control_values).issubset(response.cache_control)
assert response.last_modified
assert response.expires
assert response.get_etag()[0]

0 comments on commit 75a7b07

Please sign in to comment.