HTTP hop-by-hop headers or "how one discovers unsuspected and essential technical information"
Despite of what the illustration of this article suggests, hop-by-hop HTTP headers have nothing to do with hops. It is rather in the sense of "jump" that the word is used here. But the hops are beautiful and are used to make beer!
So, how does one discover the hop-by-hop headers ? In my case, by chance, writing a proxy in Python to one of our HTTP services generating pdf.
The following source code:
response = HttpResponse(document.read())
for (key, value) in document.headers.dict.items():
response[key] = value
return response
was always raising an exception:
Traceback (most recent call last): File "/home/ab/work/django/venv-django/local/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 283, in run self.result = application(self.environ, self.start_response) File "/home/ab/work/django/venv-django/local/lib/python3.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__ return self.application(environ, start_response) File "/home/ab/work/django/venv-django/local/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 285, in __call__ start_response(status, response_headers) File "/home/ab/work/django/venv-django/local/lib/python3.7/site-packages/django/core/servers/basehttp.py", line 373, in start_response assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed" AssertionError: Hop-by-hop headers not allowed
These headers, few in number, oppose the vast majority of end-to-end HTTP headers. Their goal is quite simple: avoid transmitting information on the entire Internet communication chain between the client and the server that is only useful for a connection between two nodes of the chain. Saving a few kilobytes on each HTTP packet does not seem so important but this kind of details makes the Internet works so well on a large scale. The engineers who thought this architecture, its standards and its protocols really did a good job, nothing is neglected at any level.
End-to-end headers are cached and forwarded by proxy.
Any hop-by-hop headers are not cached and are not forwarded.
New hop-by-hop headers can be created by the proxy.
After a little reading on the subject, the error message becomes very clear, my proxy should not transfer hop-by-hop headers:
response = HttpResponse(document.read())
for (key, value) in document.headers.dict.items():
if not is_hop_by_hop(key):
response[key] = value
return response