summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Senionis <warliukz@gmail.com>2024-08-03 20:24:25 +0300
committerGitHub <noreply@github.com>2024-08-03 13:24:25 -0400
commit3e50ce65a721ee6a8f930613dd196f92a9126c1d (patch)
treeb68ae0d6042eb50164436aa6f78ae74dec99950b
parentadf5a763924f99429d9b7829fce5ae15f3977a4b (diff)
downloaddecky-loader-3e50ce65a721ee6a8f930613dd196f92a9126c1d.tar.gz
decky-loader-3e50ce65a721ee6a8f930613dd196f92a9126c1d.zip
fix: fetchNoCors and http_request data handling (#664)
-rw-r--r--backend/decky_loader/utilities.py12
-rw-r--r--frontend/src/plugin-loader.tsx16
2 files changed, 17 insertions, 11 deletions
diff --git a/backend/decky_loader/utilities.py b/backend/decky_loader/utilities.py
index f7f22517..a90244a1 100644
--- a/backend/decky_loader/utilities.py
+++ b/backend/decky_loader/utilities.py
@@ -141,10 +141,10 @@ class Utilities:
# Loosely based on https://gist.github.com/mosquito/4dbfacd51e751827cda7ec9761273e95#file-proxy-py
async def http_request(self, req: Request) -> StreamResponse:
- if req.headers.get('X-Decky-Auth', '') != helpers.get_csrf_token() and req.query.get('auth', '') != helpers.get_csrf_token():
+ if req.query['auth'] != helpers.get_csrf_token():
return Response(text='Forbidden', status=403)
- url = req.headers["X-Decky-Fetch-URL"] if "X-Decky-Fetch-URL" in req.headers else unquote(req.query.get('fetch_url', ''))
+ url = unquote(req.query['fetch_url'])
self.logger.info(f"Preparing {req.method} request to {url}")
headers = dict(req.headers)
@@ -180,7 +180,11 @@ class Utilities:
body = await req.read() # TODO can this also be streamed?
- async with ClientSession() as web:
+ # We disable auto-decompress so that the body is completely forwarded to the
+ # JS engine for it to do the decompression. Otherwise we need need to clear
+ # the Content-Encoding header in the response headers, however that would
+ # defeat the point of this proxy.
+ async with ClientSession(auto_decompress=False) as web:
async with web.request(req.method, url, headers=headers, data=body, ssl=helpers.get_ssl_context()) as web_res:
res = StreamResponse(headers=web_res.headers, status=web_res.status)
if web_res.headers.get('Transfer-Encoding', '').lower() == 'chunked':
@@ -190,8 +194,6 @@ class Utilities:
self.logger.debug(f"Starting stream for {url}")
async for data in web_res.content.iter_any():
await res.write(data)
- if data:
- await res.drain()
self.logger.debug(f"Finished stream for {url}")
return res
diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx
index 6b954d69..f7d362a7 100644
--- a/frontend/src/plugin-loader.tsx
+++ b/frontend/src/plugin-loader.tsx
@@ -528,18 +528,22 @@ class PluginLoader extends Logger {
// Same syntax as fetch but only supports the url-based syntax and an object for headers since it's the most common usage pattern
fetchNoCors(input: string, init?: DeckyRequestInit | undefined): Promise<Response> {
- const headers: { [name: string]: string } = {
- ...(init?.headers as { [name: string]: string }),
- 'X-Decky-Auth': deckyAuthToken,
- 'X-Decky-Fetch-URL': input,
+ const { headers: initHeaders = {}, ...restOfInit } = init || {};
+ const getPrefixedHeaders = () => {
+ let prefixedInitHeaders: { [name: string]: any } = {};
+ for (const [key, value] of Object.entries(initHeaders)) {
+ prefixedInitHeaders[`X-Decky-Header-${key}`] = value;
+ }
+ return prefixedInitHeaders;
};
+ const headers: { [name: string]: string } = getPrefixedHeaders();
if (init?.excludedHeaders) {
headers['X-Decky-Fetch-Excluded-Headers'] = init.excludedHeaders.join(', ');
}
- return fetch('http://127.0.0.1:1337/fetch', {
- ...init,
+ return fetch(this.getExternalResourceURL(input), {
+ ...restOfInit,
credentials: 'include',
headers,
});