- support chmod socket
- fix content-encoding if upstream sets it to gzip
- support conditionally replacing for a specific hostname
This commit is contained in:
Kay Faraday 2021-09-07 06:00:33 +00:00
parent 56c2312036
commit 980e421c4d
1 changed files with 21 additions and 6 deletions

27
app.py
View File

@ -3,6 +3,7 @@
import io
import os
import sys
import asyncio
import aiohttp
import contextlib
@ -23,9 +24,15 @@ class ContextVar:
pattern = os.environ['PATTERN'].encode()
repl = os.environ['REPL'].encode()
upstream = 'http://' + os.environ['UPSTREAM']
bind = os.environ['BIND']
port = int(os.environ.get('PORT', '8080'))
# TODO support upstream unix sockets
upstream = os.environ['UPSTREAM']
bind = sys.argv[1]
socket_mod = int(os.environ.get('SOCKET_MODE', '775'), 8)
replace_for = os.environ.get('REPLACE_FOR_HOST')
try:
port = int(sys.argv[2])
except IndexError:
port = 8080
http = ContextVar('http')
async def handler(request):
@ -38,10 +45,16 @@ async def handler(request):
# proxy redirects as-is
allow_redirects=False,
) as upstream_resp:
resp = web.StreamResponse(status=upstream_resp.status, headers=upstream_resp.headers)
headers = upstream_resp.headers.copy()
# we're not using gzip here so don't confuse our client
with contextlib.suppress(KeyError): del headers['Content-Encoding']
resp = web.StreamResponse(status=upstream_resp.status, headers=headers)
await resp.prepare(request)
if upstream_resp.content_type == 'text/html':
if (
upstream_resp.content_type == 'text/html'
and (replace_for is None or request.host == replace_for)
):
# iter_lines when
while (line := await upstream_resp.content.readline()):
await resp.write(line.replace(pattern, repl))
@ -63,6 +76,9 @@ async def amain():
async with aiohttp.ClientSession() as http_:
http.set(http_)
await site.start()
if '/' in bind:
with contextlib.suppress(KeyError):
os.chmod(bind, socket_mod)
await asyncio.sleep(float('inf'))
def main():
@ -71,4 +87,3 @@ def main():
if __name__ == '__main__':
main()