forwarded for and forwarded protocol

This commit is contained in:
Di Wu 2016-01-18 22:31:01 -08:00
parent 96b41ded9b
commit 2e6df69489
3 changed files with 50 additions and 28 deletions

View File

@ -5,33 +5,28 @@ from hc.api.models import Check, Ping
class PingTestCase(TestCase): class PingTestCase(TestCase):
def test_it_works(self): def setUp(self):
check = Check() super(PingTestCase, self).setUp()
check.save() self.check = Check.objects.create()
r = self.client.get("/ping/%s/" % check.code) def test_it_works(self):
r = self.client.get("/ping/%s/" % self.check.code)
assert r.status_code == 200 assert r.status_code == 200
same_check = Check.objects.get(code=check.code) same_check = Check.objects.get(code=self.check.code)
assert same_check.status == "up" assert same_check.status == "up"
pings = list(Ping.objects.all()) ping = Ping.objects.latest("id")
assert pings[0].scheme == "http" assert ping.scheme == "http"
def test_post_works(self): def test_post_works(self):
check = Check()
check.save()
csrf_client = Client(enforce_csrf_checks=True) csrf_client = Client(enforce_csrf_checks=True)
r = csrf_client.post("/ping/%s/" % check.code) r = csrf_client.post("/ping/%s/" % self.check.code)
assert r.status_code == 200 assert r.status_code == 200
def test_head_works(self): def test_head_works(self):
check = Check()
check.save()
csrf_client = Client(enforce_csrf_checks=True) csrf_client = Client(enforce_csrf_checks=True)
r = csrf_client.head("/ping/%s/" % check.code) r = csrf_client.head("/ping/%s/" % self.check.code)
assert r.status_code == 200 assert r.status_code == 200
assert Ping.objects.count() == 1 assert Ping.objects.count() == 1
@ -44,22 +39,44 @@ class PingTestCase(TestCase):
"AppleWebKit/537.36 (KHTML, like Gecko) " "AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/44.0.2403.89 Safari/537.36") "Chrome/44.0.2403.89 Safari/537.36")
check = Check() r = self.client.get("/ping/%s/" % self.check.code, HTTP_USER_AGENT=ua)
check.save()
r = self.client.get("/ping/%s/" % check.code, HTTP_USER_AGENT=ua)
assert r.status_code == 200 assert r.status_code == 200
pings = list(Ping.objects.all()) ping = Ping.objects.latest("id")
assert pings[0].ua == ua assert ping.ua == ua
def test_it_truncates_long_ua(self): def test_it_truncates_long_ua(self):
ua = "01234567890" * 30 ua = "01234567890" * 30
check = Check() r = self.client.get("/ping/%s/" % self.check.code, HTTP_USER_AGENT=ua)
check.save()
r = self.client.get("/ping/%s/" % check.code, HTTP_USER_AGENT=ua)
assert r.status_code == 200 assert r.status_code == 200
pings = list(Ping.objects.all()) ping = Ping.objects.latest("id")
assert len(pings[0].ua) == 200 assert len(ping.ua) == 200
assert ua.startswith(pings[0].ua) assert ua.startswith(ping.ua)
def test_it_reads_forwarded_ip(self):
ip = "1.1.1.1"
r = self.client.get("/ping/%s/" % self.check.code,
HTTP_X_FORWARDED_FOR=ip)
ping = Ping.objects.latest("id")
assert r.status_code == 200
assert ping.remote_addr == "1.1.1.1"
ip = "1.1.1.1, 2.2.2.2"
r = self.client.get("/ping/%s/" % self.check.code,
HTTP_X_FORWARDED_FOR=ip, REMOTE_ADDR="3.3.3.3")
ping = Ping.objects.latest("id")
assert r.status_code == 200
assert ping.remote_addr == "1.1.1.1"
def test_it_reads_forwarded_protocol(self):
r = self.client.get("/ping/%s/" % self.check.code,
HTTP_X_FORWARDED_PROTO="https")
ping = Ping.objects.latest("id")
assert r.status_code == 200
assert ping.scheme == "https"
def test_it_never_caches(self):
r = self.client.get("/ping/%s/" % self.check.code)
assert "no-cache" in r.get("Cache-Control")

View File

@ -1,4 +1,5 @@
from django.conf.urls import url from django.conf.urls import url
from hc.api import views from hc.api import views
urlpatterns = [ urlpatterns = [

View File

@ -4,13 +4,16 @@ from django.contrib.humanize.templatetags.humanize import naturaltime
from django.db.models import F from django.db.models import F
from django.http import HttpResponse, HttpResponseBadRequest from django.http import HttpResponse, HttpResponseBadRequest
from django.utils import timezone from django.utils import timezone
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from hc.api.decorators import uuid_or_400 from hc.api.decorators import uuid_or_400
from hc.api.models import Check, Ping from hc.api.models import Check, Ping
@csrf_exempt @csrf_exempt
@uuid_or_400 @uuid_or_400
@never_cache
def ping(request, code): def ping(request, code):
try: try:
check = Check.objects.get(code=code) check = Check.objects.get(code=code)
@ -28,8 +31,9 @@ def ping(request, code):
ping = Ping(owner=check) ping = Ping(owner=check)
headers = request.META headers = request.META
ping.n = check.n_pings ping.n = check.n_pings
ping.remote_addr = headers.get("HTTP_X_REAL_IP", headers["REMOTE_ADDR"]) remote_addr = headers.get("HTTP_X_FORWARDED_FOR", headers["REMOTE_ADDR"])
ping.scheme = headers.get("HTTP_X_SCHEME", "http") ping.remote_addr = remote_addr.split(",")[0]
ping.scheme = headers.get("HTTP_X_FORWARDED_PROTO", "http")
ping.method = headers["REQUEST_METHOD"] ping.method = headers["REQUEST_METHOD"]
# If User-Agent is longer than 200 characters, truncate it: # If User-Agent is longer than 200 characters, truncate it:
ping.ua = headers.get("HTTP_USER_AGENT", "")[:200] ping.ua = headers.get("HTTP_USER_AGENT", "")[:200]