-
-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose the raw event.request
#52
Comments
function handler(req, res) {
var request = new Request(req.url, req);
// ...
} |
You can proxy WS just fine, there's even a The entire framework works by passing a Response directly to the |
import {Router, listen} from 'worktop';
const API = new Router();
API.add("POST", "/", async (request, response) => {
// @ts-ignore
const req = new Request("https://httpbin.org/post", request)
return await fetch(req)
})
listen(API.run); Raw response: {
"args": {},
"data": "{\n\t\"kek\": \"kek\"\n}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "17",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "[CENSORED]",
"X-Amzn-Trace-Id": "[CENSORED]"
},
"json": {
"kek": "kek"
},
"origin": "[CENSORED]",
"url": "https://httpbin.org/post"
} With worktop: {
"args": {},
"data": "function () { [native code] }",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "29",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "[CENSORED]",
"X-Amzn-Trace-Id": "[CENSORED]"
},
"json": null,
"origin": "[CENSORED]",
"url": "https://httpbin.org/post"
} |
Oh sorry, that's how it was in a previous version, before Instead, it's this: const request = new Request(req.url, {
...req, body: await req.body.arrayBuffer(),
}) |
@dhrubabasu Did this work for you? |
@lukeed It worked for the httpbin example but it doesn't appear to be working for websockets. Here's what I'm trying: export const passThroughHandler: Handler = async (request, _) => {
return fetch(
// @ts-expect-error
new Request(request.url, {
...request,
body: await request.body.arrayBuffer(),
}),
);
};
API.add('GET', '/ws', passThroughHandler); The result with the above worker:
|
What is your origin receiving? |
I haven't had time to dive into this further but wanted to post a workaround. I'm using export function reply(handler: ResponseHandler): FetchHandler {
return (event) => {
if (['/ws'].includes(new URL(event.request.url).pathname)) {
event.respondWith(fetch(event.request));
} else {
event.respondWith(
lookup(event).then((previous) => {
return (
previous ??
handler(event).then((response) => {
return save(event, response);
})
);
}),
);
}
};
} I'll try to put together a minimal repo this weekend to verify if there is an issue with |
Sure, thanks! You don't have to modify anything btw. Your initialization code can look something like this: import { Router } from 'worktop';
import * as Cache from 'worktop/cache';
const API = new Router;
// ...
addEventListener('fetch', event => {
let { pathname } = new URL(event.request.url);
if (pathname === '/ws') event.respondWith(fetch(event.request));
else Cache.reply(API.run)(event);
}); |
My main hesitation here is that exposing a API.add('POST', '/demo', async (req, res) => {
let foo = await req.body();
// ^ success
let bar = await req.body();
// ^ this already throws
// but it's more obvious why
let baz = await req.raw.text();
// ^ throws, and not as obvious
// also true for this sequence:
await req.raw.text();
await req.body(); // throws
}); The only valid way to access it twice would be to do this: API.add('POST', '/demo', async (req, res) => {
let copy = req.raw.clone();
let input1 = await copy.text();
let input2 = await req.body();
}); ... which is fine, but is assumed knowledge & becomes the dev's responsibility. The other mildly annoying thing is that Thoughts? |
Honestly, I think the snippet you posted above is good enough. If you have to access the raw event.request, you're doing something that's not in the norm. addEventListener('fetch', event => {
let { pathname } = new URL(event.request.url);
if (pathname === '/ws') event.respondWith(fetch(event.request));
else Cache.reply(API.run)(event);
}); I think it should be documented though, perhaps under |
I like the idea of passing the original request as request.raw so that you always have access to it. For my use case I want to access the original request body reader, but that's currently not possible with Worktop without cloning the request. This way you can take advantage of the worktop features but still fall back to original request handling where you need to. The alternative is to build out 100% of functionality, which is maybe a good eventual goal, but until then request.raw may be a necessity. |
This is achieved through #83 and will be available as |
Couldn’t a proxy be used instead since then it’s no longer a function but a value ready for consumption which I think could take on form function if required for backwards compatibility. |
https://github.com/lukeed/worktop/blob/master/src/request.ts#L4
I intend on using this to do a passthrough handler:
As an aside, it also seems like you can't proxy websocket requests with
worktop
but you can with default workers. Exposingevent.request
would solve this as well.https://community.cloudflare.com/t/websocket-pass-through-crashes-worker-script/78482/6
The text was updated successfully, but these errors were encountered: