-
Notifications
You must be signed in to change notification settings - Fork 61
Open
Labels
Description
Is your feature request related to a problem?
Example how to reproduce. In the end durable worker returns the same Response.
import { getCloudflareContext } from "@opennextjs/cloudflare";
import type { NextRequest } from "next/server";
export default async function handler(request: NextRequest) {
console.log("WebSocket upgrade handler invoked");
const webSocketPair = new WebSocketPair();
const [client, server] = Object.values(webSocketPair);
return new Response(null, { status: 101, webSocket: client });
}
export { handler as GET};
I assume somewhere in NextJS pipeline the webSocket
object is lost and we get [ERROR] Uncaught RangeError: Responses may only be constructed with status codes in the range 200 to 599, inclusive.
Describe the solution you'd like
Ability to make nextjs API return our webSocket object
Describe alternatives you've considered
-
Use seperate worker for websocket API
-
Rewrite workers.js with hook for handling websockets
//@ts-expect-error: Will be resolved by wrangler build
import { fetchImage } from "./.open-next/cloudflare/images.js";
//@ts-expect-error: Will be resolved by wrangler build
import { runWithCloudflareRequestContext } from "./.open-next/cloudflare/init.js";
//@ts-expect-error: Will be resolved by wrangler build
import { maybeGetSkewProtectionResponse } from "./.open-next/cloudflare/skew-protection.js";
// @ts-expect-error: Will be resolved by wrangler build
import { handler as middlewareHandler } from "./.open-next/middleware/handler.mjs";
import { wsHandler } from "./src/workers/handler.js";
//@ts-expect-error: Will be resolved by wrangler build
export { DOQueueHandler } from "./.open-next/.build/durable-objects/queue.js";
//@ts-expect-error: Will be resolved by wrangler build
export { DOShardedTagCache } from "./.open-next/.build/durable-objects/sharded-tag-cache.js";
//@ts-expect-error: Will be resolved by wrangler build
export { BucketCachePurge } from "./.open-next/.build/durable-objects/bucket-cache-purge.js";
export default {
async fetch(request: Request, env: any, ctx: any) {
return runWithCloudflareRequestContext(request, env, ctx, async () => {
const response = maybeGetSkewProtectionResponse(request);
if (response) {
return response;
}
const url = new URL(request.url);
// handle it here
if (url.pathname.startsWith("/api/ws")) {
return wsHandler(request);
}
// Serve images in development.
// Note: "/cdn-cgi/image/..." requests do not reach production workers.
if (url.pathname.startsWith("/cdn-cgi/image/")) {
const m = url.pathname.match(/\/cdn-cgi\/image\/.+?\/(?<url>.+)$/);
if (m === null) {
return new Response("Not Found!", { status: 404 });
}
const imageUrl = m.groups?.url;
return imageUrl?.match(/^https?:\/\//)
? fetch(imageUrl, { cf: { cacheEverything: true } })
: env.ASSETS?.fetch(new URL(`/${imageUrl}`, url));
}
// Fallback for the Next default image loader.
if (url.pathname === `${(globalThis as any).__NEXT_BASE_PATH__}/_next/image`) {
const imageUrl = url.searchParams.get("url") ?? "";
return await fetchImage(env.ASSETS, imageUrl, ctx);
}
// - `Request`s are handled by the Next server
const reqOrResp = await middlewareHandler(request, env, ctx);
if (reqOrResp instanceof Response) {
return reqOrResp;
}
// @ts-expect-error: resolved by wrangler build
const { handler } = await import("./.open-next/server-functions/default/handler.mjs");
return handler(reqOrResp, env, ctx);
});
},
};
export { ClientHibernationServer } from "./src/workers/clientDO";
@opennextjs/cloudflare version
1.5.1
Additional context
Before submitting
- I have checked that there isn't already a similar feature request
- This is a single feature (not multiple features in one request)
alin-c-gen and serban-mihai