Skip to content

Commit

Permalink
Fix cors nad proto
Browse files Browse the repository at this point in the history
  • Loading branch information
timonson committed Sep 30, 2021
1 parent 452737a commit abe0cbb
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 60 deletions.
4 changes: 0 additions & 4 deletions server/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ export async function handleHttpRequest(
const headers = new Headers(options.headers);
if (options.cors) {
headers.append("access-control-allow-origin", "*");
headers.append(
"access-control-allow-headers",
"Content-Type, Authorization",
);
}
if (rpcResponseOrBatchOrNull === null) {
return new Response(null, { status: 204, headers: headers });
Expand Down
96 changes: 49 additions & 47 deletions server/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export type Options = {
publicErrorStack?: boolean;
// enable 'subscribe', 'emit' and 'unsubscribe' (only ws):
enableInternalMethods?: boolean;
// defaults to http:
proto?: "ws" | "http";
// defaults to both:
proto?: "ws" | "http" | "both";
// Enable CORS via the "Access-Control-Allow-Origin" header (only http):
cors?: boolean;
// The server can pass additional arguments to the rpc methods:
Expand All @@ -26,74 +26,76 @@ export type Options = {
methods?: (keyof Methods)[];
allMethods?: boolean;
}[];
// for jwt verification (only http):
// for jwt verification:
auth?: {
key?: CryptoKey;
methods?: (keyof Methods)[];
allMethods?: boolean;
jwt?: string | null;
};
};

export async function respond(
methods: Methods,
req: any,
req: Request,
{
headers = new Headers(),
publicErrorStack = false,
enableInternalMethods = false,
proto = "http",
proto = "both",
cors = false,
additionalArguments = [],
auth = {},
}: Options = {},
) {
switch (proto) {
case "http":
return await handleHttpRequest(
req,
methods,
{
): Promise<Response> {
const realProto = req.headers.get("upgrade") === "websocket" ? "ws" : "http";
if (
(proto === "http" || proto === "both") && realProto === "http"
) {
return await handleHttpRequest(
req,
methods,
{
headers,
publicErrorStack,
enableInternalMethods,
additionalArguments,
proto,
cors,
auth,
},
req.headers.get("Authorization"),
);
} else if ((proto === "ws" || proto === "both") && realProto === "ws") {
const { socket, response } = Deno.upgradeWebSocket(req);
const methodsAndIdsStore = new Map();
handleWs(
{
socket,
methods: enableInternalMethods
? { ...methods, ...internalMethods }
: methods,
options: {
headers,
publicErrorStack,
enableInternalMethods,
additionalArguments,
additionalArguments: enableInternalMethods
? [...additionalArguments, {
args: { methodsAndIdsStore },
methods: ["subscribe", "unsubscribe"],
}]
: additionalArguments,
proto,
cors,
auth,
},
req.headers.get("Authorization"),
);
break;
case "ws":
const methodsAndIdsStore = new Map();
const { socket, response } = Deno.upgradeWebSocket(req.request);
handleWs(
{
socket,
methods: enableInternalMethods
? { ...methods, ...internalMethods }
: methods,
options: {
headers,
publicErrorStack,
enableInternalMethods,
additionalArguments: enableInternalMethods
? [...additionalArguments, {
args: { methodsAndIdsStore },
methods: ["subscribe", "unsubscribe"],
}]
: additionalArguments,
proto,
cors,
auth,
},
},
req.request.headers.get("sec-websocket-protocol"),
);
req.respondWith(response);
return response;
break;
default:
throw new TypeError(`The protocol '${proto}' is not supported.`);
},
auth.jwt,
);
return response;
} else {
throw new TypeError(
`The received protocol '${realProto}' doesn't match the expected protocol '${proto}'.`,
);
}
}
16 changes: 7 additions & 9 deletions server/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Emission = {

function partialEmitListener(
{ socket, methods, options }: Input,
authHeader: string | null,
bearer: string | null,
) {
return async function emitListener(event: CustomEvent) {
const { method, params } = event.detail as Emission;
Expand All @@ -32,7 +32,7 @@ function partialEmitListener(
),
methods,
options,
authHeader,
bearer,
);
if (response) {
try {
Expand All @@ -48,18 +48,16 @@ function partialEmitListener(

export async function handleWs(
{ socket, methods, options }: Input,
jwtOrNull: string | null,
jwtOrNull?: string | null,
) {
const authHeader = typeof jwtOrNull === "string"
? `Bearer ${jwtOrNull}`
: null;
const bearer = typeof jwtOrNull === "string" ? `Bearer ${jwtOrNull}` : null;
let emitListenerOrNull: null | ((event: CustomEvent<any>) => void) = null;
if (options.enableInternalMethods) {
emitListenerOrNull = partialEmitListener({
socket,
methods,
options,
}, authHeader);
}, bearer);
addEventListener("emit", emitListenerOrNull as EventListener);
}
socket.onopen = () => {
Expand All @@ -71,7 +69,7 @@ export async function handleWs(
validationObjectOrBatch,
methods,
options,
authHeader,
bearer,
);
if (rpcResponseOrBatchOrNull) {
socket.send(JSON.stringify(rpcResponseOrBatchOrNull));
Expand All @@ -81,7 +79,7 @@ export async function handleWs(
if (options.enableInternalMethods) {
removeEventListener("emit", emitListenerOrNull as EventListener);
}
console.log("WebSocket has been closed.");
// console.log("WebSocket has been closed.");
};
socket.onerror = (ev) => {
if (options.enableInternalMethods) {
Expand Down

0 comments on commit abe0cbb

Please sign in to comment.