Pull to refresh

Comments 7

Не знаю насколько отдача заголовка 418 заслуживает описания на целую статью, возможно новичкам будет полезно, но есть одно «но» — данную проблему можно решить еще проще, переключив тип кеширования прям в интерфейсе cloudflare, если конечно не используется «уж очень разный» подход к кешированию (что бывает достаточно редко):
В статье ссылка на другую статью, которая относится к нестандартному кешированию.
Сей подход реализован через Page Rules: Cache level->cache everything.

Статья не о 418, а о том, как решить конкретную проблему (=побочный эффект от такого кеширования) через 418 код.
В общем, рабочий вариант:
image
+
image
Если брать тесты, то:

add_header Cache-Control "public, max-age=315360000";
В директиве сервер, следом
эмулятор
	location ~* "^/api/image/exif/(.*?)\.txt$" {
		default_type text/plain;
		set $testimageid $1;
		##backend
		if ($testimageid ~ 1337){
			add_header Cache-Control "private, max-age=0" always;
			return 404 "Image $testimageid not found";
		}
		return 200 "EXIF for $testimageid image";
		##backend
	}

Основной момент, это always в add_header Cache-Control "private, max-age=0" always;, так как nginx по умолчанию не хедеры с 4хх ответами.

и реальный бекенд
	location ~* "^/api/image/jexif/(.*?)\.txt$" {
		##backend
		proxy_pass http://localhost:8080/headerstest/headerstest.jsp?imgid=$1;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		##backend
	}


Вот код JSP:
<%@ page contentType="text/plain;charset=UTF-8" language="java" trimDirectiveWhitespaces="true" session="false" %>
<%
    String imgId = request.getParameter("imgid");
    if (imgId != null){
        if(imgId.equalsIgnoreCase("1337")) {
            response.setStatus(404);
            response.setHeader("Cache-Control", "private, max-age=0");
            out.print("file not found");
        }else{
            out.print("Exif for image "+imgId);
        }
    }
%>


Что в итоге?

В случае Cloudflare статья стала реальным костылем, пока лавочку не прикрыли. Так как если убрать add_header Cache-Control "public, max-age=315360000"; из директивы server, и оставить только в location:
например
	location / {
		add_header Cache-Control "public, max-age=315360000";
	}

И затем добавить к нашей динамике (в случае с JSP)
response.setHeader("Cache-Control", "public, max-age=20");

То мы получаем 20 секундный кеш ответов с динамики, вообще любой. Только что протестировал, и при такой раскладке бесплатно имеем главное преимущество более дорогих планов (30сек TTL и ниже только на ентерпрайзе).

Спасибо за наводку, я добавлю в статью.
От директивы set можно красиво избавиться — достаточно использовать в location именованные выделения:
location ~* "^/api/image/exif/(?P<testimageid>.*?)\.txt$" {
	default_type text/plain;
	##backend
	if ($testimageid ~ 1337){
		return 418 "Image $testimageid not found";
	}
	##backend
	return 200 "EXIF for $testimageid image";
}

Тогда сразу по виду регулярки понятно, что куда идёт.
Sign up to leave a comment.

Articles