valohai / asgiproxy

Tools for building HTTP and Websocket proxies for the asynchronous ASGI protocol
MIT License
31 stars 1 forks source link

Pass URL query string naively and remove `date` header #3

Open jokull opened 3 years ago

jokull commented 3 years ago

I noticed a URL queryparameter like ?import is turned into ?import=. Perhaps it's better to pass the scope['query_string'] along naively to ensure URL’s are as transparent and unmodified as possible?


class ProxyConfig(BaseURLProxyConfigMixin, ProxyConfig):
    upstream_base_url = config("FRONTEND_URL", default=None)
    rewrite_host_header = config("API_HOST", default=None)

    def get_upstream_http_options(
        self, *, scope: Scope, client_request: Request, data
    ) -> dict:
        url = urljoin(self.upstream_base_url, scope["path"])
        if query_string := scope.get("query_string"):
            url += '?{}'.format(query_string.decode("utf-8"))
        options = super().get_upstream_http_options(
            scope=scope,
            client_request=client_request,
            data=data,
        )
        return options | {
            'url': url,
            'params': None,
        }

    def process_upstream_headers(
        self, *, scope: Scope, proxy_response: aiohttp.ClientResponse
    ) -> CIMultiDictProxy:
        headers = super().process_upstream_headers(
            scope=scope, proxy_response=proxy_response
        )
        headers = headers.copy()
        del headers['date']
        return headers

... also noticed a double date header because my server added it. Perhaps a default behaviour of removing it from the upstream response headers?

jokull commented 3 years ago

BTW thank you for creating this. Super useful for my tiny project. In development I'm transparently letting requests pass through to my frontend development server. In production I also use the proxy to serve the static build. The frontend is using Svelte Kit. It's a super lean and quick way to have both Python and Svelte JS in the same repo. On Render I deploy using

NODE_ENV=production poetry install --no-dev && pip install gunicorn && yarn install --production=false && node_modules/.bin/svelte-kit build

and then just run gunicorn with a uvicorn worker.

akx commented 3 years ago

Thank you for the appreciation and sorry it's taken a while to get back to this.

I wonder if there should be other upstream headers that should be deduplicated by default – HTTP of course supports multiple headers, and in many cases (e.g. Set-Cookie) they should be kept as-is...